<?php

namespace FleekDash\Modules\FleekTasks;

use FleekDash\Core\BaseModule;

/**
 * FleekTasks Module
 *
 * Manages Urgency and Importance taxonomies for post classification
 * using the Eisenhower prioritization methodology
 */
class FleekTasks extends BaseModule
{
    /**
     * Module name
     */
    protected string $name = 'fleek-tasks';

    /**
     * Module version
     */
    protected string $version = '1.0.0';

    /**
     * Default Urgency terms (fixed set)
     */
    private array $urgencyTerms = ['Urgent', 'High', 'Medium', 'Normal', 'Low'];

    /**
     * Default Importancy terms (fixed set)
     */
    private array $importancyTerms = ['Essential', 'Important', 'Moderate', 'Optional', 'Minor'];

    /**
     * Initialize the module
     */
    public function init()
    {
        $this->log_info('Initializing FleekTasks module');
    }

    /**
     * Register module hooks
     */
    protected function register_hooks()
    {
        // Register taxonomies ALWAYS in init
        $this->add_action('init', [$this, 'register_taxonomies'], 5);

        // Protections against term deletion/creation
        $this->add_filter('pre_delete_term', [$this, 'prevent_term_deletion'], 10, 2);
        $this->add_filter('pre_insert_term', [$this, 'prevent_term_creation'], 10, 2);

        // Restore terms automatically
        $this->add_action('admin_init', [$this, 'restore_missing_terms']);

        // Remove default metaboxes
        $this->add_action('add_meta_boxes', [$this, 'remove_default_taxonomy_metaboxes'], 20);
        // Add custom metabox
        $this->add_action('add_meta_boxes', [$this, 'add_fleek_tasks_metabox'], 30);
        // Save custom selection
        $this->add_action('save_post', [$this, 'save_fleek_tasks_metabox'], 10, 1);

        // Remove taxonomy columns from posts table
        $this->add_filter('manage_post_posts_columns', [$this, 'remove_fleek_tasks_columns'], 100);

        // Plugin activation hook to create initial terms
        register_activation_hook(FLEEKDASH_PLUGIN_FILE, function () {
            // Fallback: ensure taxonomies are registered
            if (!\call_user_func('taxonomy_exists', 'urgency') || !\call_user_func('taxonomy_exists', 'importancy')) {
                \add_action('init', function () {
                    $this->register_taxonomies();
                    $this->create_initial_terms();
                }, 0);
            } else {
                $this->create_initial_terms();
            }
        });
    }

