<?php

namespace Dits\CaW\Modules;

// Exit if accessed directly
defined('WPINC') || die;

use Dits\CaW\Utils\PluginFeatures;
// use Dits\CaW\Modules\CompareModal;
class Compare extends AbstractModule
{
    protected string $meta_key = 'dcaw_compared_products';

    function get_module_name(): string
    {
        return 'compare';
    }

    public function get_config(): array
    {
        return [
            'selectors' => [
                'counters' => '.js-dcaw-compare-count',
                'button' => '.js-dcaw-compare-btn',
                'remove' => '.js-dcaw-compare-remove-btn',
                'collapse' => '.js-dcaw-attribute-collapse',
                'tables' => '.dcaw-compare'
            ],
            'classes' => [
                'counter' => 'dcaw-compare-count',
                'empty' => 'is-empty',
                'active' => 'is-active',
                'loading' => 'is-loading',
                'collapse' => 'is-collapse'
            ],
            'max' => $this->settings->get('max', 'compare'),
            'compare_page' => $this->settings->get('compare_page', 'compare'),
        ];
    }

    public function hooks()
    {

        parent::hooks();

        // Compare shortcode
        add_shortcode('dcaw_compare_table', [$this, 'table_shortcode']);
        add_shortcode('dcaw_compare_table_without_cat', [$this, 'table_shortcode_without_categories']);

        add_action('wp_footer', [$this, 'display_popup']);
    }

    public function button($atts = []): string
    {
        $args = $this->get_button_args($atts['id'] ?? null);

        $current_data = $this->get_data();

        foreach ($current_data as $list) {
            if (in_array($args['id'], $list['products'])) {
                $args['class'] .= ' is-active';
            }
        }

        $args['show_popup'] = $this->settings->get('show_popup', 'compare');

        $is_link = $this->settings->get('dits_compare_button_view', 'compare');
        if (!empty($is_link) && $is_link === 'display_link') {
            return $this->view->get('compare-link.twig', $args);
        } else {
            return $this->view->get('compare-button.twig', $args);
        }
    }



    public function table_shortcode(): string
    {
        $args['content'] = $this->table();
        $args['categories'] = $this->get_categories();

        return $this->view->get('compare.twig', $args);
    }
    public function table_shortcode_without_categories(): string
    {
        $args['content'] = $this->table();

        return $this->view->get('compare.twig', $args);
    }
    public function table($selected_category_id = null): string
    {
        $html = '';
        $categories = $this->get_categories();

        // We iterate over all data lists
        foreach ($this->get_data() as $list) {
            $products = [];

            // Skip empty product lists
            if (empty($list['products'])) {
                continue;
            }

            // Iterate over product IDs in the list
            foreach ($list['products'] as $product_id) {
                $_product = wc_get_product($product_id);

                // Skip a product if its category does not match the selected one
                if ($selected_category_id && !has_term($selected_category_id, 'product_cat', $product_id)) {
                    continue;
                }

                // Fill the product data array
                $products[$product_id] = [
                    'img' => $_product->get_image(),
                    'title' => $_product->get_name(),
                    'link' => $_product->get_permalink(),
                    'price' => $_product->get_price_html(),
                    'short_description' => wp_trim_words($_product->get_short_description(), 20, '...'),
                    'buy' => do_shortcode('[add_to_cart id="' . $product_id . '" show_price="false" style=""]'),
                    'compare' => $this->button(['id' => $product_id]),
                    'attributes' => [
                        'availability' => [
                            'name' => __('Availability', 'dits-compare'),
                            'value' => $_product->is_in_stock() ? __('In stock', 'dits-compare') : __('Out of stock', 'dits-compare')
                        ]
                    ]
                ];

                $is_atribute = 'on';

                if (PluginFeatures::is_pro()) {
                    $is_atribute = $this->settings->get('attributes', 'field_settings');
                }
                // Add product attributes if enabled in the settings
                if ($is_atribute == "on") {
                    foreach ($_product->get_attributes() as $slug => $attribute_object) {
                        // if (in_array($slug, ['product_cat', 'product_tag'])) { // $this->settings->get('taxonomies', 'field_settings')
                        $products[$product_id]['attributes'][$slug] = [
                            'name' => wc_attribute_label($attribute_object->get_name(), $_product),
                            'value' => $_product->get_attribute($slug),
                        ];
                        // }
                    }
                }

                // Add product dimensions and weight if enabled in the settings
                if (true) {
                    $dimensions = ['length', 'height', 'width', 'weight'];
                    if (PluginFeatures::is_pro()) {
                        $dimensions = $this->settings->get('dimensions', 'field_settings');
                    }
                    foreach ($dimensions as $dimension) {
                        $method_name = 'get_' . $dimension;
                        $dimension_value = $_product->$method_name();
                        if ($dimension_value) {
                            $unit = $dimension === 'weight' ? get_option('woocommerce_weight_unit') : get_option('woocommerce_dimension_unit');
                            $name = ucfirst($dimension);
                            $products[$product_id]['attributes'][$dimension] = [
                                'name' => $name, //__($name, 'dits-compare'),
                                'value' => sprintf('%s %s', $dimension_value, $unit)
                            ];
                        }
                    }
                }
                $taxonomies = array('product_cat', 'product_tag');
                if (PluginFeatures::is_pro()) {
                    $taxonomies = $this->settings->get('taxonomies', 'field_settings');
                }
                // Add taxonomies if enabled in the settings
                if ($taxonomies) { // $this->settings->get('taxonomies', 'field_settings')
                    foreach ($taxonomies as $taxonomy) {
                        $terms = get_the_terms($product_id, $taxonomy);
                        if ($terms) {
                            $terms = array_map(fn($term) => $term->name, $terms);
                            $products[$product_id]['attributes'][$taxonomy] = [
                                'name' => get_taxonomy($taxonomy)->label,
                                'value' => implode(', ', $terms),
                            ];
                        }
                    }
                }
            }

            // Prepare data for the template

            // translators: %s is the number of products being compared.
            $args['title'] = sprintf(__('Compare %s products', 'dits-compare'), count($products));
            $args['products'] = $products;
            $args['noDelete'] = 'off';
            $args['count'] = count($products);
            $args['clear_text'] = __('Clear', 'dits-compare');
            $args['clear_icon'] = $this->view->get('icons/trash.svg');
            $args['categories'] = $categories;
            $args['selected_category_id'] = $selected_category_id;
            $args['hide_short_description'] = $this->settings->get('hide_short_description', 'field_settings');
            $args['attributes'] = $this->prepare_attributes($products);

            // Render the table using Twig
            $html .= $this->view->get('compare-table.twig', $args);
        }
        return $html;
    }



