<?php
declare(strict_types=1);

// IO Elementor Pro Form Field: Rental Picker (radio list with images)
// Displays rentals as a radio list (image + name). Values posted are rental (WP page) IDs.
// Admin can choose specific rentals and/or categories to include.

if (!defined('ABSPATH')) {
    exit; // Exit if accessed directly
}

use Elementor\Controls_Manager;
use ElementorPro\Modules\Forms\Fields\Field_Base;

if (class_exists('ElementorPro\\Modules\\Forms\\Fields\\Field_Base')) {

    class IO_Rental_Picker_Field extends Field_Base
    {
        public function get_type(): string
        {
            return 'io_rental_picker';
        }

        public function get_name(): string
        {
            return __('IO Rental Picker', 'inflatableoffice');
        }

        public function get_label(): string
        {
            return __('IO Rental Picker', 'inflatableoffice');
        }

        public function get_title(): string
        {
            return __('IO Rental Picker', 'inflatableoffice');
        }

        // Add custom controls for this field type in the Elementor Form widget
        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) || empty($control_data['fields'])) {
                return;
            }

            $field_controls = [
                'io_rental_picker_notice' => [
                    'name' => 'io_rental_picker_notice',
                    'label' => __('IO Rental Picker', 'inflatableoffice'),
                    'type' => Controls_Manager::RAW_HTML,
                    'raw' => __('Choose which rentals to show by selecting specific Items and/or Categories. The visitor will pick one rental. The submitted value will be the rental ID.', 'inflatableoffice'),
                    'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
                    'condition' => [
                        'field_type' => $this->get_type(),
                    ],
                    'tab' => 'content',
                    'inner_tab' => 'form_fields_content_tab',
                    'tabs_wrapper' => 'form_fields_tabs',
                    'tab_wrapper' => 'form_fields_content_tab',
                ],

                'io_rental_picker_items' => [
                    'name' => 'io_rental_picker_items',
                    'label' => __('Items (specific rentals)', 'inflatableoffice'),
                    'type' => Controls_Manager::SELECT2,
                    'multiple' => true,
                    'options' => $this->get_rental_items_options(),
                    'label_block' => true,
                    'condition' => [
                        'field_type' => $this->get_type(),
                    ],
                    'tab' => 'content',
                    'inner_tab' => 'form_fields_content_tab',
                    'tabs_wrapper' => 'form_fields_tabs',
                    'tab_wrapper' => 'form_fields_content_tab',
                ],

                'io_rental_picker_categories' => [
                    'name' => 'io_rental_picker_categories',
                    'label' => __('Categories (show rentals from these)', 'inflatableoffice'),
                    'type' => Controls_Manager::SELECT2,
                    'multiple' => true,
                    'options' => $this->get_category_options(),
                    'label_block' => true,
                    'condition' => [
                        'field_type' => $this->get_type(),
                    ],
                    'tab' => 'content',
                    'inner_tab' => 'form_fields_content_tab',
                    'tabs_wrapper' => 'form_fields_tabs',
                    'tab_wrapper' => 'form_fields_content_tab',
                ],

                'io_rental_picker_layout_cols' => [
                    'name' => 'io_rental_picker_layout_cols',
                    'label' => __('# of columns', 'inflatableoffice'),
                    'type' => Controls_Manager::NUMBER,
                    'min' => 1,
                    'max' => 6,
                    'step' => 1,
                    'default' => 4,
                    'condition' => [
                        'field_type' => $this->get_type(),
                    ],
                    'tab' => 'content',
                    'inner_tab' => 'form_fields_content_tab',
                    'tabs_wrapper' => 'form_fields_tabs',
                    'tab_wrapper' => 'form_fields_content_tab',
                ],
            ];

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

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

        public function render($item, $item_index, $form)
        {
            $field_id = $form->get_id( $item, $item_index );

            $form->add_render_attribute( 'io_rental_select' . $item_index, [
                'name'  => $form->get_attribute_name($item),
                'id'    => $field_id,
                'class' => 'elementor-field-textual ' . $item['css_classes'],
            ] );
            $value = isset( $item['field_value'] ) ? $item['field_value'] : '';

            $cols = isset($item['io_rental_picker_layout_cols']) && (int)$item['io_rental_picker_layout_cols'] > 0
                ? (int)$item['io_rental_picker_layout_cols'] : 4;
            if ($cols < 1 || $cols > 6) { $cols = 4; }

            $selected_item_ids = [];
            if (!empty($item['io_rental_picker_items'])) {
                if (is_array($item['io_rental_picker_items'])) {
                    $selected_item_ids = array_map('intval', $item['io_rental_picker_items']);
                } elseif (is_string($item['io_rental_picker_items'])) {
                    $selected_item_ids = array_map('intval', array_filter(explode(',', $item['io_rental_picker_items'])));
                }
            }
            $selected_cat_ids = [];
            if (!empty($item['io_rental_picker_categories'])) {
                if (is_array($item['io_rental_picker_categories'])) {
                    $selected_cat_ids = array_map('intval', $item['io_rental_picker_categories']);
                } elseif (is_string($item['io_rental_picker_categories'])) {
                    $selected_cat_ids = array_map('intval', array_filter(explode(',', $item['io_rental_picker_categories'])));
                }
            }

            $rentals = $this->collect_rentals($selected_item_ids, $selected_cat_ids);

            // Output
            echo '<div class="io-rental-picker" role="group" aria-labelledby="' . esc_attr($field_id) . '-label">';
            if (!empty($item['field_label'])) {
                echo '<div id="' . esc_attr($field_id) . '-label" class="io-rental-picker-label">' . esc_html($item['field_label']) . '</div>';
            }

            $grid_style = 'display:grid;grid-template-columns:repeat(' . (int)$cols . ',1fr);gap:12px;';
            echo '<div class="io-rental-picker-grid" style="' . esc_attr($grid_style) . '">';

            if (empty($rentals)) {
                echo '<div>' . esc_html__('No rentals found for this selection.', 'inflatableoffice') . '</div>';
            } else {
                foreach ($rentals as $r) {
                    $rid = (int)$r['rental_id'];
                    $checked = ((string)$value === (string)$rid) ? ' checked' : '';
                    $img = !empty($r['image']) ? $r['image'] : '';
                    $title = $r['title'];
                    $radio_id = $field_id . '-' . $rid;
                    $field_name = $form->get_attribute_name($item);
                    echo '<label for="' . esc_attr($radio_id) . '" class="io-rental-picker-card" style="border:1px solid #ddd;border-radius:6px;padding:8px;cursor:pointer;display:block;">';
                    echo '<input type="radio" name="' . esc_attr($field_name) . '" id="' . esc_attr($radio_id) . '" value="' . esc_attr((string)$rid) . '" style="margin-right:8px;"' . $checked . ' />';
                    if ($img) {
                        echo '<div style="width:100%;aspect-ratio:4/3;overflow:hidden;border-radius:4px;margin:4px 0 6px 0;background:#fafafa;display:flex;align-items:center;justify-content:center;">'
                           . '<img src="' . esc_url($img) . '" alt="' . esc_attr($title) . '" style="max-width:100%;max-height:100%;object-fit:cover;" />'
                           . '</div>';
                    }
                    echo '<div class="io-rental-picker-title" style="font-size:14px;font-weight:600;line-height:1.2;">' . esc_html($title) . '</div>';
                    echo '</label>';
                }
            }

            echo '</div>'; // grid
            echo '</div>'; // wrapper
        }

        // Collect rentals based on selected items and categories
        private function collect_rentals(array $item_ids, array $category_ids): array
        {
            $rentals_map = $this->get_all_rentals_indexed(); // title-normalized => [id,title,image]
            $by_id = [];

            // Specific items first
            foreach ($item_ids as $pid) {
                $p = get_post($pid);
                $rid = $this->get_post_rental_id($p->post_content);
                if ($p && $p->post_type === 'page') {
                    $title = get_the_title($pid);
                    $by_id[$rid] = [
                        'post_id' => $pid,
                        'rental_id' => $rid,
                        'title' => $title,
                        'image' => $this->get_post_image($pid),
                    ];
                }
            }

            // From categories: parse shortcodes within selected category pages to find rentals by name
            foreach ($category_ids as $cid) {
                $p = get_post($cid);
                if (!$p || $p->post_type !== 'page') { continue; }
                $content = get_post_field('post_content', $cid);
                if (!$content) { continue; }
                // Find all [sc :io_*] shortcodes
                if (preg_match_all('/\[sc\s*:io_[^\]]*\]/', $content, $m)) {
                    foreach ($m[0] as $sc) {
                        $name = $this->extract_attr($sc, 'rental_name');
                        if (!$name) { continue; }
                        $norm = $this->normalize_title($name);
                        $rid = $this->get_post_rental_id($sc);
                        if (isset($rentals_map[$norm])) {
                            $by_id[$rid] = $rentals_map[$norm];
                        }
                    }
                }
            }

            // If neither provided, show all rentals (safety net, but keep list reasonable)
            if (empty($by_id) && empty($item_ids) && empty($category_ids)) {
                $all = $this->get_all_rentals_list();
                foreach ($all as $r) { $by_id[$r['id']] = $r; }
            }

            // Sort by title
            uasort($by_id, function ($a, $b) {
                return strcasecmp($a['title'], $b['title']);
            });

            return array_values($by_id);
        }

        private function get_all_rentals_indexed(): array
        {
            $indexed = [];
            foreach ($this->get_all_rentals_list() as $r) {
                $indexed[$this->normalize_title($r['title'])] = $r;
            }
            return $indexed;
        }

        private function get_all_rentals_list(): array
        {
            $args = [
                'orderby' => 'name',
                'order' => 'ASC',
                'post_type' => 'page',
                'posts_per_page' => -1,
                'fields' => 'ids',
            ];
            $q = new WP_Query($args);
            $list = [];
            while ($q->have_posts()) { $q->the_post();
                $pid = get_the_ID();
                $content = get_the_content(null, false, $pid);
                $rid = $this->get_post_rental_id($content);
                if (strpos($content, '[sc :io_rental') !== false) {
                    $list[] = [
                        'post_id' => $pid,
                        'rental_id' => $rid,
                        'title' => get_the_title($pid),
                        'image' => $this->get_post_image($pid),
                    ];
                }
            }
            wp_reset_postdata();
            return $list;
        }

        private function get_post_image(int $post_id): string
        {
            $img = '';
            if (has_post_thumbnail($post_id)) {
                $src = wp_get_attachment_image_src(get_post_thumbnail_id($post_id), 'medium');
                if (!empty($src[0])) { $img = $src[0]; }
            }
            return $img;
        }

        private function extract_attr(string $shortcode, string $attr): ?string
        {
            // Attempt to parse attributes from our [sc :io_*] style strings
            $attrs = shortcode_parse_atts(trim($this->trim_sc_brackets($shortcode)));
            if (isset($attrs[$attr])) {
                return html_entity_decode((string)$attrs[$attr]);
            }
            return null;
        }

        private function trim_sc_brackets(string $sc): string
        {
            // Remove leading "[" and optional leading "sc " and trailing "]"
            $sc = ltrim($sc);
            if (substr($sc, 0, 1) === '[') { $sc = substr($sc, 1); }
            if (substr($sc, -1) === ']') { $sc = substr($sc, 0, -1); }
            if (strpos($sc, 'sc ') === 0) { $sc = substr($sc, 3); }
            return $sc;
        }

        private function normalize_title(string $title): string
        {
            $title = html_entity_decode($title);
            $title = str_replace('–', '-', $title); // en dash to hyphen
            $title = trim($title);
            return mb_strtolower($title);
        }

        private function get_category_options(): array
        {
            $opts = [];
            $args = [
                'orderby' => 'name',
                'order' => 'ASC',
                'post_type' => 'page',
                'posts_per_page' => -1,
                'fields' => 'ids',
            ];
            $q = new WP_Query($args);
            while ($q->have_posts()) { $q->the_post();
                $pid = get_the_ID();
                $content = get_the_content(null, false, $pid);
                $include_page = get_post_meta($pid, 'io-include-featured', true) === 'true';
                if (strpos($content, '[sc :io_category') !== false || $include_page) {
                    $opts[$pid] = get_the_title($pid);
                }
            }
            wp_reset_postdata();
            return $opts;
        }

        private function get_rental_items_options(): array
        {
            $opts = [];
            foreach ($this->get_all_rentals_list() as $r) {
                $opts[$r['post_id']] = $r['title'];
            }
            return $opts;
        }

        private function get_post_rental_id($content): string{
            $found_rid = preg_match('/rental_id="([^"]*)"/', $content, $matches_rid);
            $found_increment = preg_match('/increment="([^"]*)"/', $content, $matches_increment);
            if($found_rid){
                return $matches_rid[1]."-".$found_increment[1]."|";
            }
            return "";
        }
    }
}
