<?php

namespace Calio\Core;

if (!defined('ABSPATH')) {
    exit;
}

/**
 * Adds lightweight mega menu item controls to Appearance > Menus.
 */
class MegaMenuManager
{
    private const AJAX_ACTION_TEMPLATE = 'calio_megamenu_template';
    private const AJAX_NONCE_FIELD = '_ajax_nonce';
    private const NAV_MENU_NONCE_ACTION = 'update-nav_menu';
    private const NAV_MENU_NONCE_FIELD = 'update-nav-menu-nonce';

    public function __construct()
    {
        add_action('wp_ajax_' . self::AJAX_ACTION_TEMPLATE, [$this, 'ajax_megamenu_template']);
        add_action('wp_ajax_nopriv_' . self::AJAX_ACTION_TEMPLATE, [$this, 'ajax_megamenu_template']);

        if (!is_admin()) {
            return;
        }

        add_action('wp_nav_menu_item_custom_fields', [$this, 'render_item_fields'], 10, 4);
        add_action('wp_update_nav_menu_item', [$this, 'save_item_fields'], 10, 2);
        add_action('admin_enqueue_scripts', [$this, 'enqueue_admin_script']);
    }

    /**
     * Renders custom fields for each menu item.
     *
     * @param int   $item_id Menu item ID.
     * @param mixed $item    Menu item object.
     * @param int   $depth   Menu depth.
     * @param mixed $args    Walker args.
     */
    public function render_item_fields($item_id, $item, $depth, $args): void
    {
        if ((int) $depth !== 0) {
            return;
        }

        $enabled = get_post_meta($item_id, '_calio_megamenu_enabled', true) === '1';
        $template_id = (int) get_post_meta($item_id, '_calio_megamenu_template_id', true);
        $width_mode = (string) get_post_meta($item_id, '_calio_megamenu_width_mode', true);
        $custom_width = (string) get_post_meta($item_id, '_calio_megamenu_custom_width', true);
        $badge_text = (string) get_post_meta($item_id, '_calio_megamenu_badge_text', true);
        $badge_color = (string) get_post_meta($item_id, '_calio_megamenu_badge_color', true);
        $badge_bg = (string) get_post_meta($item_id, '_calio_megamenu_badge_bg', true);
        $icon_class = (string) get_post_meta($item_id, '_calio_megamenu_icon_class', true);
        $icon_color = (string) get_post_meta($item_id, '_calio_megamenu_icon_color', true);
        $position_type = (string) get_post_meta($item_id, '_calio_megamenu_position_type', true);
        $mobile_submenu_type = (string) get_post_meta($item_id, '_calio_megamenu_mobile_submenu_type', true);
        $ajax_load = (string) get_post_meta($item_id, '_calio_megamenu_ajax_load', true);

        if ($width_mode === '') {
            $width_mode = 'default';
        }

        if (!in_array($position_type, ['relative', 'top'], true)) {
            $position_type = 'relative';
        }

        if (!in_array($mobile_submenu_type, ['builder', 'submenu'], true)) {
            $mobile_submenu_type = 'builder';
        }

        if (!in_array($ajax_load, ['yes', 'no'], true)) {
            $ajax_load = 'no';
        }

        $templates = $this->get_elementor_templates();
        ?>
        <div class="description-wide calio-megamenu-fields" style="padding:10px 12px;border:1px solid #dcdcde;border-radius:8px;background:#fff;margin:10px 0;">
            <strong style="display:block;margin-bottom:10px;"><?php echo esc_html__('Calio Mega Menu', 'calio-addon'); ?></strong>

            <p class="description">
                <label>
                    <input type="checkbox" name="calio_megamenu_enabled[<?php echo esc_attr((string) $item_id); ?>]" value="1" <?php checked($enabled); ?> />
                    <?php echo esc_html__('Enable Mega Panel for this item', 'calio-addon'); ?>
                </label>
            </p>

            <p class="description description-wide">
                <label for="calio-mega-template-<?php echo esc_attr((string) $item_id); ?>">
                    <?php echo esc_html__('Mega Template', 'calio-addon'); ?><br />
                    <select id="calio-mega-template-<?php echo esc_attr((string) $item_id); ?>" name="calio_megamenu_template_id[<?php echo esc_attr((string) $item_id); ?>]" style="width:100%;">
                        <option value="0"><?php echo esc_html__('Select Elementor Template', 'calio-addon'); ?></option>
                        <?php foreach ($templates as $tpl_id => $tpl_label) : ?>
                            <option value="<?php echo esc_attr((string) $tpl_id); ?>" <?php selected($template_id, (int) $tpl_id); ?>>
                                <?php echo esc_html($tpl_label); ?>
                            </option>
                        <?php endforeach; ?>
                    </select>
                </label>
            </p>

            <p class="description description-wide">
                <label for="calio-mega-width-mode-<?php echo esc_attr((string) $item_id); ?>">
                    <?php echo esc_html__('Width Mode', 'calio-addon'); ?><br />
                    <select id="calio-mega-width-mode-<?php echo esc_attr((string) $item_id); ?>" name="calio_megamenu_width_mode[<?php echo esc_attr((string) $item_id); ?>]" style="width:100%;">
                        <option value="default" <?php selected($width_mode, 'default'); ?>><?php echo esc_html__('Default', 'calio-addon'); ?></option>
                        <option value="full" <?php selected($width_mode, 'full'); ?>><?php echo esc_html__('Full Width', 'calio-addon'); ?></option>
                        <option value="custom" <?php selected($width_mode, 'custom'); ?>><?php echo esc_html__('Custom Width', 'calio-addon'); ?></option>
                    </select>
                </label>
            </p>

            <p class="description description-wide calio-mega-custom-width-row">
                <label for="calio-mega-custom-width-<?php echo esc_attr((string) $item_id); ?>">
                    <?php echo esc_html__('Custom Width (e.g. 960px)', 'calio-addon'); ?><br />
                    <input type="text" id="calio-mega-custom-width-<?php echo esc_attr((string) $item_id); ?>" name="calio_megamenu_custom_width[<?php echo esc_attr((string) $item_id); ?>]" value="<?php echo esc_attr($custom_width); ?>" style="width:100%;" />
                </label>
            </p>

            <p class="description description-wide">
                <label for="calio-mega-position-type-<?php echo esc_attr((string) $item_id); ?>">
                    <?php echo esc_html__('Mega Menu Position', 'calio-addon'); ?><br />
                    <select id="calio-mega-position-type-<?php echo esc_attr((string) $item_id); ?>" name="calio_megamenu_position_type[<?php echo esc_attr((string) $item_id); ?>]" style="width:100%;">
                        <option value="relative" <?php selected($position_type, 'relative'); ?>><?php echo esc_html__('Relative', 'calio-addon'); ?></option>
                        <option value="top" <?php selected($position_type, 'top'); ?>><?php echo esc_html__('Top', 'calio-addon'); ?></option>
                    </select>
                </label>
            </p>

            <p class="description description-wide">
                <label for="calio-mega-mobile-submenu-<?php echo esc_attr((string) $item_id); ?>">
                    <?php echo esc_html__('Mobile Submenu Source', 'calio-addon'); ?><br />
                    <select id="calio-mega-mobile-submenu-<?php echo esc_attr((string) $item_id); ?>" name="calio_megamenu_mobile_submenu_type[<?php echo esc_attr((string) $item_id); ?>]" style="width:100%;">
                        <option value="builder" <?php selected($mobile_submenu_type, 'builder'); ?>><?php echo esc_html__('Builder Content', 'calio-addon'); ?></option>
                        <option value="submenu" <?php selected($mobile_submenu_type, 'submenu'); ?>><?php echo esc_html__('WordPress Submenu List', 'calio-addon'); ?></option>
                    </select>
                </label>
            </p>

            <p class="description description-wide">
                <label for="calio-mega-ajax-load-<?php echo esc_attr((string) $item_id); ?>">
                    <?php echo esc_html__('Ajax Load Panel', 'calio-addon'); ?><br />
                    <select id="calio-mega-ajax-load-<?php echo esc_attr((string) $item_id); ?>" name="calio_megamenu_ajax_load[<?php echo esc_attr((string) $item_id); ?>]" style="width:100%;">
                        <option value="no" <?php selected($ajax_load, 'no'); ?>><?php echo esc_html__('No', 'calio-addon'); ?></option>
                        <option value="yes" <?php selected($ajax_load, 'yes'); ?>><?php echo esc_html__('Yes', 'calio-addon'); ?></option>
                    </select>
                </label>
            </p>

            <p class="description description-wide">
                <label for="calio-mega-icon-<?php echo esc_attr((string) $item_id); ?>">
                    <?php echo esc_html__('Icon Class (optional)', 'calio-addon'); ?><br />
                    <input type="text" id="calio-mega-icon-<?php echo esc_attr((string) $item_id); ?>" name="calio_megamenu_icon_class[<?php echo esc_attr((string) $item_id); ?>]" value="<?php echo esc_attr($icon_class); ?>" style="width:100%;" placeholder="fas fa-star" />
                </label>
            </p>

            <p class="description description-wide">
                <label for="calio-mega-icon-color-<?php echo esc_attr((string) $item_id); ?>">
                    <?php echo esc_html__('Icon Color', 'calio-addon'); ?><br />
                    <input type="color" id="calio-mega-icon-color-<?php echo esc_attr((string) $item_id); ?>" name="calio_megamenu_icon_color[<?php echo esc_attr((string) $item_id); ?>]" value="<?php echo esc_attr($icon_color !== '' ? $icon_color : '#334155'); ?>" />
                </label>
            </p>

            <p class="description description-wide">
                <label for="calio-mega-badge-text-<?php echo esc_attr((string) $item_id); ?>">
                    <?php echo esc_html__('Badge Text (optional)', 'calio-addon'); ?><br />
                    <input type="text" id="calio-mega-badge-text-<?php echo esc_attr((string) $item_id); ?>" name="calio_megamenu_badge_text[<?php echo esc_attr((string) $item_id); ?>]" value="<?php echo esc_attr($badge_text); ?>" style="width:100%;" />
                </label>
            </p>

            <p class="description" style="display:flex;gap:8px;align-items:center;">
                <label for="calio-mega-badge-color-<?php echo esc_attr((string) $item_id); ?>">
                    <?php echo esc_html__('Badge Color', 'calio-addon'); ?><br />
                    <input type="color" id="calio-mega-badge-color-<?php echo esc_attr((string) $item_id); ?>" name="calio_megamenu_badge_color[<?php echo esc_attr((string) $item_id); ?>]" value="<?php echo esc_attr($badge_color !== '' ? $badge_color : '#ffffff'); ?>" />
                </label>

                <label for="calio-mega-badge-bg-<?php echo esc_attr((string) $item_id); ?>">
                    <?php echo esc_html__('Badge Background', 'calio-addon'); ?><br />
                    <input type="color" id="calio-mega-badge-bg-<?php echo esc_attr((string) $item_id); ?>" name="calio_megamenu_badge_bg[<?php echo esc_attr((string) $item_id); ?>]" value="<?php echo esc_attr($badge_bg !== '' ? $badge_bg : '#7c3aed'); ?>" />
                </label>
            </p>
        </div>
        <?php
    }

