<?php
namespace SabaiApps\Directories\Component\PaymentGateway\FieldWidget;

use SabaiApps\Directories\Component\Field\Widget\AbstractWidget;
use SabaiApps\Directories\Component\Field\IField;
use SabaiApps\Directories\Component\Entity\Type\IEntity;
use SabaiApps\Directories\Component\Form\Form;

class PlanFieldWidget extends AbstractWidget {

	protected function _fieldWidgetInfo() {
		return array(
			'label'       => __( 'Payment Plan Information', 'directories-pro' ),
			'field_types' => array( $this->_name ),
		);
	}

	protected function _getPaymentEnabledBundles( IField $field ) {
		$bundles      = array();
		$bundle_group = $field->Bundle->group;
		foreach ( $this->_application->Entity_BundleTypes_byFeatures( array( 'payment_enable' ) ) as $entity_type => $bundle_types ) {
			foreach ( $this->_application->Entity_Bundles_byType( $bundle_types, $bundle_group ) as $bundle ) {
				if ( empty( $bundle->info['payment_enable'] ) ) {
					continue;
				}

				$bundles[ $bundle->name ] = $bundle->getGroupLabel() . ' - ' . $bundle->getLabel( 'singular' );
			}
		}
		return $bundles;
	}

	public function fieldWidgetForm( IField $field, array $settings, $value = null, ?IEntity $entity = null, array $parents = array(), $language = null ) {
		$payment_enabled_bundles = $this->_getPaymentEnabledBundles( $field );
		$price                   = $display_order = $interval = $interval_count = $feature_list = null;
		if ( isset( $value ) ) {
			$data          = $value['data'] ?? array();
			$price         = $data['price'] ?? null;
			$feature_list  = $data['feature_list'] ?? null;
			$display_order = $value['display_order'] ?? 1;
			if ( $value['plan_type'] === 'subscription' ) {
				$interval       = $data['interval'] ?? null;
				$interval_count = $data['interval_count'] ?? null;
			}
		}
		$plan_types = $this->_application->PaymentGateway_Util_planTypes();
		$form       = array(
			'#admin_only_main'  => true,
			'#element_validate' => array(
				function ( Form $form, &$value, $element ) use ( $plan_types ) {
						$type = explode( '-', $value['plan_type'] );
					if ( count( $type ) !== 2 || ! isset( $plan_types[ $type[1] ] ) || ! isset( $value[ $type[0] ] ) ) {
						$form->setError( $element, __( 'Invalid plan type selected.', 'directories-pro' ) );
						return;
					}
						$value['plan_type']    = $type[1];
						$value['content_name'] = $type[0];
					if ( ! isset( $value[ $value['content_name'] ] ) ) {
						$form->setError( $element, __( 'Invalid plan type selected.', 'directories-pro' ) );
						return;
					}
						$value['data'] = $value[ $value['content_name'] ];
						unset( $value[ $value['content_name'] ] );
					foreach ( array( 'price', 'feature_list', 'interval', 'interval_count' ) as $key ) {
						if ( isset( $value[ $key ] ) ) {
							$value['data'][ $key ] = $value[ $key ];
							unset( $value[ $key ] );
						}
					}
				},
			),
			'interval'          => array(
				'#type'          => 'select',
				'#title'         => __( 'Recurrence type', 'directories-pro' ),
				'#options'       => array(
					'day'   => __( 'Daily', 'directories-pro' ),
					'week'  => __( 'Weekly', 'directories-pro' ),
					'month' => __( 'Monthly', 'directories-pro' ),
					'year'  => __( 'Yearly', 'directories-pro' ),
				),
				'#default_value' => isset( $interval ) ? $interval : 'month',
				'#horizontal'    => true,
				'#required'      => true,
				'#states'        => array(
					'visible' => array(
						$type_selector = sprintf( '[name="%s"]', $this->_application->Form_Form_fieldName( array( $parents, 'plan_type' ) ) ) => array(
							'type'  => '$value',
							'value' => '-subscription',
						),
					),
				),
				'#weight'        => 10,
			),
			'interval_count'    => array(
				'#type'          => 'number',
				'#integer'       => true,
				'#title'         => __( 'Recurrence interval', 'directories-pro' ),
				'#default_value' => empty( $interval_count ) ? 1 : $interval_count,
				'#min_value'     => 1,
				'#horizontal'    => true,
				'#required'      => true,
				'#states'        => array(
					'visible' => array(
						$type_selector => array(
							'type'  => '$value',
							'value' => '-subscription',
						),
					),
				),
				'#weight'        => 11,
			),
			'price'             => array(
				'#type'          => 'number',
				'#title'         => __( 'Price', 'directories-pro' ),
				'#numeric'       => true,
				'#default_value' => $price,
				'#field_prefix'  => $this->_application->Payment_Components_impl( 'default' )->paymentGetCurrency(),
				'#step'          => 0.01,
				'#horizontal'    => true,
				'#required'      => true,
				'#weight'        => 15,
			),
			'description'       => array(
				'#type'          => 'textarea',
				'#title'         => __( 'Description', 'directories-pro' ),
				'#rows'          => 5,
				'#default_value' => isset( $entity ) ? $entity->getContent() : null,
				'#horizontal'    => true,
				'#weight'        => 20,
			),
			'feature_list'      => array(
				'#type'              => 'options',
				'#horizontal'        => true,
				'#description'       => __( 'Optionally enter a list of features that will be displayed on the pricing table for reference only. Please note that these features do not imply any actual additions or changes to the payment plan.', 'directories-pro' ),
				'#description_top'   => true,
				'#default_value'     => $feature_list,
				'#multiple'          => true,
				'#default_unchecked' => false,
				'#disable_add_csv'   => true,
				'#hide_value'        => true,
				'#weight'            => 21,
				'#label_title'       => __( 'e.g., Priority Customer Service, Extended Warranty', 'directories-pro' ),
			),
			'display_order'     => array(
				'#type'          => 'slider',
				'#title'         => __( 'Plan display order', 'directories-pro' ),
				'#integer'       => true,
				'#min_value'     => 1,
				'#max_value'     => 10,
				'#default_value' => $display_order,
				'#horizontal'    => true,
				'#weight'        => 25,
			),
		);
		if ( isset( $value ) ) {
			$bundle                = $this->_application->Entity_Bundle( $value['content_name'], $field->Bundle->group );
			$form['_type']         = array(
				'#title'         => __( 'Plan type', 'directories-pro' ),
				'#type'          => 'item',
				'#default_value' => sprintf(
					__( '%1$s (%2$s)', 'directories-pro' ),
					$payment_enabled_bundles[ $bundle->name ],
					$plan_types[ $value['plan_type'] ]
				),
				'#horizontal'    => true,
				'#weight'        => 3,
			);
			$form['plan_type']     = array(
				'#type'          => 'hidden',
				'#default_value' => $value['content_name'] . '-' . $value['plan_type'],
			);
			$settings              = array(
				'level'    => $data['level'] ?? '',
				'features' => ( isset( $data['features']['enabled'] ) ? (array) $data['features']['enabled'] : array() )
					+ ( isset( $data['features']['disabled'] ) ? (array) $data['features']['disabled'] : array() ),
			);
			$form[ $bundle->type ] = $this->_application->Payment_Features_form( $bundle, $value['plan_type'], $settings, array_merge( $parents, array( $bundle->type ) ) );
		} else {
			$type_options = array();
			foreach ( $payment_enabled_bundles as $bundle_name => $bundle_label ) {
				$bundle              = $this->_application->Entity_Bundle( $bundle_name );
				$bundle_type_options = array();
				foreach ( $plan_types as $plan_type => $plan_type_label ) {
					$type_options[ $key    = $bundle->type . '-' . $plan_type ] = sprintf(
						__( '%1$s (%2$s)', 'directories-pro' ),
						$bundle_label,
						$plan_type_label
					);
					$bundle_type_options[] = $key;
				}
				$form[ $bundle->type ] = $this->_application->Payment_Features_form( $bundle, array_keys( $plan_types ), null, array_merge( $parents, array( $bundle->type ) ), array_merge( $parents, array( 'plan_type' ) ) );
			}
			$form['plan_type'] = array(
				'#type'       => 'select',
				'#title'      => __( 'Plan type', 'directories-pro' ),
				'#options'    => $type_options,
				'#horizontal' => true,
				'#required'   => true,
				'#weight'     => 3,
			);
		}

		return $form;
	}
}
