<?php

namespace Blazemedia\Blackhole\Settings;
use Blazemedia\Blackhole\Settings\Capability;

class SettingPage {

    private $blackhole_settings_options;

    public function __construct() {
        add_action( 'admin_menu', [ $this, 'blackhole_settings_add_plugin_page' ]);
        add_action( 'admin_init', [ $this, 'blackhole_settings_page_init' ] );
        add_action( 'wp_ajax_get_terms_by_taxonomy', [ $this, 'get_terms_by_taxonomy' ] ); // AJAX for terms
        add_filter( 'option_page_capability_blackhole_settings_option_group', [ $this, 'get_option_page_capability' ] );
    }

    public function blackhole_settings_add_plugin_page() {
        if ( !Capability::canAccessPlugin() ) {
            return;
        }

        add_menu_page(
            'Blackhole Settings', // page_title
            'Blackhole Settings', // menu_title
            'read', // capability
            'blackhole-settings', // menu_slug
            [ $this, 'blackhole_settings_create_admin_page' ], // callback
            'dashicons-media-archive', // icon_url
            65 // position
        );

        add_submenu_page(
            'blackhole-settings',
            'Post Blackhole',
            'Post Blackhole',
            'read',
            'edit.php?post_type=blackhole'
        );
    }

    public function blackhole_settings_create_admin_page() {

        if( !Capability::canAccessPlugin() ) {
            wp_die('Non hai i permessi per visualizzare questa pagina');
        } 

        $this->blackhole_settings_options = get_option( 'blackhole_settings_option', array() );
        $summary_text = $this->build_settings_summary_text();
        ?>

        <div class="wrap">
            <h2>Impostazioni Blackhole</h2>
            <div class="notice notice-info inline">
                <p>
                    <?php
                    echo esc_html( $summary_text );
                    ?>
                </p>
            </div>
            <form method="post" action="options.php">
                <?php
                    settings_fields( 'blackhole_settings_option_group' );
                    do_settings_sections( 'blackhole-settings-admin' );
                    submit_button();
                ?>
            </form>
        </div>
        <script>
            jQuery(document).ready(function($) {
                function loadTerms(selectTaxonomy, selectTerm) {
                    var taxonomy = selectTaxonomy.val();
                    selectTerm.empty().append('<option value="">Seleziona un termine</option>');
                    if (!taxonomy) return;

                    $.post(ajaxurl, {
                        action: 'get_terms_by_taxonomy',
                        taxonomy: taxonomy
                    }, function(response) {
                        if (response.success) {
                            $.each(response.data, function(index, term) {
                                selectTerm.append('<option value="' + term.slug + '">' + term.name + '</option>');
                            });
                        }
                    });
                }

                function refreshIndexes(container) {
                    container.find('.taxonomy-term-wrapper').each(function(index) {
                        $(this).find('select').each(function() {
                            var name = $(this).attr('name');
                            if (!name) return;
                            name = name.replace(/\[\d+\]/, '[' + index + ']');
                            $(this).attr('name', name);
                        });
                    });
                }

                $(document).on('click', '.add-taxonomy-term', function(e) {
                    e.preventDefault();

                    var target = $(this).data('target');
                    var container = $('#' + target);
                    var firstRow = container.find('.taxonomy-term-wrapper:first');

                    if (!firstRow.length) return;

                    var clone = firstRow.clone();
                    clone.find('.taxonomy-select').val('');
                    clone.find('.term-select').html('<option value="">Seleziona un termine</option>');

                    container.append(clone);
                    refreshIndexes(container);
                });

                $(document).on('change', '.taxonomy-select', function() {
                    var selectTaxonomy = $(this);
                    var selectTerm = selectTaxonomy.closest('.taxonomy-term-wrapper').find('.term-select');
                    loadTerms(selectTaxonomy, selectTerm);
                });
            });
        </script>
    <?php }