    /**
     * Register Urgency and Importance taxonomies
     */
    public function register_taxonomies()
    {
        // Urgency
        $urgency_labels = array(
            'name' => \call_user_func('_x', 'Urgencies', 'taxonomy general name', 'fleekdash'),
            'singular_name' => \call_user_func('_x', 'Urgency', 'taxonomy singular name', 'fleekdash'),
            'search_items' => \call_user_func('__', 'Search Urgencies', 'fleekdash'),
            'all_items' => \call_user_func('__', 'All Urgencies', 'fleekdash'),
            'parent_item' => \call_user_func('__', 'Parent Urgency', 'fleekdash'),
            'parent_item_colon' => \call_user_func('__', 'Parent Urgency:', 'fleekdash'),
            'edit_item' => \call_user_func('__', 'Edit Urgency', 'fleekdash'),
            'update_item' => \call_user_func('__', 'Update Urgency', 'fleekdash'),
            'add_new_item' => \call_user_func('__', 'Add New Urgency', 'fleekdash'),
            'new_item_name' => \call_user_func('__', 'New Urgency Name', 'fleekdash'),
            'menu_name' => \call_user_func('__', 'Urgency', 'fleekdash'),
        );
        $urgency_args = array(
            'hierarchical' => false,
            'labels' => $urgency_labels,
            'show_ui' => false, // Hide from admin menu
            'show_admin_column' => false, // Hide taxonomy column on posts list
            'query_var' => true,
            'rewrite' => array('slug' => 'urgency'),
            'show_in_rest' => true,
        );
        \call_user_func('register_taxonomy', 'urgency', \call_user_func('get_post_types', ['public' => true], 'names'), $urgency_args);

        // Importancy
        $importancy_labels = array(
            'name' => \call_user_func('_x', 'Importancies', 'taxonomy general name', 'fleekdash'),
            'singular_name' => \call_user_func('_x', 'Importancy', 'taxonomy singular name', 'fleekdash'),
            'search_items' => \call_user_func('__', 'Search Importancies', 'fleekdash'),
            'all_items' => \call_user_func('__', 'All Importancies', 'fleekdash'),
            'parent_item' => \call_user_func('__', 'Parent Importancy', 'fleekdash'),
            'parent_item_colon' => \call_user_func('__', 'Parent Importancy:', 'fleekdash'),
            'edit_item' => \call_user_func('__', 'Edit Importancy', 'fleekdash'),
            'update_item' => \call_user_func('__', 'Update Importancy', 'fleekdash'),
            'add_new_item' => \call_user_func('__', 'Add New Importancy', 'fleekdash'),
            'new_item_name' => \call_user_func('__', 'New Importancy Name', 'fleekdash'),
            'menu_name' => \call_user_func('__', 'Importancy', 'fleekdash'),
        );
        $importancy_args = array(
            'hierarchical' => false,
            'labels' => $importancy_labels,
            'show_ui' => false, // Hide from admin menu
            'show_admin_column' => false, // Hide taxonomy column on posts list
            'query_var' => true,
            'rewrite' => array('slug' => 'importancy'),
            'show_in_rest' => true,
        );
        \call_user_func('register_taxonomy', 'importancy', \call_user_func('get_post_types', ['public' => true], 'names'), $importancy_args);

        $this->log_info('Taxonomies registered successfully');
    }

    /**
     * Prevent deletion of default terms
     */
    public function prevent_term_deletion(mixed $term, string $taxonomy)
    {
        if ($taxonomy === 'urgency' && in_array(\call_user_func('get_term', $term)->name, $this->urgencyTerms, true)) {
            \add_filter('redirect_term_location', function ($location) {
                \add_filter('admin_notices', function () {
                    echo '<div class="notice notice-error is-dismissible"><p>' . __('You cannot delete default Urgency terms.', 'fleekdash') . '</p></div>';
                });
                return $location;
            });
            return false; // Block delete
        }
        if ($taxonomy === 'importancy' && in_array(\call_user_func('get_term', $term)->name, $this->importancyTerms, true)) {
            \add_filter('redirect_term_location', function ($location) {
                \add_filter('admin_notices', function () {
                    echo '<div class="notice notice-error is-dismissible"><p>' . __('You cannot delete default Importancy terms.', 'fleekdash') . '</p></div>';
                });
                return $location;
            });
            return false;
        }
        return $term;
    }

    /**
     * Prevent creation of new terms
     */
    public function prevent_term_creation(mixed $term, string $taxonomy)
    {
        if ($taxonomy === 'urgency' && !in_array($term, $this->urgencyTerms, true)) {
            \add_filter('admin_notices', function () {
                echo '<div class="notice notice-error is-dismissible"><p>' . __('You cannot add new Urgency terms. Only the default terms are allowed.', 'fleekdash') . '</p></div>';
            });
            return new \WP_Error('term_add_blocked', __('You cannot add new Urgency terms. Only the default terms are allowed.', 'fleekdash'));
        }
        if ($taxonomy === 'importancy' && !in_array($term, $this->importancyTerms, true)) {
            \add_filter('admin_notices', function () {
                echo '<div class="notice notice-error is-dismissible"><p>' . __('You cannot add new Importancy terms. Only the default terms are allowed.', 'fleekdash') . '</p></div>';
            });
            return new \WP_Error('term_add_blocked', __('You cannot add new Importancy terms. Only the default terms are allowed.', 'fleekdash'));
        }
        return $term;
    }