    /**
     * Saves custom menu item meta fields.
     */
    public function save_item_fields(int $menu_id, int $menu_item_db_id): void
    {
        if (!current_user_can('edit_theme_options')) {
            return;
        }

        check_admin_referer(self::NAV_MENU_NONCE_ACTION, self::NAV_MENU_NONCE_FIELD);

        $enabled_map = $this->posted_map('calio_megamenu_enabled');
        $template_map = $this->posted_map('calio_megamenu_template_id');
        $width_mode_map = $this->posted_map('calio_megamenu_width_mode');
        $custom_width_map = $this->posted_map('calio_megamenu_custom_width');
        $icon_map = $this->posted_map('calio_megamenu_icon_class');
        $position_type_map = $this->posted_map('calio_megamenu_position_type');
        $mobile_submenu_type_map = $this->posted_map('calio_megamenu_mobile_submenu_type');
        $ajax_load_map = $this->posted_map('calio_megamenu_ajax_load');
        $icon_color_map = $this->posted_map('calio_megamenu_icon_color');
        $badge_text_map = $this->posted_map('calio_megamenu_badge_text');
        $badge_color_map = $this->posted_map('calio_megamenu_badge_color');
        $badge_bg_map = $this->posted_map('calio_megamenu_badge_bg');

        $enabled = isset($enabled_map[$menu_item_db_id]) ? '1' : '0';
        $template_id = isset($template_map[$menu_item_db_id]) ? (int) $template_map[$menu_item_db_id] : 0;
        $width_mode = isset($width_mode_map[$menu_item_db_id]) ? sanitize_key((string) $width_mode_map[$menu_item_db_id]) : 'default';
        $custom_width = isset($custom_width_map[$menu_item_db_id]) ? sanitize_text_field((string) $custom_width_map[$menu_item_db_id]) : '';
        $icon_class = isset($icon_map[$menu_item_db_id]) ? sanitize_text_field((string) $icon_map[$menu_item_db_id]) : '';
        $icon_color = isset($icon_color_map[$menu_item_db_id]) ? sanitize_hex_color((string) $icon_color_map[$menu_item_db_id]) : '';
        $position_type = isset($position_type_map[$menu_item_db_id]) ? sanitize_key((string) $position_type_map[$menu_item_db_id]) : 'relative';
        $mobile_submenu_type = isset($mobile_submenu_type_map[$menu_item_db_id]) ? sanitize_key((string) $mobile_submenu_type_map[$menu_item_db_id]) : 'builder';
        $ajax_load = isset($ajax_load_map[$menu_item_db_id]) ? sanitize_key((string) $ajax_load_map[$menu_item_db_id]) : 'no';
        $badge_text = isset($badge_text_map[$menu_item_db_id]) ? sanitize_text_field((string) $badge_text_map[$menu_item_db_id]) : '';
        $badge_color = isset($badge_color_map[$menu_item_db_id]) ? sanitize_hex_color((string) $badge_color_map[$menu_item_db_id]) : '';
        $badge_bg = isset($badge_bg_map[$menu_item_db_id]) ? sanitize_hex_color((string) $badge_bg_map[$menu_item_db_id]) : '';

        if (!in_array($width_mode, ['default', 'full', 'custom'], true)) {
            $width_mode = 'default';
        }

        if ($custom_width !== '' && !preg_match('/^\d+(\.\d+)?(px|%|rem|em|vw)$/', $custom_width)) {
            $custom_width = '';
        }

        if (!in_array($position_type, ['relative', 'top'], true)) {
            $position_type = 'relative';
        }

        if (!in_array($mobile_submenu_type, ['builder', 'submenu'], true)) {
            $mobile_submenu_type = 'builder';
        }

        if (!in_array($ajax_load, ['yes', 'no'], true)) {
            $ajax_load = 'no';
        }

        update_post_meta($menu_item_db_id, '_calio_megamenu_enabled', $enabled);
        update_post_meta($menu_item_db_id, '_calio_megamenu_template_id', $template_id);
        update_post_meta($menu_item_db_id, '_calio_megamenu_width_mode', $width_mode);
        update_post_meta($menu_item_db_id, '_calio_megamenu_custom_width', $custom_width);
        update_post_meta($menu_item_db_id, '_calio_megamenu_icon_class', $icon_class);
        update_post_meta($menu_item_db_id, '_calio_megamenu_icon_color', $icon_color ?: '');
        update_post_meta($menu_item_db_id, '_calio_megamenu_position_type', $position_type);
        update_post_meta($menu_item_db_id, '_calio_megamenu_mobile_submenu_type', $mobile_submenu_type);
        update_post_meta($menu_item_db_id, '_calio_megamenu_ajax_load', $ajax_load);
        update_post_meta($menu_item_db_id, '_calio_megamenu_badge_text', $badge_text);
        update_post_meta($menu_item_db_id, '_calio_megamenu_badge_color', $badge_color ?: '');
        update_post_meta($menu_item_db_id, '_calio_megamenu_badge_bg', $badge_bg ?: '');
    }

