<?php
if (!defined('ABSPATH')) {
    exit; // Exit if accessed directly.
}

use Elementor\Icons_Manager;
/**
 * Elementor Form Field - Rating
 *
 * Add a new "Rating" field to Elementor form widget.
 *
 * @since 1.0.0
 */
if(!class_exists('Cfkef_Rating_Field')) {
class Cfkef_Rating_Field extends \ElementorPro\Modules\Forms\Fields\Field_Base {

    public $depended_scripts = ['cfkef-rating-field-script'];

	public $depended_styles = ['cfkef-rating-field-style'];

    /**
     * Get field type.
     *
     * Retrieve rating field unique ID.
     *
     * @since 1.0.0
     * @return string
     */
    public function get_type() {
        return 'rating';
    }


    public function get_script_depends(): array {
		return $this->depended_scripts;
	}

	public function get_style_depends(): array {
		return $this->depended_styles;
	}

    /**
     * Get field name.
     *
     * Retrieve rating field label.
     *
     * @since 1.0.0
     * @return string
     */
    public function get_name() {
        return esc_html__('Rating', 'cool-formkit');
    }

    /**
     * Render field output on the frontend.
     *
     * @since 1.0.0
     * @param mixed $item
     * @param mixed $item_index
     * @param mixed $form
     * @return void
     */
    public function render($item, $item_index, $form) {
        $field_name = $form->get_attribute_name($item, $item_index);

        $rating_size = isset($item['rating_size']['size']) ? $item['rating_size']['size'] : 24;
        $rating_spacing = isset($item['rating_spacing']['size']) ? $item['rating_spacing']['size'] : 4;
        $rating_scale = intval($item['rating_scale']);
        $rating_default = floatval($item['rating_default']);
        $rating_step = floatval($item['rating_step']);
        $rating_icon = $this->get_rating_icon($item['rating_icon'], $item['rating_icon_custom']);
        $rating_marked_color = esc_attr($item['rating_marked_color']);
        $rating_unmarked_color = esc_attr($item['rating_unmarked_color']);
        $show_rating_value = !empty($item['show_rating_value']) ? true : false;
        $rating_alignment = !empty($item['rating_alignment']) ? $item['rating_alignment'] : 'center';
        $required = isset($item['required']) ? $item['required'] : '';
        if(isset($item['rating_icon_custom']['value'])){
            if(gettype( $item['rating_icon_custom']['value']) == "string"){
                $rating_icon_custom = esc_attr($item['rating_icon_custom']['value']);
            }else{
                $rating_icon_custom = esc_attr($item['rating_icon_custom']['value']['url']);
            }
        }else{
            $rating_icon_custom = "";   
        }

        $form->add_render_attribute(
            $field_name,
            [
                'class' => 'elementor-field-subgroup elementor-rating',
                'id' => 'form-field-' . $item["custom_id"],
                'data-rating-scale' => esc_attr($rating_scale),
                'data-rating-default' => esc_attr($rating_default),
                'data-rating-step' => esc_attr($rating_step),
                'data-rating-icon' => esc_attr($item['rating_icon']),
                'data-rating-icon-custom' => esc_attr($rating_icon_custom),
                'data-rating-size' => esc_attr($rating_size),
                'data-rating-spacing' => esc_attr($rating_spacing),
                'data-rating-marked-color' => $rating_marked_color,
                'data-rating-unmarked-color' => $rating_unmarked_color,
                'data-show-rating-value' => $show_rating_value ? 'true' : 'false',
                'style' => '--rating-size: ' . esc_attr($rating_size) . 'px; --rating-spacing: ' . esc_attr($rating_spacing) . 'px; --rating-marked-color: ' . $rating_marked_color . '; --rating-unmarked-color: ' . $rating_unmarked_color . '; --rating-alignment:'.$rating_alignment.';',
                'data-required' => esc_attr($required),
            ]
        );

        echo '<div ' . $form->get_render_attribute_string($field_name) . '>';
        for ($i = 1; $i <= $rating_scale; $i++) {
            $full_marked = ($i <= $rating_default) ? 'marked' : '';
            $half_marked = ($rating_step == 0.5 && ($i - 0.5) <= $rating_default) ? 'marked' : '';
            echo '<span class="rating-icon-wrapper">';
            if ($rating_step == 0.5) {
                echo '<span class="rating-icon half ' . $half_marked . '" data-value="' . ($i - 0.5) . '">';
                echo $this->render_custom_icon($item['rating_icon'], $item['rating_icon_custom']);
                echo '</span>';
            }
            echo '<span class="rating-icon full ' . $full_marked . '" data-value="' . $i . '">';
            echo $this->render_custom_icon($item['rating_icon'], $item['rating_icon_custom']);
            echo '</span>';
            echo '</span>';
        }
        echo '<input type="hidden" name="' . esc_attr($field_name) . '" value="' . esc_attr($rating_default) . '" class="elementor-rating-input">';
        if ($show_rating_value) {
            echo '<span class="elementor-rating-value">(' . $rating_default . '/' . $rating_scale . ')</span>';
        }
        echo '</div>';
    }
    
    private function render_custom_icon($icon, $custom_icon) {
        if ($icon === 'custom' && !empty($custom_icon)) {
                // Otherwise, use Icons_Manager for standard icons
                ob_start();
                Icons_Manager::render_icon($custom_icon, ['aria-hidden' => 'true']);
                $icon_html = ob_get_clean();
                return $icon_html;
        }
        return $this->get_rating_icon($icon, null);
    }    

    /**
     * Get the rating icon HTML.
     *
     * @since 1.0.0
     * @param string $icon
     * @param array $custom_icon
     * @return string
     */
    private function get_rating_icon($icon, $custom_icon) {
        switch ($icon) {
            case 'heart':
                return '♥';
            case 'smile':
                return '☻';
            case 'custom':
                if (!empty($custom_icon)) {
                    ob_start();
                    Icons_Manager::render_icon($custom_icon, ['aria-hidden' => 'true']);
                    $icon_html = ob_get_clean();
                    return $icon_html;
                }
                return '★';
            default:
                return '★';
        }
    }

    /**
     * Update form widget controls.
     *
     * Add input fields to allow the user to customize the rating field.
     *
     * @since 1.0.0
     * @param \Elementor\Widget_Base $widget The form widget instance.
     * @return void
     */
    public function update_controls($widget) {
        $elementor = \ElementorPro\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_controls = [
            'rating_scale' => [
                'name' => 'rating_scale',
                'label' => esc_html__('Rating Scale', 'cool-formkit'),
                'type' => \Elementor\Controls_Manager::SELECT,
                'options' => [
                    '5' => '0-5',
                    '10' => '0-10',
                ],
                'default' => '5',
                'condition' => [
                    'field_type' => $this->get_type(),
                ],
                'tab' => 'content',
                'inner_tab' => 'form_fields_content_tab',
                'tabs_wrapper' => 'form_fields_tabs',
            ],
            'rating_default' => [
                'name' => 'rating_default',
                'label' => esc_html__('Default Rating', 'cool-formkit'),
                'type' => \Elementor\Controls_Manager::NUMBER,
                'default' => '4',
                'condition' => [
                    'field_type' => $this->get_type(),
                ],
                'tab' => 'content',
                'inner_tab' => 'form_fields_content_tab',
                'tabs_wrapper' => 'form_fields_tabs',
            ],
            'rating_step' => [
                'name' => 'rating_step',
                'label' => esc_html__('Step', 'cool-formkit'),
                'type' => \Elementor\Controls_Manager::SELECT,
                'options' => [
                    '1' => '1',
                    '0.5' => '0.5',
                ],
                'default' => '1',
                'condition' => [
                    'field_type' => $this->get_type(),
                ],
                'tab' => 'content',
                'inner_tab' => 'form_fields_content_tab',
                'tabs_wrapper' => 'form_fields_tabs',
            ],
            'rating_icon' => [
                'name' => 'rating_icon',
                'label' => esc_html__('Rating Icon', 'cool-formkit'),
                'type' => \Elementor\Controls_Manager::SELECT,
                'options' => [
                    'star' => __('Star', 'cool-formkit'),
                    'custom' => __('Custom', 'cool-formkit'),
                ],
                'default' => 'star',
                'condition' => [
                    'field_type' => $this->get_type(),
                ],
                'tab' => 'content',
                'inner_tab' => 'form_fields_content_tab',
                'tabs_wrapper' => 'form_fields_tabs',
            ],
            'rating_icon_custom' => [
                'name' => 'rating_icon_custom',
                'label' => esc_html__('Custom Icon', 'cool-formkit'),
                'type' => \Elementor\Controls_Manager::ICONS,
                'condition' => [
                    'field_type' => $this->get_type(),
                    'rating_icon' => 'custom',
                ],
                'tab' => 'content',
                'inner_tab' => 'form_fields_content_tab',
                'tabs_wrapper' => 'form_fields_tabs',
            ],
            'rating_size' => [
                'name' => 'rating_size',
                'label' => esc_html__('Size', 'cool-formkit'),
                'type' => \Elementor\Controls_Manager::SLIDER,
                'size_units' => ['px'],
                'range' => [
                    'px' => [
                        'min' => 10,
                        'max' => 100,
                        'step' => 1,
                    ],
                ],
                'default' => [
                    'unit' => 'px',
                    'size' => 50,
                ],
                'condition' => [
                    'field_type' => $this->get_type(),
                ],
                'tab' => 'content',
                'inner_tab' => 'form_fields_content_tab',
                'tabs_wrapper' => 'form_fields_tabs',
            ],
            'rating_spacing' => [
                'name' => 'rating_spacing',
                'label' => esc_html__('Spacing', 'cool-formkit'),
                'type' => \Elementor\Controls_Manager::SLIDER,
                'size_units' => ['px'],
                'range' => [
                    'px' => [
                        'min' => 0,
                        'max' => 50,
                        'step' => 1,
                    ],
                ],
                'default' => [
                    'unit' => 'px',
                    'size' => 4,
                ],
                'condition' => [
                    'field_type' => $this->get_type(),
                ],
                'tab' => 'content',
                'inner_tab' => 'form_fields_content_tab',
                'tabs_wrapper' => 'form_fields_tabs',
            ],
            'rating_marked_color' => [
                'name' => 'rating_marked_color',
                'label' => esc_html__('Marked Color', 'cool-formkit'),
                'type' => \Elementor\Controls_Manager::COLOR,
                'default' => '#FFD700',
                'condition' => [
                    'field_type' => $this->get_type(),
                ],
                'tab' => 'content',
                'inner_tab' => 'form_fields_content_tab',
                'tabs_wrapper' => 'form_fields_tabs',
            ],
            'rating_unmarked_color' => [
                'name' => 'rating_unmarked_color',
                'label' => esc_html__('Unmarked Color', 'cool-formkit'),
                'type' => \Elementor\Controls_Manager::COLOR,
                'default' => '#E0E0E0',
                'condition' => [
                    'field_type' => $this->get_type(),
                ],
                'tab' => 'content',
                'inner_tab' => 'form_fields_content_tab',
                'tabs_wrapper' => 'form_fields_tabs',
            ],
            'rating_alignment' => [
                'name' => 'rating_alignment',
                'label' => esc_html__('Alignment', 'cool-formkit'),
                'type' => \Elementor\Controls_Manager::CHOOSE,
                'options' => [
                    'left' => [
                        'title' => __('Left', 'cool-formkit'),
                        'icon' => 'eicon-text-align-left',
                    ],
                    'center' => [
                        'title' => __('Center', 'cool-formkit'),
                        'icon' => 'eicon-text-align-center',
                    ],
                    'right' => [
                        'title' => __('Right', 'cool-formkit'),
                        'icon' => 'eicon-text-align-right',
                    ],
                ],
                'default' => 'left',
                'toggle' => true,
                'condition' => [
                    'field_type' => $this->get_type(),
                ],
                'tab' => 'content',
                'inner_tab' => 'form_fields_content_tab',
                'tabs_wrapper' => 'form_fields_tabs',
            ],
            'show_rating_value' => [
                'name' => 'show_rating_value',
                'label' => esc_html__('Show Rating Value', 'cool-formkit'),
                'type' => \Elementor\Controls_Manager::SWITCHER,
                'label_on' => esc_html__('Yes', 'cool-formkit'),
                'label_off' => esc_html__('No', 'cool-formkit'),
                'default' => '',
                'condition' => [
                    'field_type' => $this->get_type(),
                ],
                'tab' => 'content',
                'inner_tab' => 'form_fields_content_tab',
                'tabs_wrapper' => 'form_fields_tabs',
            ],
        ];

        $control_data['fields'] = $this->inject_field_controls($control_data['fields'], $field_controls);

        $widget->update_control('form_fields', $control_data);
    }

    /**
     * Field constructor.
     *
     * @since 1.0.0
     */
    public function __construct() {
        parent::__construct();
        add_action('elementor/preview/init', [$this, 'editor_preview_footer']);
		add_action( 'wp_enqueue_scripts', array( $this, 'add_assets_files' ) );
    }


    public function add_assets_files(){
        wp_register_style('cfkef-rating-field-style', CFKEF_PLUGIN_URL . 'assets/css/rating-field.css', null, CFKEF_PLUGIN_VERSION);
        wp_register_script('cfkef-rating-field-script', CFKEF_PLUGIN_URL . 'assets/js/rating-field.min.js', array('jquery'), CFKEF_PLUGIN_VERSION, true);        
    }

    /**
     * Elementor editor preview.
     *
     * @since 1.0.0
     * @return void
     */
    public function editor_preview_footer() {
        add_action('wp_footer', [$this, 'content_template_script']);
    }

    /**
     * Content template script.
     *
     * @since 1.0.0
     * @return void
     */
    public function content_template_script() {
        ?>
        <script>
        jQuery(document).ready(function() {
            elementor.hooks.addFilter(
                'elementor_pro/forms/content_template/field/<?php echo $this->get_type(); ?>',
                function(inputField, item, i) {
                    const fieldId = `form_field_${i}`;
                    const fieldClass = `elementor-field-subgroup elementor-rating`;
                    const ratingScale = item['rating_scale'];
                    const ratingDefault = item['rating_default'];
                    const ratingStep = item['rating_step'];
                    const ratingIcon = item['rating_icon'];
                    const ratingIconCustom = (item['rating_icon_custom'] !== undefined) ? item['rating_icon_custom'] : 'fa fa-star';
                    const ratingSize = item['rating_size']['size'];
                    const ratingSpacing = item['rating_spacing']['size'];
                    const ratingMarkedColor = item['rating_marked_color'];
                    const ratingUnmarkedColor = item['rating_unmarked_color'];
                    const showRatingValue = item['show_rating_value'];
                    const RatingAlignment = item['rating_alignment'];
                    // Define emoji mappings
                    const emojiMap = {
                        'heart': '♥',
                        'thumbs-up': '👍',
                        // Add more mappings as needed
                    };
                    

                    // Get the appropriate emoji or default to '★'
                    const getIcon = (icon) => {
                        if(typeof ratingIconCustom !== 'string'){
                            if (icon === 'custom' && typeof ratingIconCustom.value == "string" ) {
                                return `<i class="${ratingIconCustom.value}"></i>`;
                            }
                            if(icon === 'custom' && (ratingIconCustom.value.url).includes('.svg')){
                                // return `<img src="${ratingIconCustom.value.url}" alt="svg"></img>`;
                                const svg  = elementor.helpers.getInlineSvg(
                                    { id: ratingIconCustom.value.id, url: ratingIconCustom.value.url },
                                null                  
                                ); 
                                if(svg){
                                    return svg;
                                } else{
                                    setTimeout(() => {
                                                const loadedSvg = elementor.helpers.getInlineSvg(
                                                    { id: ratingIconCustom.value.id, url: ratingIconCustom.value.url },
                                                    null
                                                );
                                                if (loadedSvg) {
                                                    updateSvg(loadedSvg);
                                                } 
                                            }, 500);
                                }
                            }
                        }
                        return emojiMap[icon] || '★';
                    };

                    let icons = '';
                    for (let j = 1; j <= ratingScale; j++) {
                        const fullMarked = (j <= ratingDefault) ? 'marked' : '';
                        const halfMarked = ((j - 0.5) <= ratingDefault) ? 'marked' : '';
                        icons += `<span class="rating-icon-wrapper">`;
                        if (ratingStep == 0.5) {
                            icons += `<span class="rating-icon half ${halfMarked}" data-value="${j - 0.5}">${getIcon(ratingIcon)}</span>`;
                        }
                        icons += `<span class="rating-icon full ${fullMarked}" data-value="${j}">${getIcon(ratingIcon)}</span>`;
                        icons += `</span>`;
                    }

                    function  updateSvg(loadedSvg){
                        const elements = document.querySelectorAll(`#${fieldId} .rating-icon.full, #${fieldId} .rating-icon.half`);
                        elements.forEach(element => {
                            element.innerHTML = loadedSvg;
                        });

                        if (elements.length === 0) {
                            console.error(`Element with ID not found.`);
                        }
                    }

                    return `<div id="${fieldId}" class="${fieldClass}" data-rating-scale="${ratingScale}" data-rating-default="${ratingDefault}" data-rating-step="${ratingStep}" data-rating-icon="${ratingIcon}" data-rating-icon-custom="${ratingIconCustom}" data-rating-size="${ratingSize}" data-rating-spacing="${ratingSpacing}" data-rating-marked-color="${ratingMarkedColor}" data-rating-unmarked-color="${ratingUnmarkedColor}" data-show-rating-value="${showRatingValue}" style="--rating-size:${ratingSize}px; --rating-spacing:${ratingSpacing}px; --rating-marked-color:${ratingMarkedColor}; --rating-unmarked-color:${ratingUnmarkedColor}; --rating-alignment:${RatingAlignment};">${icons}<input type="hidden" name="${item.custom_id}" value="${ratingDefault}" class="elementor-rating-input">${showRatingValue ? `<span class="elementor-rating-value">(${ratingDefault}/${ratingScale})</span>` : ''}</div>`;
                }, 10, 3
            );
        });
        </script>
        <?php
    }

    /**
     * Field validation.
     *
     * Validate rating field value to ensure it complies to certain rules.
     *
     * @since 1.0.0
     * @access public
     * @param \ElementorPro\Modules\Forms\Classes\Field_Base   $field
     * @param \ElementorPro\Modules\Forms\Classes\Form_Record  $record
     * @param \ElementorPro\Modules\Forms\Classes\Ajax_Handler $ajax_handler
     * @return void
     */

     public function validation( $field, $record, $ajax_handler ) {
        $field_value   = empty( $field['value'] ) ? '' : $field['value'];
		$field_require = $field['required'];

        if ( $field_require && empty( $field_value ) ) {
			$ajax_handler->add_error(
				$field['id'],
				esc_html__( 'This field is required and cannot be left blank.', 'cool-formkit' )
			);
			return;
		}
    }    
}
}