    public function blackhole_settings_page_init() {
        register_setting(
            'blackhole_settings_option_group', // option_group
            'blackhole_settings_option', // option_name
            array(  $this, 'blackhole_settings_sanitize' ) // sanitize_callback
        );

        add_settings_section(
            'blackhole_settings_setting_section', // id
            'Impostazioni', // title
            array( $this, 'blackhole_settings_section_info' ), // callback
            'blackhole-settings-admin' // page
        );

        // Analytics Property field (Text input)
        add_settings_field(
            'analytics_property', // id
            'Id Property Analitics', // title
            array( $this, 'analytics_property_callback' ), // callback
            'blackhole-settings-admin', // page
            'blackhole_settings_setting_section' // section
        );

        add_settings_field(
            'analytics_enabled', // id
            'Verifica traffico Analytics', // title
            array( $this, 'analytics_enabled_callback' ), // callback
            'blackhole-settings-admin', // page
            'blackhole_settings_setting_section' // section
        );

        add_settings_field(
            'traffic_lookback_days', // id
            'Finestra traffico (giorni)', // title
            array( $this, 'traffic_lookback_days_callback' ), // callback
            'blackhole-settings-admin', // page
            'blackhole_settings_setting_section' // section
        );

        add_settings_field(
            'users_threshold', // id
            'Soglia utenti minima', // title
            array( $this, 'users_threshold_callback' ), // callback
            'blackhole-settings-admin', // page
            'blackhole_settings_setting_section' // section
        );

        if ( Capability::isAccessManager() ) {
            add_settings_field(
                'enabled_user_ids', // id
                'Utenti abilitati al plugin', // title
                array( $this, 'enabled_user_ids_callback' ), // callback
                'blackhole-settings-admin', // page
                'blackhole_settings_setting_section' // section
            );
        }

        // Post Types field (Multiple select)
        add_settings_field(
            'post_types', // id
            'Tipi di Post (opzionale)', // title
            array( $this, 'post_types_callback' ), // callback
            'blackhole-settings-admin', // page
            'blackhole_settings_setting_section' // section
        );

        // Taxonomy/Term fields (dynamic)
        add_settings_field(
            'included_taxonomy_terms', // id
            'Tassonomie/Termini da includere (opzionale)', // title
            array( $this, 'included_taxonomy_terms_callback' ), // callback
            'blackhole-settings-admin', // page
            'blackhole_settings_setting_section' // section
        );

        add_settings_field(
            'excluded_taxonomy_terms', // id
            'Tassonomie/Termini da escludere (opzionale)', // title
            array( $this, 'excluded_taxonomy_terms_callback' ), // callback
            'blackhole-settings-admin', // page
            'blackhole_settings_setting_section' // section
        );

        add_settings_field(
            'cutoff_mode', // id
            'Limite temporale offerte', // title
            array( $this, 'cutoff_mode_callback' ), // callback
            'blackhole-settings-admin', // page
            'blackhole_settings_setting_section' // section
        );

        add_settings_field(
            'cutoff_days', // id
            'Anzianita in giorni', // title
            array( $this, 'cutoff_days_callback' ), // callback
            'blackhole-settings-admin', // page
            'blackhole_settings_setting_section' // section
        );

        add_settings_field(
            'cutoff_date', // id
            'Data limite fissa', // title
            array( $this, 'cutoff_date_callback' ), // callback
            'blackhole-settings-admin', // page
            'blackhole_settings_setting_section' // section
        );

      
    }