    public function get_categories()
    {
        $products = [];
        foreach ($this->get_data() as $list) {
            if (!empty($list['products'])) {
                $products = array_merge($products, $list['products']);
            }
        }

        $category_ids = [];
        foreach ($products as $product_id) {
            $terms = wp_get_post_terms($product_id, 'product_cat');
            foreach ($terms as $term) {
                $category_ids[] = $term->term_id;
            }
        }
        $category_ids = array_unique($category_ids);

        $categories = [];
        foreach ($category_ids as $category_id) {
            $term = get_term($category_id, 'product_cat');
            if (!is_wp_error($term)) {
                $categories[] = [
                    'id' => $term->term_id,
                    'name' => $term->name,
                ];
            }
        }

        return $categories;
    }




    public function display_popup()
    {
        // Get product data for the popup
        $products_data = $this->get_data();
        $popup_content = '';

        foreach ($products_data as $list) {
            $products = [];

            if (empty($list['products'])) {
                continue;
            }

            foreach ($list['products'] as $product_id) {
                $_product = wc_get_product($product_id);

                $products[] = [
                    'img' => $_product->get_image(),
                    'title' => $_product->get_name(),
                    'link' => $_product->get_permalink(),
                    'price' => $_product->get_price_html(),
                    'short_description' => wp_trim_words($_product->get_short_description(), 20, '...'),
                    'buy' => do_shortcode('[add_to_cart id="' . $product_id . '" show_price="false" style=""]'),
                    'compare' => $this->button(['id' => $product_id]),
                    'attributes' => [
                        'availability' => [
                            'name' => __('Availability', 'dits-compare'),
                            'value' => $_product->is_in_stock() ? __('In stock', 'dits-compare') : __('Out of stock', 'dits-compare')
                        ]
                    ]
                ];
                $is_atribute = 'on';
                if (PluginFeatures::is_pro()) {
                    $is_atribute = $this->settings->get('attributes', 'field_settings');
                }
                if ($is_atribute == 'on') { // $this->settings->get('attributes', 'compare')

                    foreach ($_product->get_attributes() as $slug => $attribute_object) {
                        if (in_array($slug, ['product_cat', 'product_tag'])) { // $this->settings->get('taxonomies', 'compare')
                            $products[count($products) - 1]['attributes'][$slug] = [
                                'name' => wc_attribute_label($attribute_object->get_name(), $_product),
                                'value' => $_product->get_attribute($slug),
                            ];
                        }
                    }
                }

                if (true) { //$this->settings->get('dimensions', 'compare')

                    $dimensions = ['length', 'height', 'width', 'weight'];
                    if (PluginFeatures::is_pro()) {
                        $dimensions = $this->settings->get('dimensions', 'field_settings');
                    }
                    foreach ($dimensions as $dimension) {
                        $method_name = 'get_' . $dimension;
                        $dimension_value = $_product->$method_name();
                        if ($dimension_value) {
                            $unit = $dimension === 'weight' ? get_option('woocommerce_weight_unit') : get_option('woocommerce_dimension_unit');
                            $name = ucfirst($dimension);
                            $products[count($products) - 1]['attributes'][$dimension] = [
                                'name' => $name, //__($name, 'dits-compare'),
                                'value' => sprintf('%s %s', $dimension_value, $unit)
                            ];
                        }
                    }
                }
                $taxonomies = array('product_cat', 'product_tag');
                if (PluginFeatures::is_pro()) {
                    $taxonomies = $this->settings->get('taxonomies', 'field_settings');
                }
                if ($taxonomies) { // $this->settings->get('taxonomies', 'compare')
                    foreach ($taxonomies as $taxonomy) {
                        $terms = get_the_terms($product_id, $taxonomy);
                        if ($terms) {
                            $terms = array_map(fn($term) => $term->name, $terms);
                            $products[count($products) - 1]['attributes'][$taxonomy] = [
                                'name' => get_taxonomy($taxonomy)->label,
                                'value' => implode(', ', $terms),
                            ];
                        }
                    }
                }
            }

            $args = [
                'products' => $products,
                'count' => count($products),
                // translators: %s is the number of products being compared.
                'title' => sprintf(__('Compare %s products', 'dits-compare'), count($products)),
                'clear_text' => __('Clear', 'dits-compare'),
                'clear_icon' => $this->view->get('icons/trash.svg'),
                'hide_short_description' => $this->settings->get('hide_short_description', 'field_settings'),
                'compare_page' => $this->settings->get('compare_page', 'compare'),
                'attributes' => $this->prepare_attributes($products),
                'categories' => $this->get_categories(),
            ];


            $popup_content .= $this->view->get('compare-popup.twig', $args);
        }

        // Check if the current page is a product page or a product archive
        if (is_product() || is_shop() || is_product_category() || is_product_tag()) {
            // Check if the show_popup setting is enabled, then display the popup
            if ($this->settings->get('show_popup', 'compare') == 'on') {
                // This popup ESCAPED by the twig functionality
                echo wp_kses_post($popup_content);
            }
        }
    }