    /**
     * Restore default terms that may have been removed
     */
    public function restore_missing_terms()
    {
        // Ensure default urgency terms exist
        foreach ($this->urgencyTerms as $term) {
            if (!\call_user_func('term_exists', $term, 'urgency')) {
                \call_user_func('wp_insert_term', $term, 'urgency');
                $this->log_info("Restored missing urgency term: {$term}");
            }
        }

        // Ensure default importancy terms exist
        foreach ($this->importancyTerms as $term) {
            if (!\call_user_func('term_exists', $term, 'importancy')) {
                \call_user_func('wp_insert_term', $term, 'importancy');
                $this->log_info("Restored missing importancy term: {$term}");
            }
        }
    }

    /**
     * Create initial terms on plugin activation
     */
    public function create_initial_terms()
    {
        // Do not register taxonomies here — only seed terms
        // Urgency terms
        foreach ($this->urgencyTerms as $term) {
            if (!\call_user_func('term_exists', $term, 'urgency')) {
                \call_user_func('wp_insert_term', $term, 'urgency');
            }
        }
        // Importancy terms
        foreach ($this->importancyTerms as $term) {
            if (!\call_user_func('term_exists', $term, 'importancy')) {
                \call_user_func('wp_insert_term', $term, 'importancy');
            }
        }
        $this->log_info('Initial terms created successfully');
    }

    /**
     * Remove default taxonomy metaboxes
     */
    public function remove_default_taxonomy_metaboxes()
    {
        \call_user_func('remove_meta_box', 'tagsdiv-urgency', 'post', 'side');
        \call_user_func('remove_meta_box', 'tagsdiv-importancy', 'post', 'side');
    }

    /**
     * Add custom metabox for FleekTasks matrix
     */
    public function add_fleek_tasks_metabox()
    {
        \call_user_func('add_meta_box',
            'fleek_tasks_matrix',
            __('Task Settings', 'fleekdash'),
            [$this, 'render_fleek_tasks_metabox'],
            'post',
            'side',
            'default',
        );
    }

