<?php

namespace HulkPlugins\ElementorPro\Forms\InternationalTelephoneField;

use Elementor\Controls_Manager;
use Elementor\Repeater;
use ElementorPro\Modules\Forms\Classes\Ajax_Handler;
use ElementorPro\Modules\Forms\Classes\Form_Record;
use ElementorPro\Modules\Forms\Fields\Field_Base;
use ElementorPro\Plugin;
use HulkPlugins\ElementorPro\Forms\InternationalTelephoneField\Utils\Helper;

class Field extends Field_Base {

	public const TYPE = PREFIX . 'telephone';
	private array $fieldSettings = [];

	public $depended_styles = [ PREFIX . 'telephone' ];
	public $depended_scripts = [ PREFIX . 'telephone' ];

	/**
	 * Field unique type
	 * @return string
	 */
	public function get_type(): string {
		return self::TYPE;
	}

	/**
	 * Field name
	 * @return string
	 */
	public function get_name(): string {
		return esc_html__( 'Telephone', 'international-telephone-field-for-elementor-form' );
	}

	/**
	 * Field markup
	 * @param $item
	 * @param $item_index
	 * @param $form
	 *
	 * @return void
	 */
	public function render( $item, $item_index, $form ): void {
		global $post;
		$hulk_epfitf_settings = [];
		$type = $this->get_type();
		$prefix = $type . '_';
		$mainId = $post->ID ?? 0;
		$_id = $item['_id'];
		require PLUGIN_DIR_PATH . 'includes/render.php';
	}

	/**
	 * Field controls
	 * @param $widget
	 *
	 * @return void
	 */
	public function update_controls( $widget ): void {
		$elementor = Plugin::elementor();
		$control_data = $elementor->controls_manager->get_control_from_stack( $widget->get_unique_name(), 'form_fields' );
		if ( is_wp_error( $control_data ) ) {
			return;
		}
		$field     = new Repeater();
		$type      = $this->get_type();
		$widget_id = $widget->get_id();
		$prefix = $type . '_';
		require PLUGIN_DIR_PATH . 'includes/controls/content.php';
		require PLUGIN_DIR_PATH . 'includes/controls/advanced.php';
		$controls = $field->get_controls();
		if ( isset( $controls['_id'] ) ) {
			unset( $controls['_id'] );
		}
		foreach ( $controls as &$control ) {
			if ( isset( $control['control_tab'] ) && $control['control_tab'] === Controls_Manager::TAB_CONTENT ) {
				$control['condition']['field_type'] = $type;
				$control['tab'] = 'content';
				$control['inner_tab'] = 'form_fields_content_tab';
				$control['tabs_wrapper'] = 'form_fields_tabs';
			} elseif ( isset( $control['control_tab'] ) && $control['control_tab'] === Controls_Manager::TAB_ADVANCED ) {
				$control['condition']['field_type'] = $type;
				$control['tab'] = 'advanced';
				$control['inner_tab'] = 'form_fields_advanced_tab';
				$control['tabs_wrapper'] = 'form_fields_tabs';
			}
		}
		unset( $control );
		$control_data['fields'] = $this->inject_field_controls( $control_data['fields'], $controls );
		$widget->update_control( 'form_fields', $control_data );
	}