    public function blackhole_settings_sanitize($input) {
        $sanitary_values = array();

        if ( isset( $input['post_types'] ) ) {
            $post_types = array_map( 'sanitize_text_field', (array) $input['post_types'] );
            $sanitary_values['post_types'] = array_values( array_filter( $post_types ) );
        }

        $included_input = $input['included_taxonomy_terms'] ?? ( $input['taxonomy_terms'] ?? array() );
        $sanitary_values['included_taxonomy_terms'] = $this->sanitize_taxonomy_terms( $included_input );
        $sanitary_values['excluded_taxonomy_terms'] = $this->sanitize_taxonomy_terms( $input['excluded_taxonomy_terms'] ?? array() );

        $cutoff_mode = isset( $input['cutoff_mode'] ) ? sanitize_text_field( $input['cutoff_mode'] ) : 'days';
        $sanitary_values['cutoff_mode'] = in_array( $cutoff_mode, array( 'days', 'fixed_date' ), true ) ? $cutoff_mode : 'days';

        $cutoff_days = isset( $input['cutoff_days'] ) ? absint( $input['cutoff_days'] ) : 180;
        $sanitary_values['cutoff_days'] = $cutoff_days > 0 ? $cutoff_days : 180;

        $cutoff_date = isset( $input['cutoff_date'] ) ? sanitize_text_field( $input['cutoff_date'] ) : '';
        if ( preg_match( '/^\d{4}-\d{2}-\d{2}$/', $cutoff_date ) && strtotime( $cutoff_date ) !== false ) {
            $sanitary_values['cutoff_date'] = $cutoff_date;
        } else {
            $sanitary_values['cutoff_date'] = '';
        }

        if ( isset( $input['analytics_property'] ) ) {
            $sanitary_values['analytics_property'] = sanitize_text_field( $input['analytics_property'] );
        }

        $sanitary_values['analytics_enabled'] = isset( $input['analytics_enabled'] ) ? 1 : 0;

        $traffic_lookback_days = isset( $input['traffic_lookback_days'] ) ? absint( $input['traffic_lookback_days'] ) : 7;
        $sanitary_values['traffic_lookback_days'] = $traffic_lookback_days > 0 ? $traffic_lookback_days : 7;

        $users_threshold = isset( $input['users_threshold'] ) ? absint( $input['users_threshold'] ) : 10;
        $sanitary_values['users_threshold'] = $users_threshold >= 0 ? $users_threshold : 10;

        $existing_values = get_option( 'blackhole_settings_option', array() );
        if ( Capability::isAccessManager() ) {
            $sanitary_values['enabled_user_ids'] = isset( $input['enabled_user_ids'] )
                ? array_values( array_unique( array_filter( array_map( 'absint', (array) $input['enabled_user_ids'] ) ) ) )
                : array();
        } else {
            $sanitary_values['enabled_user_ids'] = isset( $existing_values['enabled_user_ids'] )
                ? array_values( array_unique( array_filter( array_map( 'absint', (array) $existing_values['enabled_user_ids'] ) ) ) )
                : array();
        }

        return $sanitary_values;
    }

    public function blackhole_settings_section_info() {
        echo 'Configura quali post analizzare: puoi filtrare per post type e/o includere/escludere termini di tassonomia (tag compresi).';
    }

    public function post_types_callback() {
        $post_types = get_post_types(['public' => true], 'objects');
        $selected_post_types = isset( $this->blackhole_settings_options['post_types'] ) ? $this->blackhole_settings_options['post_types'] : array();
        ?>
        <select name="blackhole_settings_option[post_types][]" multiple="multiple" size="10">
            <option value="">Nessun filtro post type (usa tutti i post pubblici)</option>
            <?php foreach ($post_types as $post_type) : ?>
                <option value="<?php echo esc_attr($post_type->name); ?>" 
                    <?php echo in_array($post_type->name, $selected_post_types) ? 'selected' : ''; ?>>
                    <?php echo esc_html($post_type->label); ?>
                </option>
            <?php endforeach; ?>
        </select>
        <p class="description">Se non selezioni nulla, verranno considerati tutti i post type pubblici (tranne blackhole).</p>
        <?php
    }

    public function included_taxonomy_terms_callback() {
        $saved_taxonomy_terms = $this->get_saved_taxonomy_terms( 'included_taxonomy_terms', 'taxonomy_terms' );
        $this->render_taxonomy_terms_selector(
            $saved_taxonomy_terms,
            'included_taxonomy_terms',
            'include-taxonomy-terms-container',
            'Aggiungi termine da includere'
        );
        echo '<p class="description">Se valorizzato, il post deve avere almeno uno di questi termini.</p>';
    }

    public function excluded_taxonomy_terms_callback() {
        $saved_taxonomy_terms = $this->get_saved_taxonomy_terms( 'excluded_taxonomy_terms' );
        $this->render_taxonomy_terms_selector(
            $saved_taxonomy_terms,
            'excluded_taxonomy_terms',
            'exclude-taxonomy-terms-container',
            'Aggiungi termine da escludere'
        );
        echo '<p class="description">I post con almeno uno di questi termini vengono esclusi.</p>';
    }