    public function render_fleek_tasks_metabox(\WP_Post $post): void
    {
        $urgency_terms = \get_terms(['taxonomy' => 'urgency', 'hide_empty' => false]);
        $urgency_terms = is_array($urgency_terms) ? $urgency_terms : [];

        $importancy_terms = \get_terms(['taxonomy' => 'importancy', 'hide_empty' => false]);
        $importancy_terms = is_array($importancy_terms) ? $importancy_terms : [];

        $current_urgency = \wp_get_post_terms($post->ID, 'urgency', ['fields' => 'names']);
        $current_importancy = \wp_get_post_terms($post->ID, 'importancy', ['fields' => 'names']);

        $current_urgency = is_array($current_urgency) ? $current_urgency : [];
        $current_importancy = is_array($current_importancy) ? $current_importancy : [];

        // Order terms to match canonical default arrays.
        $ordered_urgency_terms = $this->buildOrderedTermList($urgency_terms, $this->urgencyTerms);
        $ordered_importancy_terms = $this->buildOrderedTermList($importancy_terms, $this->importancyTerms);

        // Saved due date meta
        $due_date = \get_post_meta($post->ID, '_fleekdash_due_date', true);
        ?>
        <style>
            .fleek-tasks-tabs {
                display: flex;
                border-bottom: 1px solid #eee;
                margin-bottom: 10px;
            }

            .fleek-tasks-tab {
                padding: 6px 16px;
                cursor: pointer;
                border: 1px solid #eee;
                border-bottom: none;
                background: #f9f9f9;
                margin-right: 2px;
                border-radius: 4px 4px 0 0;
            }

            .fleek-tasks-tab.active {
                background: #fff;
                font-weight: bold;
            }

            .fleek-tasks-tab-content {
                display: none;
            }

            .fleek-tasks-tab-content.active {
                display: block;
            }

            .fleek-tasks-radio-list {
                margin: 0;
                padding: 0;
                list-style: none;
            }

            .fleek-tasks-radio-list li {
                margin-bottom: 6px;
            }

            .fleek-tasks-due-date-label {
                font-weight: bold;
                display: block;
                margin: 12px 0 4px 0;
            }

            .fleek-tasks-due-date-input {
                margin-bottom: 0;
                width: 100%;
            }
        </style>
        <div id="fleek-tasks-matrix-tabs">
            <div class="fleek-tasks-tabs">
                <div class="fleek-tasks-tab active" data-tab="urgency">Urgency</div>
                <div class="fleek-tasks-tab" data-tab="importancy">Importancy</div>
            </div>
            <div class="fleek-tasks-tab-content active" data-content="urgency">
                <ul class="fleek-tasks-radio-list">
                    <?php foreach ($ordered_urgency_terms as $term): ?>
                        <li>
                            <label>
                                <input type="radio" name="fleek_tasks_urgency[]" value="<?php echo \esc_attr($term->term_id); ?>" <?php echo in_array($term->name, $current_urgency, true) ? 'checked' : ''; ?> />
                                <?php echo \esc_html($term->name); ?>
                            </label>
                        </li>
                    <?php endforeach; ?>
                </ul>
            </div>
            <div class="fleek-tasks-tab-content" data-content="importancy">
                <ul class="fleek-tasks-radio-list">
                    <?php foreach ($ordered_importancy_terms as $term): ?>
                        <li>
                            <label>
                                <input type="radio" name="fleek_tasks_importancy[]" value="<?php echo \esc_attr($term->term_id); ?>" <?php echo in_array($term->name, $current_importancy, true) ? 'checked' : ''; ?> />
                                <?php echo \esc_html($term->name); ?>
                            </label>
                        </li>
                    <?php endforeach; ?>
                </ul>
            </div>
            <label class="fleek-tasks-due-date-label" for="fleekdash-due-date">Due Date</label>
            <input class="fleek-tasks-due-date-input" type="date" id="fleekdash-due-date" name="fleekdash_due_date" value="<?php echo \esc_attr($due_date); ?>" />
        </div>
        <script>
            ( function () {
                // Corrected selectors for valid IDs and classes
                const tabs = document.querySelectorAll( '#fleek-tasks-matrix-tabs .fleek-tasks-tab' );
                const contents = document.querySelectorAll( '#fleek-tasks-matrix-tabs .fleek-tasks-tab-content' );
                tabs.forEach( tab => {
                    tab.addEventListener( 'click', function () {
                        tabs.forEach( t => t.classList.remove( 'active' ) );
                        contents.forEach( c => c.classList.remove( 'active' ) );
                        tab.classList.add( 'active' );
                        // Select the correct content by data-content attribute
                        const content = document.querySelector( '#fleek-tasks-matrix-tabs .fleek-tasks-tab-content[data-content="' + tab.dataset.tab + '"]' );
                        if ( content ) {
                            content.classList.add( 'active' );
                        }
                    } );
                } );
            } )();
        </script>
        <?php
    }

    /**
     * @param array<int, mixed> $terms
     * @param array<int, string> $canonicalNames
     * @return array<int, object>
     */
    private function buildOrderedTermList(array $terms, array $canonicalNames): array
    {
        $termsByName = [];
        foreach ($terms as $term) {
            if (\is_object($term) && isset($term->name)) {
                $termsByName[(string) $term->name] = $term;
            }
        }

        $orderedTerms = [];
        foreach ($canonicalNames as $name) {
            if (isset($termsByName[$name])) {
                $orderedTerms[] = $termsByName[$name];
            }
        }

        return $orderedTerms;
    }