    /**
     * Keeps custom width input visible only when width mode is set to custom.
     */
    public function enqueue_admin_script(string $hook_suffix = ''): void
    {
        if ($hook_suffix !== 'nav-menus.php') {
            return;
        }

        $script_path = CALIO_PATH . 'assets/build/admin/megamenu.js';
        $script_url = CALIO_URL . 'assets/build/admin/megamenu.js';
        $asset_meta_path = CALIO_PATH . 'assets/build/admin/megamenu.asset.php';
        $dependencies = [];
        $version = CALIO_VERSION;

        if (is_readable($asset_meta_path)) {
            $asset_meta = require $asset_meta_path;
            if (is_array($asset_meta)) {
                if (!empty($asset_meta['dependencies']) && is_array($asset_meta['dependencies'])) {
                    $dependencies = array_map('strval', $asset_meta['dependencies']);
                }
                if (!empty($asset_meta['version']) && is_string($asset_meta['version'])) {
                    $version = $asset_meta['version'];
                }
            }
        } elseif (is_readable($script_path)) {
            $version = (string) (filemtime($script_path) ?: CALIO_VERSION);
        }

        if (!is_readable($script_path)) {
            return;
        }

        wp_register_script('calio-megamenu-admin', $script_url, $dependencies, $version, true);
        wp_enqueue_script('calio-megamenu-admin');
    }

