<?php

namespace Limb_Chatbot\Includes\Services\Parsers;

use Limb_Chatbot\Includes\Data_Objects\Action_Plan;
use Limb_Chatbot\Includes\Data_Objects\Action_Plan_Step;
use Limb_Chatbot\Includes\Data_Objects\Parameter;

class Action_Plan_Parser{

	/**
	 * Parses serialized Action_Plan data back into Action_Plan object.
	 *
	 * @param  mixed  $value  Serialized Action_Plan data (JSON string or array).
	 *
	 * @return Action_Plan|null Parsed Action_Plan object or null if invalid.
	 */
	public function parse( $value ): ?Action_Plan {
		if ( empty( $value ) ) {
			return null;
		}

		// Handle JSON string input
		if ( is_string( $value ) ) {
			$decoded = json_decode( $value, true );
			if ( json_last_error() !== JSON_ERROR_NONE ) {
				return null;
			}
			$value = $decoded;
		}

		// Handle array input
		if ( ! is_array( $value ) ) {
			return null;
		}

		$action_plan = new Action_Plan();

		if ( isset( $value['action_name'] ) ) {
			$action_plan->set_action_name( $value['action_name'] );
		}

		// Parse steps if they exist
		if ( isset( $value['steps'] ) && is_array( $value['steps'] ) ) {
			foreach ( $value['steps'] as $step_data ) {
				$step = $this->parse_step( $step_data );
				if ( $step ) {
					$action_plan->add_step( $step );
				}
			}
		}

		return $action_plan;
	}

	/**
	 * Parses a single Action_Plan_Step from array data.
	 *
	 * @param  array  $step_data  Step data array.
	 *
	 * @return Action_Plan_Step|null Parsed step or null if invalid.
	 */
	private function parse_step( array $step_data ): ?Action_Plan_Step {
		if ( ! isset( $step_data['type'] ) || ! isset( $step_data['state'] ) ) {
			return null;
		}

		$step = new Action_Plan_Step();
		$step->set_type( (int) $step_data['type'] );
		$step->set_state( (int) $step_data['state'] );

		// Parse step data
		if ( isset( $step_data['data'] ) && is_array( $step_data['data'] ) ) {
			foreach ( $step_data['data'] as $key => $value ) {
				// Handle Parameter objects in data
				if ( $key === 'parameter' && is_array( $value ) ) {
					$parameter = new Parameter( $value );
					$step->add_data( $key, $parameter );
				} else {
					$step->add_data( $key, $value );
				}
			}
		}

		return $step;
	}
}