    /**
     * Save the custom metabox selection
     */
    public function save_fleek_tasks_metabox(int $post_id): void
    {
        if (defined('DOING_AUTOSAVE') && constant('DOING_AUTOSAVE')) {
            return;
        }

        if (!\current_user_can('edit_post', $post_id)) {
            return;
        }

        $urgency_terms = isset($_POST['fleek_tasks_urgency']) ? array_map('intval', $_POST['fleek_tasks_urgency']) : [];
        $importancy_terms = isset($_POST['fleek_tasks_importancy']) ? array_map('intval', $_POST['fleek_tasks_importancy']) : [];

        \call_user_func('wp_set_post_terms', $post_id, $urgency_terms, 'urgency');
        \call_user_func('wp_set_post_terms', $post_id, $importancy_terms, 'importancy');

        // Save due date
        if (isset($_POST['fleekdash_due_date'])) {
            $due_date = \sanitize_text_field($_POST['fleekdash_due_date']);
            if ($due_date) {
                \call_user_func('update_post_meta', $post_id, '_fleekdash_due_date', $due_date);
            } else {
                \call_user_func('delete_post_meta', $post_id, '_fleekdash_due_date');
            }
        }
    }

    /**
     * Get FleekTasks matrix for a post
     */
    public function get_post_matrix(int $post_id): array
    {
        $urgency = wp_get_post_terms($post_id, 'urgency', ['fields' => 'names']);
        $importancy = wp_get_post_terms($post_id, 'importancy', ['fields' => 'names']);

        return [
            'urgency' => !empty($urgency) ? $urgency[0] : null,
            'importancy' => !empty($importancy) ? $importancy[0] : null,
            'quadrant' => $this->calculateQuadrant($urgency[0] ?? null, $importancy[0] ?? null)
        ];
    }

    /**
     * Calculate FleekTasks matrix quadrant
     */
    private function calculateQuadrant(?string $urgency, ?string $importancy): ?int
    {
        $quadrant = null;
        if (!$urgency || !$importancy) {
            $quadrant = null;
        } else {
            $urgency_high = in_array($urgency, ['Urgent', 'High'], true);
            $importancy_high = in_array($importancy, ['Essential', 'Important'], true);

            if ($urgency_high && $importancy_high) {
                $quadrant = 1; // Do First (Urgent + Important)
            } elseif (!$urgency_high && $importancy_high) {
                $quadrant = 2; // Schedule (Not Urgent + Important)
            } elseif ($urgency_high && !$importancy_high) {
                $quadrant = 3; // Delegate (Urgent + Not Important)
            } else {
                $quadrant = 4; // Delete (Not Urgent + Not Important)
            }
        }

        return $quadrant;
    }

    /**
     * Get posts by quadrant
     */
    public function get_posts_by_quadrant(int $quadrant): array
    {
        switch ($quadrant) {
            case 1: // Do First
                $urgency_terms = ['Urgent', 'High'];
                $importancy_terms = ['Essential', 'Important'];
                break;
            case 2: // Schedule
                $urgency_terms = ['Medium', 'Normal', 'Low'];
                $importancy_terms = ['Essential', 'Important'];
                break;
            case 3: // Delegate
                $urgency_terms = ['Urgent', 'High'];
                $importancy_terms = ['Moderate', 'Optional', 'Minor'];
                break;
            case 4: // Delete
                $urgency_terms = ['Medium', 'Normal', 'Low'];
                $importancy_terms = ['Moderate', 'Optional', 'Minor'];
                break;
            default:
                return [];
        }

        $args = [
            'post_type' => 'any',
            'post_status' => 'any',
            'posts_per_page' => -1,
            'tax_query' => [
                'relation' => 'AND',
                [
                    'taxonomy' => 'urgency',
                    'field' => 'name',
                    'terms' => $urgency_terms,
                    'operator' => 'IN'
                ],
                [
                    'taxonomy' => 'importancy',
                    'field' => 'name',
                    'terms' => $importancy_terms,
                    'operator' => 'IN'
                ]
            ]
        ];

        // Performance: when only listing, return IDs to reduce memory/queries
        $args['fields'] = 'ids';
        $args['no_found_rows'] = true;
        $args['update_post_meta_cache'] = false;
        $args['update_post_term_cache'] = false;
        $args['ignore_sticky_posts'] = true;
        return \get_posts($args);
    }

    /**
     * Remove urgency/importancy columns from posts table
     */
    public function remove_fleek_tasks_columns(array $columns): array
    {
        unset($columns['taxonomy-urgency']);
        unset($columns['taxonomy-importancy']);
        return $columns;
    }
}