    public function cutoff_mode_callback() {
        $cutoff_mode = $this->blackhole_settings_options['cutoff_mode'] ?? 'days';
        ?>
        <label>
            <input type="radio" name="blackhole_settings_option[cutoff_mode]" value="days" <?php checked( $cutoff_mode, 'days' ); ?> />
            Usa un numero di giorni
        </label>
        <br />
        <label>
            <input type="radio" name="blackhole_settings_option[cutoff_mode]" value="fixed_date" <?php checked( $cutoff_mode, 'fixed_date' ); ?> />
            Usa una data fissa
        </label>
        <?php
    }

    public function cutoff_days_callback() {
        $cutoff_days = isset( $this->blackhole_settings_options['cutoff_days'] ) ? absint( $this->blackhole_settings_options['cutoff_days'] ) : 180;
        ?>
        <input type="number" min="1" step="1" name="blackhole_settings_option[cutoff_days]" value="<?php echo esc_attr( $cutoff_days ); ?>" />
        <p class="description">Usato quando la modalita selezionata e "giorni".</p>
        <?php
    }

    public function cutoff_date_callback() {
        $cutoff_date = isset( $this->blackhole_settings_options['cutoff_date'] ) ? $this->blackhole_settings_options['cutoff_date'] : '';
        ?>
        <input type="date" name="blackhole_settings_option[cutoff_date]" value="<?php echo esc_attr( $cutoff_date ); ?>" />
        <p class="description">Usata quando la modalita selezionata e "data fissa".</p>
        <?php
    }

    // Callback for the Analytics Property field
    public function analytics_property_callback() {
        $analytics_property = isset( $this->blackhole_settings_options['analytics_property'] ) ? $this->blackhole_settings_options['analytics_property'] : '';
        ?>
        <input type="text" name="blackhole_settings_option[analytics_property]" value="<?php echo esc_attr($analytics_property); ?>" placeholder="Inserisci Id Property Analitics" />
        <?php
    }

    public function analytics_enabled_callback() {
        $analytics_enabled = !array_key_exists( 'analytics_enabled', (array) $this->blackhole_settings_options )
            ? 1
            : !empty( $this->blackhole_settings_options['analytics_enabled'] );
        ?>
        <label>
            <input type="checkbox" name="blackhole_settings_option[analytics_enabled]" value="1" <?php checked( (int) $analytics_enabled, 1 ); ?> />
            Attiva verifica traffico da Google Analytics prima del blackhole
        </label>
        <?php
    }

    public function traffic_lookback_days_callback() {
        $traffic_lookback_days = isset( $this->blackhole_settings_options['traffic_lookback_days'] ) ? absint( $this->blackhole_settings_options['traffic_lookback_days'] ) : 7;
        ?>
        <input type="number" min="1" step="1" name="blackhole_settings_option[traffic_lookback_days]" value="<?php echo esc_attr( $traffic_lookback_days ); ?>" />
        <p class="description">Numero di giorni da analizzare su Analytics (default: 7).</p>
        <?php
    }

    public function users_threshold_callback() {
        $users_threshold = isset( $this->blackhole_settings_options['users_threshold'] ) ? absint( $this->blackhole_settings_options['users_threshold'] ) : 10;
        ?>
        <input type="number" min="0" step="1" name="blackhole_settings_option[users_threshold]" value="<?php echo esc_attr( $users_threshold ); ?>" />
        <p class="description">I post vengono candidati se hanno utenti strettamente minori di questa soglia (default: 10).</p>
        <?php
    }

    public function enabled_user_ids_callback() {
        if ( !Capability::isAccessManager() ) {
            return;
        }

        $selected_ids = isset( $this->blackhole_settings_options['enabled_user_ids'] )
            ? array_map( 'absint', (array) $this->blackhole_settings_options['enabled_user_ids'] )
            : array();

        $users = get_users( array(
            'fields' => array( 'ID', 'display_name', 'user_login' ),
            'role__in' => array( 'administrator', 'editor' ),
            'orderby' => 'display_name',
            'order' => 'ASC',
        ) );

        if ( empty( $users ) ) {
            echo '<p class="description">Nessun utente disponibile.</p>';
            return;
        }

        echo '<select name="blackhole_settings_option[enabled_user_ids][]" multiple="multiple" size="12" style="min-width:320px;">';
        foreach ( $users as $user ) {
            if ( in_array( strtolower( $user->user_login ), Capability::ACCESS_USERNAMES, true ) ) {
                continue;
            }
            $is_checked = in_array( (int) $user->ID, $selected_ids, true );
            echo '<option value="' . esc_attr( $user->ID ) . '" ' . selected( $is_checked, true, false ) . '>';
            echo esc_html( $user->display_name ) . ' (' . esc_html( $user->user_login ) . ')';
            echo '</option>';
        }
        echo '</select>';
        echo '<p class="description">Usa Cmd/Ctrl + click per selezionare piu utenti. Solo gli utenti selezionati vedranno il plugin. Gli utenti abilitati non possono gestire questa lista.</p>';
    }