	/**
	 * Field validation
	 * @param $field
	 * @param Form_Record $record
	 * @param Ajax_Handler $ajax_handler
	 *
	 * @return void
	 */
	public function validation( $field, Form_Record $record, Ajax_Handler $ajax_handler ): void {
		if ( empty( $field['value'] ) ) {
			return;
		}

		$id = $field['id'];

		$sent_data = $record->get( 'sent_data' );
		$form_fields = (array)$record->get_form_settings( 'form_fields' );
        $field_settings = $this->get_field_settings( $form_fields, $id );

        $isEnableValidation = ($field_settings['enableValidation'] ?? 'no') === 'yes';

		if ( ! $isEnableValidation ) {
			return;
		}

		$isValid = filter_var( $sent_data[ "{$id}_isValid" ], FILTER_VALIDATE_BOOLEAN );

		if ( $isValid ) {
			return;
		}

		$errorCode = (int) $sent_data[ "{$id}_errorCode" ];

		switch ( $errorCode ) {
			case 2:
				$errorMessage = $this->get_error_message( $field_settings, 'TOO_SHORT' );
				break;
			case 3:
				$errorMessage = $this->get_error_message( $field_settings, 'TOO_LONG' );
				break;
			case 4:
				$errorMessage = $this->get_error_message( $field_settings, 'INVALID_BUT_POSSIBLE' );
				break;
			case 1:
				$errorMessage = $this->get_error_message( $field_settings, 'INVALID_COUNTRY_CODE' );
				break;
			case 5:
				$errorMessage = $this->get_error_message( $field_settings, 'INVALID_LENGTH' );
				break;
			case 0:
				$errorMessage = $this->get_error_message( $field_settings, 'NOT_A_NUMBER' );
				break;
			default:
				$errorMessage = $this->get_error_message( $field_settings, 'UNKNOWN' );
				break;
		}

		$ajax_handler->add_error( $id, $errorMessage );
	}

	/**
	 * Get error message by key
	 * @param array $field_settings
	 * @param string $key
	 *
	 * @return mixed|string
	 */
	public function get_error_message( array $field_settings, string $key ) {
		$message = trim( $field_settings[ $key ] ?? '' );
		if ( empty( $message ) ) {
			$messages = Helper::getErrorMessages();
			return $messages[ $key ] ?? $messages['UNKNOWN'];
		}
		return $message;
	}

	/**
	 * Enqueue script and style if elementor cache is enabled
	 * @return void
	 */
	public function get_builder_content(): void {
		foreach ( $this->depended_styles as $style ) {
			wp_enqueue_style( $style );
		}
		foreach ( $this->depended_scripts as $script ) {
			wp_enqueue_script( $script );
		}
	}

	/**
	 * After frontend enqueue scripts.
	 *
	 * Fires after Elementor frontend scripts are enqueued.
	 */
	public function frontend_enqueue_scripts(): void {
		if ( ! wp_script_is( 'react-jsx-runtime', 'registered' ) ) {
			wp_register_script(
				'react-jsx-runtime',
				PLUGIN_DIR_URL . 'assets/js/react-jsx-runtime.min.js',
				[ 'react' ],
				'18.3.1',
				true
			);
		}

		$frontend_asset = require PLUGIN_DIR_PATH . 'build/frontend/index.asset.php';

		wp_register_style(
			PREFIX . 'telephone',
			PLUGIN_DIR_URL . 'build/frontend/index.css',
			[],
			$frontend_asset['version'],
		);

		wp_register_script(
			PREFIX . 'telephone',
			PLUGIN_DIR_URL . 'build/frontend/index.js',
			$frontend_asset['dependencies'],
			$frontend_asset['version'],
			true
		);

		wp_add_inline_script(
			PREFIX . 'telephone',
			'var ' . PREFIX . 'webpack_public_path = "' . PLUGIN_DIR_URL . 'build/frontend/"',
			'before'
		);
	}

	/**
	 * Get field settings by ID
	 *
	 * @param array $fields
	 * @param string $id
	 *
	 * @return array|mixed
	 */
	protected function get_field_settings( array $fields, string $id ) {
		if ( empty( $this->fieldSettings[ $id ] ) ) {
			foreach ( $fields as $field ) {
				if ( str_contains( $id, $field['_id'] ) ) {
					$filtered = array_filter(
						$field,
						fn( $key ) => str_starts_with( $key, $this->get_type() ),
						ARRAY_FILTER_USE_KEY
					);
					$result = [];
					foreach ( $filtered as $key => $value ) {
						// Remove the prefix from the key
						$newKey = str_replace( $this->get_type() . '_', '', $key );
						$result[ $newKey ] = $value;
					}
					$this->fieldSettings[ $id ] = $result;
					return $result;
				}
			}
		}
		return $this->fieldSettings[ $id ] ?? [];
	}

	public function __construct() {
		parent::__construct();
		add_action( 'elementor/frontend/after_enqueue_scripts', [ $this, 'frontend_enqueue_scripts' ] );
		add_action( 'elementor/frontend/get_builder_content', [ $this,'get_builder_content' ] );
	}
}