    /**
     * Ajax endpoint for lazy-loading megamenu Elementor template output.
     */
    public function ajax_megamenu_template(): void
    {
        if (check_ajax_referer(self::AJAX_ACTION_TEMPLATE, self::AJAX_NONCE_FIELD, false) === false) {
            wp_send_json_error(['message' => esc_html__('Invalid request.', 'calio-addon')], 403);
        }

        $template_id = isset($_POST['template_id']) ? absint(wp_unslash($_POST['template_id'])) : 0;
        if ($template_id <= 0) {
            wp_send_json_error(['message' => esc_html__('Invalid template.', 'calio-addon')], 400);
        }

        $template_post = get_post($template_id);
        if (!$template_post || $template_post->post_type !== 'elementor_library') {
            wp_send_json_error(['message' => esc_html__('Template not found.', 'calio-addon')], 404);
        }

        $status = get_post_status($template_id);
        if ($status !== 'publish' && !current_user_can('edit_post', $template_id)) {
            wp_send_json_error(['message' => esc_html__('Template is not public.', 'calio-addon')], 403);
        }

        if (!class_exists('\Elementor\Plugin')) {
            wp_send_json_error(['message' => esc_html__('Elementor is required.', 'calio-addon')], 500);
        }

        $content = (string) \Elementor\Plugin::$instance->frontend->get_builder_content_for_display($template_id, true);
        if ($content === '') {
            wp_send_json_error(['message' => esc_html__('No template content found.', 'calio-addon')], 404);
        }

        wp_send_json_success(['html' => $content]);
    }

    /**
     * @return array<int, string>
     */
    private function get_elementor_templates(): array
    {
        static $templates = null;
        if (is_array($templates)) {
            return $templates;
        }

        $templates = [];
        $posts = get_posts([
            'post_type' => 'elementor_library',
            'post_status' => ['publish', 'draft', 'private'],
            'posts_per_page' => -1,
            'orderby' => 'title',
            'order' => 'ASC',
            'no_found_rows' => true,
        ]);

        foreach ($posts as $post) {
            if (!isset($post->ID, $post->post_title)) {
                continue;
            }

            $templates[(int) $post->ID] = sprintf('#%d %s', (int) $post->ID, (string) $post->post_title);
        }

        return $templates;
    }

    /**
     * @return array<int|string, string>
     */
    private function posted_map(string $key): array
    {
        // Nonce is verified in save_item_fields() before this helper reads menu form fields.
        // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
        if (!isset($_POST[$key]) || !is_array($_POST[$key])) {
            return [];
        }

        // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
        $raw = map_deep(wp_unslash($_POST[$key]), 'sanitize_text_field');

        return is_array($raw) ? $raw : [];
    }
}
