<?php
namespace Tiamr\Admin;

use Tiamr\Meta;
use Tiamr\Utils\Roles;
use Tiamr\Utils\Sanitizer;

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


final class Menu_Item_Fields {
    public function __construct() {
        add_action('wp_nav_menu_item_custom_fields', [$this, 'render_fields'], 10, 5);
        add_action('wp_update_nav_menu_item', [$this, 'save_fields'], 10, 3);
        add_action('wp_ajax_tiamr_search_content', [$this, 'ajax_search_content']);
    }

    /**
     * @param int      $item_id
     * @param \WP_Post $item
     * @param int      $depth
     * @param object   $args
     * @param int      $id
     */
    public function render_fields($item_id, $item, $depth, $args, $id): void {
        $item_id             = (int) $item_id;
        $rule                = Meta::get_rule($item_id);
        $audience_conditions = Meta::get_audience_conditions();
        $location_conditions = Meta::get_location_conditions();
        $actions             = Meta::get_actions();
        $roles               = Roles::get_all_roles();

        $display_audience = $rule['audience'] ?? Meta::AUDIENCE_EVERYONE;
        $display_location = $rule['location'] ?? Meta::LOCATION_EVERYWHERE;

        $is_role_condition = in_array($display_audience, [Meta::AUDIENCE_ROLE_IS, Meta::AUDIENCE_ROLE_IS_NOT], true);
        $is_page_condition = in_array($display_location, [Meta::LOCATION_PAGE_IS, Meta::LOCATION_PAGE_IS_NOT], true);
        $is_post_condition = in_array($display_location, [Meta::LOCATION_POST_IS, Meta::LOCATION_POST_IS_NOT], true);
        ?>
        <div class="amr-panel" data-amr-item-id="<?php echo esc_attr((string) $item_id); ?>">
            <div class="amr-panel__header">
                <div>
                    <span class="amr-panel__title"><?php esc_html_e('Titanium Nav Menu Roles & Visibility Rules', 'titanium-advanced-menu-rules'); ?></span>
                    <span class="amr-panel__subtitle"><?php esc_html_e('Server-side visibility for this menu item.', 'titanium-advanced-menu-rules'); ?></span>
                </div>
                <span class="amr-panel__badge"><?php esc_html_e('Free', 'titanium-advanced-menu-rules'); ?></span>
            </div>

            <div class="amr-section">
                <span class="amr-label"><?php esc_html_e('Display Mode', 'titanium-advanced-menu-rules'); ?></span>
                <div class="amr-radio-row amr-display-mode">
                    <?php foreach ($actions as $value => $label) : ?>
                        <label class="amr-radio-pill">
                            <input
                                type="radio"
                                class="amr-action"
                                name="tiamr_action[<?php echo esc_attr((string) $item_id); ?>]"
                                value="<?php echo esc_attr($value); ?>"
                                <?php checked($rule['action'], $value); ?>
                            />
                            <span><?php echo esc_html($label); ?></span>
                        </label>
                    <?php endforeach; ?>
                </div>
            </div>

            <div class="amr-section">
                <span class="amr-label"><?php esc_html_e('Audience', 'titanium-advanced-menu-rules'); ?></span>
                <div class="amr-radio-grid amr-audience-rules">
                    <?php foreach ($audience_conditions as $value => $label) : ?>
                        <label class="amr-radio-option">
                            <input
                                type="radio"
                                class="amr-audience"
                                name="tiamr_audience[<?php echo esc_attr((string) $item_id); ?>]"
                                value="<?php echo esc_attr($value); ?>"
                                <?php checked($display_audience, $value); ?>
                            />
                            <span><?php echo esc_html($label); ?></span>
                        </label>
                    <?php endforeach; ?>
                </div>
            </div>

            <div class="amr-roles-wrap<?php echo $is_role_condition ? '' : ' amr-hidden'; ?>">
                <div class="amr-roles-head">
                    <span class="amr-label"><?php esc_html_e('Target roles', 'titanium-advanced-menu-rules'); ?></span>
                    <span class="amr-roles-count"></span>
                </div>

                <div class="amr-role-toolbar">
                    <input type="search" class="widefat amr-role-search" placeholder="<?php esc_attr_e('Search roles...', 'titanium-advanced-menu-rules'); ?>" autocomplete="off" />
                    <div class="amr-role-actions">
                        <button type="button" class="button button-small amr-select-all-roles"><?php esc_html_e('Select all roles', 'titanium-advanced-menu-rules'); ?></button>
                        <button type="button" class="button button-small amr-clear-roles"><?php esc_html_e('Clear roles', 'titanium-advanced-menu-rules'); ?></button>
                    </div>
                </div>

                <div class="amr-role-list" data-empty-text="<?php esc_attr_e('No roles match your search.', 'titanium-advanced-menu-rules'); ?>">
                    <?php foreach ($roles as $role_slug => $role_data) :
                        $role_name = translate_user_role($role_data['name']);
                        $checked   = in_array($role_slug, $rule['roles'], true);
                        ?>
                        <label class="amr-role-option" data-role-label="<?php echo esc_attr(strtolower($role_name . ' ' . $role_slug)); ?>">
                            <input
                                type="checkbox"
                                class="amr-role-checkbox"
                                name="tiamr_roles[<?php echo esc_attr((string) $item_id); ?>][]"
                                value="<?php echo esc_attr($role_slug); ?>"
                                data-role-name="<?php echo esc_attr($role_name); ?>"
                                <?php checked($checked); ?>
                            />
                            <span><?php echo esc_html($role_name); ?></span>
                        </label>
                    <?php endforeach; ?>
                </div>
            </div>

            <div class="amr-section">
                <span class="amr-label"><?php esc_html_e('Location', 'titanium-advanced-menu-rules'); ?></span>
                <div class="amr-radio-grid amr-location-rules">
                    <?php foreach ($location_conditions as $value => $label) : ?>
                        <label class="amr-radio-option">
                            <input
                                type="radio"
                                class="amr-location"
                                name="tiamr_location[<?php echo esc_attr((string) $item_id); ?>]"
                                value="<?php echo esc_attr($value); ?>"
                                <?php checked($display_location, $value); ?>
                            />
                            <span><?php echo esc_html($label); ?></span>
                        </label>
                    <?php endforeach; ?>
                </div>
            </div>

            <?php $this->render_content_picker($item_id, 'page', $rule['pages'], $is_page_condition); ?>
            <?php $this->render_content_picker($item_id, 'post', $rule['posts'], $is_post_condition); ?>

            <div class="amr-summary" aria-live="polite"></div>

            <?php
            /**
             * Allows the future Pro add-on to append its button or summary under
             * the Free fields without replacing this Free foundation.
             */
            do_action('tiamr/admin/menu_item_fields_after', $item_id, $item, $depth, $args, $id);
            ?>
        </div>
        <?php
    }