    public function set_data(array $data)
    {
        if ($user_id = get_current_user_id()) {
            update_user_meta($user_id, $this->meta_key, $data);
        } else {
            $_SESSION[$this->meta_key] = $data;
        }

        $this->data = $data;
    }

    public function get_default_data(): array
    {
        return [
            ['id' => 0, 'products' => []]
        ];
    }

    public function load_data(): void
    {
        $data = $this->get_default_data();

        if ($user_id = get_current_user_id()) {
            $user_meta = get_user_meta($user_id, $this->meta_key, true);
            $data = $user_meta ?: $data;
        } else {
            $session_is_valid = (
                isset($_SESSION[$this->meta_key]) &&
                is_array($_SESSION[$this->meta_key]) &&
                isset($_SESSION[$this->meta_key]['id']) &&
                isset($_SESSION[$this->meta_key]['products']) &&
                is_array($_SESSION[$this->meta_key]['products'])
            );
            if (
                $session_is_valid
            ) {

                $session_data = $session_is_valid
                    ? [
                        'id' => sanitize_text_field($_SESSION[$this->meta_key]['id']),
                        'products' => array_map('sanitize_text_field', $_SESSION[$this->meta_key]['products']),

                    ] : ['id' => '', 'products' => []];
                $validate = array();
                $validate['id'] = sanitize_text_field($session_data['id']);
                foreach ($session_data['products'] as $product) {
                    $validate['products'][] = sanitize_text_field($product);
                }
                $data = $validate;
            }
        }
        if (PluginFeatures::is_pro()) {
            $trigger_selector = $this->settings->get('trigger_selector', 'field_settings');
            new CompareModal($this->view, $trigger_selector);
        }
        $this->set_data($data);
    }

    private function prepare_attributes(array $products): array
    {
        $attrs_keys = $attributes = [];

        foreach ($products as $product) {
            $attrs_keys = array_merge($attrs_keys, array_keys($product['attributes']));
        }

        $attrs_keys = array_values(array_unique($attrs_keys));

        foreach ($attrs_keys as $attr_slug) {
            foreach ($products as $id => $product) {
                $exist_attr = isset($product['attributes'][$attr_slug]);

                if ($exist_attr) {
                    $attributes[$attr_slug]['name'] = $product['attributes'][$attr_slug]['name'];
                }

                $attributes[$attr_slug]['values'][$id]['product'] = $product['title'];
                $attributes[$attr_slug]['values'][$id]['value'] = $exist_attr
                    ? $product['attributes'][$attr_slug]['value']
                    : false;
            }
        }

        return array_map(function ($attribute) {
            $all_values = array_map(function ($value) {
                return $value['value'];
            }, $attribute['values']);

            if (count(array_unique($all_values)) === 1) {
                $attribute['identical'] = true;
            }

            return $attribute;
        }, $attributes);
    }
}