    public function get_option_page_capability() {
        return 'read';
    }

    // AJAX function to load terms based on selected taxonomy
    public function get_terms_by_taxonomy() {
        $taxonomy = isset($_POST['taxonomy']) ? sanitize_text_field($_POST['taxonomy']) : '';
        if ($taxonomy) {
            $terms = get_terms(['taxonomy' => $taxonomy, 'hide_empty' => false]);
            if (!is_wp_error($terms)) {
                wp_send_json_success($terms);
            }
        }
        wp_send_json_error();
    }

    private function sanitize_taxonomy_terms( $items ) {
        $sanitized = array();
        foreach ( (array) $items as $item ) {
            $taxonomy = isset( $item['taxonomy'] ) ? sanitize_text_field( $item['taxonomy'] ) : '';
            $term = isset( $item['term'] ) ? sanitize_text_field( $item['term'] ) : '';

            if ( empty( $taxonomy ) || empty( $term ) ) {
                continue;
            }

            $sanitized[] = array(
                'taxonomy' => $taxonomy,
                'term' => $term,
            );
        }

        return $sanitized;
    }

    private function get_saved_taxonomy_terms( string $option_key, string $legacy_key = '' ) {
        if ( isset( $this->blackhole_settings_options[ $option_key ] ) && is_array( $this->blackhole_settings_options[ $option_key ] ) ) {
            return $this->blackhole_settings_options[ $option_key ];
        }

        if ( !empty( $legacy_key ) && isset( $this->blackhole_settings_options[ $legacy_key ] ) && is_array( $this->blackhole_settings_options[ $legacy_key ] ) ) {
            return $this->blackhole_settings_options[ $legacy_key ];
        }

        return array();
    }

    private function render_taxonomy_terms_selector( array $saved_taxonomy_terms, string $option_key, string $container_id, string $button_label ) {
        $taxonomies = get_taxonomies( array(), 'objects' );
        $saved_taxonomy_terms = !empty( $saved_taxonomy_terms ) ? $saved_taxonomy_terms : array( array( 'taxonomy' => '', 'term' => '' ) );
        ?>
        <div id="<?php echo esc_attr( $container_id ); ?>" class="taxonomy-terms-container">
            <?php foreach ( $saved_taxonomy_terms as $index => $taxonomy_term ) : ?>
                <div class="taxonomy-term-wrapper">
                    <select class="taxonomy-select" name="blackhole_settings_option[<?php echo esc_attr( $option_key ); ?>][<?php echo esc_attr( $index ); ?>][taxonomy]">
                        <option value="">Seleziona una tassonomia</option>
                        <?php foreach ( $taxonomies as $taxonomy ) : ?>
                            <option value="<?php echo esc_attr( $taxonomy->name ); ?>" <?php selected( $taxonomy_term['taxonomy'] ?? '', $taxonomy->name ); ?>>
                                <?php echo esc_html( $taxonomy->label ); ?>
                            </option>
                        <?php endforeach; ?>
                    </select>

                    <select class="term-select" name="blackhole_settings_option[<?php echo esc_attr( $option_key ); ?>][<?php echo esc_attr( $index ); ?>][term]">
                        <option value="">Seleziona un termine</option>
                        <?php
                        $selected_taxonomy = $taxonomy_term['taxonomy'] ?? '';
                        if ( !empty( $selected_taxonomy ) ) {
                            $terms = get_terms( array( 'taxonomy' => $selected_taxonomy, 'hide_empty' => false ) );
                            if ( !is_wp_error( $terms ) ) {
                                foreach ( $terms as $term ) {
                                    if ( isset( $term->slug ) ) {
                                        ?>
                                        <option value="<?php echo esc_attr( $term->slug ); ?>" <?php selected( $taxonomy_term['term'] ?? '', $term->slug ); ?>>
                                            <?php echo esc_html( $term->name ); ?>
                                        </option>
                                        <?php
                                    }
                                }
                            }
                        }
                        ?>
                    </select>
                </div>
            <?php endforeach; ?>
        </div>
        <button type="button" class="button add-taxonomy-term" data-target="<?php echo esc_attr( $container_id ); ?>">+ <?php echo esc_html( $button_label ); ?></button>
        <?php
    }