    public function save_fields($menu_id, $menu_item_db_id, $args): void {
        $menu_item_db_id = (int) $menu_item_db_id;

        if (!$this->can_save()) {
            return;
        }

        $action   = $this->get_posted_scalar('tiamr_action', $menu_item_db_id, Meta::ACTION_SHOW);
        $audience = $this->get_posted_scalar('tiamr_audience', $menu_item_db_id, Meta::AUDIENCE_EVERYONE);
        $location = $this->get_posted_scalar('tiamr_location', $menu_item_db_id, Meta::LOCATION_EVERYWHERE);
        $roles    = $this->get_posted_array('tiamr_roles', $menu_item_db_id);
        $pages    = $this->get_posted_array('tiamr_pages', $menu_item_db_id);
        $posts    = $this->get_posted_array('tiamr_posts', $menu_item_db_id);

        Meta::update_rule($menu_item_db_id, [
            'action'   => Sanitizer::sanitize_action($action),
            'audience' => Sanitizer::sanitize_audience_condition($audience),
            'location' => Sanitizer::sanitize_location_condition($location),
            'roles'    => Sanitizer::sanitize_roles($roles),
            'pages'    => Sanitizer::sanitize_post_ids($pages, 'page'),
            'posts'    => Sanitizer::sanitize_post_ids($posts, 'post'),
        ]);
    }

    public function ajax_search_content(): void {
        if (!current_user_can('edit_theme_options')) {
            wp_send_json_error(['message' => __('Permission denied.', 'titanium-advanced-menu-rules')], 403);
        }

        check_ajax_referer('tiamr_search_content', 'nonce');

        $post_type = isset($_POST['post_type']) ? sanitize_key(wp_unslash($_POST['post_type'])) : '';
        $search    = isset($_POST['search']) ? sanitize_text_field(wp_unslash($_POST['search'])) : '';

        if (!in_array($post_type, ['page', 'post'], true)) {
            wp_send_json_error(['message' => __('Invalid content type.', 'titanium-advanced-menu-rules')], 400);
        }

        if (strlen($search) < 2) {
            wp_send_json_success(['items' => []]);
        }

        $query = new \WP_Query([
            'post_type'              => $post_type,
            'post_status'            => ['publish', 'private', 'draft', 'pending', 'future'],
            's'                      => $search,
            'posts_per_page'         => 20,
            'orderby'                => 'title',
            'order'                  => 'ASC',
            'no_found_rows'          => true,
            'update_post_meta_cache' => false,
            'update_post_term_cache' => false,
        ]);

        $items = [];

        foreach ($query->posts as $post) {
            if (!$post instanceof \WP_Post) {
                continue;
            }

            $title = get_the_title($post);

            if ('' === $title) {
                /* translators: %d: post ID. */
                $title = sprintf(__('Untitled #%d', 'titanium-advanced-menu-rules'), (int) $post->ID);
            }

            $items[] = [
                'id'     => (int) $post->ID,
                'title'  => html_entity_decode(wp_strip_all_tags($title), ENT_QUOTES, get_bloginfo('charset')),
                'status' => (string) $post->post_status,
                'type'   => $post_type,
                'label'  => 'page' === $post_type ? __('Page', 'titanium-advanced-menu-rules') : __('Post', 'titanium-advanced-menu-rules'),
            ];
        }

        wp_send_json_success(['items' => $items]);
    }

