<?php

class Wiaas_Delivery_Process_Step extends Gravity_Flow_Step {

	/**
	 * Code for Wiaas Delivery Process Step type
	 * @var string
	 */
	public $_step_type = 'wiaas_delivery_step';

	private static $delivery_action_form_title_prefix = 'DELIVERY ACTION TYPE:';

	private static $delivery_action_types = array(
		'DELIVERY ACTION TYPE: Customer acceptance' => 'customer-acceptance',
		'DELIVERY ACTION TYPE: Validate Questionnaire' => 'validate-questionnaire',
		'DELIVERY ACTION TYPE: Manual' => 'manual',
		'DELIVERY ACTION TYPE: Schedule meeting' => 'schedule-meeting'
	);

	public static function get_delivery_action_types() {
		return array_keys(self::$delivery_action_types);
	}

	public static function get_delivery_action_type_prefix() {
		return self::$delivery_action_form_title_prefix;
	}

	/**
	 * Returns label for Wiass Delivery Process Step
	 * @return string
	 */
	public function get_label() {
		return esc_html__( 'Wiaas Delivery Step', 'wiaas' );
	}

	/**
	 * Returns settings for wiaas delivery process step
	 * @return array
	 */
	public function get_settings() {

		$settings_api = $this->get_common_settings_api();

		$forms = $this->get_target_forms_choices();
		$form_choices[] = array( 'label' => esc_html__( 'Select a Form', 'wiaas' ), 'value' => '' );
		foreach ( $forms  as $form ) {
			$form_choices[] = array( 'label' => $form->title, 'value' => $form->id );
		}


		$settings = array(
			'title'  => esc_html__( 'Wiaas Delivery Step', 'wiaas' ),
			'fields' => array(
				$settings_api->get_setting_instructions(),
				array (
					'name' => 'is_visible_to_customer',
					'label' => __( 'Visible to customer', 'wiaas' ),
					'type' => 'checkbox',
					'choices' => array(
						array(
							'label'         => __( 'Show to customer', 'wiaas' ),
							'name'          => 'is_visible_to_customer',
							'default_value' => true,
						),
					),
					'tooltip'       => __( 'Determines if this step will be shown to customer.', 'wiaas' ),
				),
				array(
					'name' => 'target_form_id',
					'label' => esc_html__( 'Action', 'wiaas' ),
					'type' => 'select',
					'onchange'    => "jQuery(this).closest('form').submit();",
					'choices' => $form_choices,
				),
			),
		);

		return $settings;
	}

	/**
	 * Process Wiass Delivery Process Step
	 *
	 *
	 * @return bool
	 */
	function process() {

		$form = $this->get_form();
		$entry = $this->get_entry();
		$target_form = GFAPI::get_form( $this->target_form_id );

		# if target form is not valid just finish the step
		if (!$target_form) {
			return true;
		}

		# create new entry for target form with populated value for customer-id from parent entry
		$new_entry = array(
			'form_id' => $this->target_form_id,
			'wiaas_delivery_process_id' => $this->get_entry_id(),
			'wiaas_delivery_order_id' => $entry['wiaas_delivery_order_id'],
            'wiaas_delivery_step_name' => $this->get_name(),
		);

		$customer_id_value = null;

		if ( is_array( $form['fields'] ) ) {
			foreach ( $form['fields'] as $field ) {
				if (GFCommon::get_label( $field ) === 'customer-id') {
					$customer_id_value = $entry[$field->id];
					break;
				}
			}
		}

		if ( is_array( $target_form['fields'] ) ) {
			foreach ( $target_form['fields'] as $field ) {
				if (GFCommon::get_label( $field ) === 'customer-id') {
					$new_entry[$field->id] = $customer_id_value;
					break;
				}
			}
		}

		$entry_id = GFAPI::add_entry( $new_entry );
		if ( is_wp_error( $entry_id ) ) {
			$this->log_debug( __METHOD__ .'(): failed to add entry' );
		} else {
			// store entry id
			gform_update_meta($this->get_entry_id(), 'wiaas_delivery_step_' . $this->get_id() .'_entry_id', $entry_id);
		}

		$note = $this->get_name() . ': ' . esc_html__( 'started.', 'wiaas' );
		$this->add_note( $note );

		# return false since we wait for workflow of target entry to be complete first
		return false;
	}

	/**
	 * Evaluates current step status based on target form entry status
	 *
	 * If target form entry has associated workflow current step will complete its status
	 * only when target form entry workflow is completed
	 * @return string
	 */
	public function status_evaluation() {

		# retrieve target form entry to check its workflow status
		$target_form_entry = $this->get_target_form_entry();

		# if there is no target form entry just complete the step
		if(!$target_form_entry) {
			return 'complete';
		}

		# retrieve target form entry workflow status
		$api = new Gravity_Flow_API( $this->target_form_id );
		$status = $api->get_status($target_form_entry);

		# status is complete only if target entry flow is complete
		return $status === 'complete' || $status === 'approved' ? 'complete' : 'pending';
	}

	/**
	 * Expands step entry with additional metadata to track created target entry id
	 * @param array $entry_meta
	 * @param int $form_id
	 *
	 * @return array
	 */
	public function get_entry_meta($entry_meta, $form_id) {
		if ($form_id === $this->get_form_id()) {
			$entry_meta['wiaas_delivery_step_' . $this->get_id() .'_entry_id'] = null;
		}
		return $entry_meta;
	}

	/**
	 * Retrieves forms that are valid options for delivery step action
	 * @return array
	 */
	public function get_target_forms_choices() {
		return GFFormsModel::search_forms(self::$delivery_action_form_title_prefix, true);
	}

	/**
	 * Retrieves delivery action type that is executed with this step
	 * @return string
	 */
	public function get_delivery_action_type() {
		$target_form = GFAPI::get_form( $this->target_form_id );
		return self::$delivery_action_types[$target_form['title']];
	}

	public function get_target_actual_date() {
		$target_entry = $this->get_target_form_entry();
		$target_form = GFAPI::get_form( $this->target_form_id );

		if (!is_wp_error($target_entry) && is_array($target_form['fields'])) {
			foreach ( $target_form['fields'] as $field ) {
				if (GFCommon::get_label( $field ) === 'Actual Date') {
					return $target_entry[$field->id];
				}
			}
		}

		return null;
	}

	public function get_target_step_comments() {
		$notes = RGFormsModel::get_lead_notes( $this->get_target_form_entry_id() );

		$comments = array();
		foreach ( $notes as $key => $note ) {
			if ( $note->note_type !== 'gravityflow' ) {
				$comments[] = array(
					'date' => $note->date_created,
					'text' => $note->value,
					'user' => $note->user_name
				);
 			}
		}
		return $comments;
	}

	/**
	 * Retrieves target form entry created when step was started
	 * @return array|null
	 */
	public function get_target_form_entry() {
		$entry = GFAPI::get_entry($this->get_target_form_entry_id());
		if(is_wp_error($entry)) {
			return null;
		}
		return $entry;
	}


	/**
	 * Retrieves target form entry id created when step was started
	 * @return int
	 */
	public function get_target_form_entry_id() {
		$value = gform_get_meta($this->get_entry_id(), 'wiaas_delivery_step_' . $this->get_id() .'_entry_id');

		return absint($value);
	}
}