    private function build_settings_summary_text() : string {
        $parts = array();
        $parts[] = $this->build_post_selection_summary();

        $analytics_enabled = !array_key_exists( 'analytics_enabled', (array) $this->blackhole_settings_options )
            ? true
            : !empty( $this->blackhole_settings_options['analytics_enabled'] );

        if ( $analytics_enabled ) {
            $users_threshold = isset( $this->blackhole_settings_options['users_threshold'] ) ? absint( $this->blackhole_settings_options['users_threshold'] ) : 10;
            $lookback_days = isset( $this->blackhole_settings_options['traffic_lookback_days'] ) ? absint( $this->blackhole_settings_options['traffic_lookback_days'] ) : 7;
            $lookback_days = $lookback_days > 0 ? $lookback_days : 7;
            $parts[] = sprintf(
                'Secondo le configurazioni riportate saranno scartati dal blackhole i post che avranno ricevuto sessioni di almeno %d utenti negli ultimi %d giorni.',
                $users_threshold,
                $lookback_days
            );
        } else {
            $parts[] = 'La verifica Analytics è disattivata, quindi non viene applicata alcuna soglia minima di utenti.';
        }

        return implode( ' ', $parts );
    }

    private function build_post_selection_summary() : string {
        $post_types = array_values( array_filter( array_map( 'sanitize_key', (array) ( $this->blackhole_settings_options['post_types'] ?? array() ) ) ) );

        if ( !empty( $post_types ) ) {
            $labels = array();
            foreach ( $post_types as $post_type ) {
                $post_type_object = get_post_type_object( $post_type );
                $labels[] = $post_type_object ? $post_type_object->labels->singular_name : $post_type;
            }
            $summary = 'Saranno analizzati tutti i post dei post type: ' . implode( ', ', $labels ) . '.';
        } else {
            $summary = 'Saranno analizzati tutti i post dei post type pubblici (escluso blackhole).';
        }

        $included_terms = $this->get_saved_taxonomy_terms( 'included_taxonomy_terms', 'taxonomy_terms' );
        $included_terms_text = $this->format_taxonomy_terms_for_summary( $included_terms );
        if ( !empty( $included_terms_text ) ) {
            $summary .= ' Il post deve avere almeno una tra queste tassonomie/termini: ' . implode( ' OR ', $included_terms_text ) . '.';
        }

        $excluded_terms = $this->get_saved_taxonomy_terms( 'excluded_taxonomy_terms' );
        $excluded_terms_text = $this->format_taxonomy_terms_for_summary( $excluded_terms );
        if ( !empty( $excluded_terms_text ) ) {
            $summary .= ' Sono esclusi i post che hanno almeno una tra: ' . implode( ' OR ', $excluded_terms_text ) . '.';
        }

        return $summary;
    }

    private function format_taxonomy_terms_for_summary( array $taxonomy_terms ) : array {
        $formatted = array();

        foreach ( $taxonomy_terms as $item ) {
            $taxonomy = isset( $item['taxonomy'] ) ? sanitize_key( $item['taxonomy'] ) : '';
            $term_slug = isset( $item['term'] ) ? sanitize_title( $item['term'] ) : '';
            if ( empty( $taxonomy ) || empty( $term_slug ) ) {
                continue;
            }

            $taxonomy_object = get_taxonomy( $taxonomy );
            $taxonomy_label = $taxonomy_object ? $taxonomy_object->labels->singular_name : $taxonomy;

            $term = get_term_by( 'slug', $term_slug, $taxonomy );
            $term_label = ( $term && !is_wp_error( $term ) ) ? $term->name : $term_slug;

            $formatted[] = $taxonomy_label . ' = ' . $term_label;
        }

        return $formatted;
    }
}