    /**
     * @param array<int> $selected_ids
     */
    private function render_content_picker(int $item_id, string $post_type, array $selected_ids, bool $is_visible): void {
        $is_page  = 'page' === $post_type;
        $wrap_cls = $is_page ? 'amr-pages-wrap' : 'amr-posts-wrap';
        $meta_key = $is_page ? 'tiamr_pages' : 'tiamr_posts';
        $title    = $is_page ? __('Target pages', 'titanium-advanced-menu-rules') : __('Target posts', 'titanium-advanced-menu-rules');
        $search   = $is_page ? __('Search pages...', 'titanium-advanced-menu-rules') : __('Search posts...', 'titanium-advanced-menu-rules');
        $empty    = $is_page ? __('No pages selected yet.', 'titanium-advanced-menu-rules') : __('No posts selected yet.', 'titanium-advanced-menu-rules');
        ?>
        <div class="amr-content-wrap <?php echo esc_attr($wrap_cls); ?><?php echo $is_visible ? '' : ' amr-hidden'; ?>" data-amr-content-type="<?php echo esc_attr($post_type); ?>" data-amr-input-name="<?php echo esc_attr($meta_key . '[' . $item_id . '][]'); ?>">
            <div class="amr-content-head">
                <span class="amr-label"><?php echo esc_html($title); ?></span>
                <span class="amr-content-count"></span>
            </div>

            <div class="amr-content-search-row">
                <input type="search" class="widefat amr-content-search" placeholder="<?php echo esc_attr($search); ?>" autocomplete="off" />
            </div>

            <div class="amr-content-results" aria-live="polite"></div>

            <div class="amr-content-selected" data-empty-text="<?php echo esc_attr($empty); ?>">
                <?php foreach ($selected_ids as $selected_id) :
                    $selected_post = get_post((int) $selected_id);

                    if (!$selected_post instanceof \WP_Post || $post_type !== $selected_post->post_type || 'trash' === $selected_post->post_status) {
                        continue;
                    }

                    $selected_title = get_the_title($selected_post);

                    if ('' === $selected_title) {
                        /* translators: %d: post ID. */
                        $selected_title = sprintf(__('Untitled #%d', 'titanium-advanced-menu-rules'), (int) $selected_post->ID);
                    }
                    ?>
                    <div class="amr-content-selected-item" data-content-id="<?php echo esc_attr((string) $selected_post->ID); ?>">
                        <input type="hidden" name="<?php echo esc_attr($meta_key . '[' . $item_id . '][]'); ?>" value="<?php echo esc_attr((string) $selected_post->ID); ?>" />
                        <span class="amr-content-selected-title"><?php echo esc_html($selected_title); ?></span>
                        <span class="amr-content-selected-meta">#<?php echo esc_html((string) $selected_post->ID); ?></span>
                        <button type="button" class="button-link amr-content-remove" aria-label="<?php esc_attr_e('Remove selected item', 'titanium-advanced-menu-rules'); ?>">×</button>
                    </div>
                <?php endforeach; ?>
            </div>
        </div>
        <?php
    }

    private function can_save(): bool {
        if (!current_user_can('edit_theme_options')) {
            return false;
        }

        if (!isset($_POST['update-nav-menu-nonce'])) {
            return false;
        }

        $nonce = sanitize_text_field(wp_unslash($_POST['update-nav-menu-nonce']));

        return (bool) wp_verify_nonce($nonce, 'update-nav_menu');
    }

    private function get_posted_scalar(string $key, int $item_id, string $default): string {
        if (!isset($_POST[$key]) || !is_array($_POST[$key])) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
            return $default;
        }

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

        if (!isset($posted[$item_id])) {
            return $default;
        }

        return sanitize_text_field((string) $posted[$item_id]);
    }

    private function get_posted_array(string $key, int $item_id): array {
        if (!isset($_POST[$key]) || !is_array($_POST[$key])) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
            return [];
        }

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

        if (!isset($posted[$item_id]) || !is_array($posted[$item_id])) {
            return [];
        }

        return array_map('sanitize_text_field', (array) $posted[$item_id]);
    }
}
