<?php

/**
 * Settings page
 *
 * @package SlideMind
 * @since 2.0.0
 */
namespace SlideMind\Admin;

use SlideMind\Core\ApiKeyManager;
if ( !defined( 'ABSPATH' ) ) {
    exit;
}
class SettingsPage {
    /**
     * API key manager
     * @var ApiKeyManager
     */
    private $api_key_manager;

    /**
     * Constructor
     *
     * @param ApiKeyManager $api_key_manager
     */
    public function __construct( ApiKeyManager $api_key_manager ) {
        $this->api_key_manager = $api_key_manager;
        add_action( 'admin_init', [$this, 'register_settings'] );
        add_action( 'wp_ajax_slidemind_test_api_key', [$this, 'ajax_test_api_key'] );
        add_action( 'wp_ajax_slidemind_save_settings', [$this, 'ajax_save_settings'] );
        add_action( 'wp_ajax_slidemind_export_all_data', [$this, 'ajax_export_all_data'] );
        add_action( 'wp_ajax_slidemind_export_all_courses', [$this, 'ajax_export_all_courses'] );
        add_action( 'wp_ajax_slidemind_export_all_modules', [$this, 'ajax_export_all_modules'] );
        add_action( 'wp_ajax_slidemind_export_all_slides', [$this, 'ajax_export_all_slides'] );
        // Invalidate profile fields cache when a plugin is activated/deactivated
        add_action( 'activated_plugin', [__CLASS__, 'clear_profile_fields_cache'] );
        add_action( 'deactivated_plugin', [__CLASS__, 'clear_profile_fields_cache'] );
    }

    /**
     * Register WordPress settings
     */
    public function register_settings() {
        register_setting( 'slidemind_settings', 'slidemind_settings', [
            'sanitize_callback' => [$this, 'sanitize_settings'],
        ] );
    }

    /**
     * Sanitize settings
     *
     * @param array $input
     * @return array
     */
    public function sanitize_settings( $input ) {
        $sanitized = [];
        // Global provider
        $valid_providers = \SlideMind\Core\LLMProxy::get_provider_slugs();
        if ( isset( $input['global_provider'] ) && in_array( $input['global_provider'], $valid_providers, true ) ) {
            update_option( 'slidemind_global_provider', $input['global_provider'] );
        }
        // API keys per provider
        foreach ( $valid_providers as $provider ) {
            $key_field = 'api_key_' . $provider;
            if ( isset( $input[$key_field] ) && !empty( $input[$key_field] ) ) {
                if ( strpos( $input[$key_field], '****' ) === false ) {
                    $this->api_key_manager->save_global_api_key( $input[$key_field], $provider );
                }
            }
        }
        // Backward compatibility: global_api_key field (legacy format)
        if ( isset( $input['global_api_key'] ) && !empty( $input['global_api_key'] ) ) {
            if ( strpos( $input['global_api_key'], '****' ) === false ) {
                $this->api_key_manager->save_global_api_key( $input['global_api_key'], 'openrouter' );
            }
        }
        // Other options
        $sanitized['log_retention_days'] = ( isset( $input['log_retention_days'] ) ? absint( $input['log_retention_days'] ) : 90 );
        // Memory retention: 0 = never purge, otherwise min 7 days
        $sanitized['memory_retention_days'] = ( isset( $input['memory_retention_days'] ) ? absint( $input['memory_retention_days'] ) : 0 );
        if ( $sanitized['memory_retention_days'] > 0 && $sanitized['memory_retention_days'] < 7 ) {
            $sanitized['memory_retention_days'] = 7;
        }
        // Anonymous session TTL: 1-168 hours, default 24
        $sanitized['anonymous_session_ttl'] = ( isset( $input['anonymous_session_ttl'] ) ? max( 1, min( 168, (int) $input['anonymous_session_ttl'] ) ) : 24 );
        $sanitized['chat_rate_limit'] = ( isset( $input['chat_rate_limit'] ) ? absint( $input['chat_rate_limit'] ) : 60 );
        $sanitized['enable_sandbox'] = ( isset( $input['enable_sandbox'] ) ? (bool) $input['enable_sandbox'] : true );
        $sanitized['widget_consent_enabled'] = !empty( $input['widget_consent_enabled'] );
        $sanitized['strip_markdown_qa'] = !empty( $input['strip_markdown_qa'] );
        $sanitized['strip_markdown_chat'] = !empty( $input['strip_markdown_chat'] );
        $sanitized['default_model'] = ( isset( $input['default_model'] ) ? sanitize_text_field( $input['default_model'] ) : 'anthropic/claude-3.5-sonnet' );
        $sanitized['default_temperature'] = ( isset( $input['default_temperature'] ) ? max( 0, min( 2, (float) $input['default_temperature'] ) ) : 0.7 );
        $sanitized['default_max_tokens'] = ( isset( $input['default_max_tokens'] ) ? max( 1, min( 128000, (int) $input['default_max_tokens'] ) ) : 1024 );
        $valid_editors = [
            'storyline',
            'captivate',
            'lectora',
            'dominknow',
            'ispring',
            'widget'
        ];
        $sanitized['default_editor'] = ( isset( $input['default_editor'] ) && in_array( $input['default_editor'], $valid_editors, true ) ? $input['default_editor'] : 'storyline' );
        // Widget appearance defaults
        $sanitized['widget_color'] = ( isset( $input['widget_color'] ) ? ( sanitize_hex_color( $input['widget_color'] ) ?: '#4f46e5' ) : '#4f46e5' );
        $sanitized['widget_ai_color'] = ( isset( $input['widget_ai_color'] ) ? ( sanitize_hex_color( $input['widget_ai_color'] ) ?: '#f1f5f9' ) : '#f1f5f9' );
        $sanitized['widget_theme'] = ( isset( $input['widget_theme'] ) && in_array( $input['widget_theme'], ['light', 'dark'], true ) ? $input['widget_theme'] : 'light' );
        $sanitized['widget_show_header'] = ( !empty( $input['widget_show_header'] ) ? '1' : '0' );
        $sanitized['widget_ai_text_color'] = ( isset( $input['widget_ai_text_color'] ) ? ( sanitize_hex_color( $input['widget_ai_text_color'] ) ?: '' ) : '' );
        $sanitized['widget_border_radius'] = ( isset( $input['widget_border_radius'] ) ? max( 0, min( 24, (int) $input['widget_border_radius'] ) ) : 12 );
        // Allowed profile fields for prompts
        $sanitized['allowed_profile_fields'] = [];
        if ( isset( $input['allowed_profile_fields'] ) && is_array( $input['allowed_profile_fields'] ) ) {
            $valid_keys = array_column( self::get_available_profile_fields(), 'key' );
            foreach ( $input['allowed_profile_fields'] as $field ) {
                $field = sanitize_text_field( $field );
                if ( in_array( $field, $valid_keys, true ) ) {
                    $sanitized['allowed_profile_fields'][] = $field;
                }
            }
        }
        // Profile field aliases (original key => short alias)
        // Alias must be a valid variable name: [a-z0-9_]
        $sanitized['profile_field_aliases'] = [];
        if ( isset( $input['profile_field_aliases'] ) && is_array( $input['profile_field_aliases'] ) ) {
            $valid_keys = array_column( self::get_available_profile_fields(), 'key' );
            foreach ( $input['profile_field_aliases'] as $original_key => $alias ) {
                $original_key = sanitize_text_field( $original_key );
                // Normalize to variable name: lowercase, Unicode letters + digits + underscores
                $alias = mb_strtolower( trim( $alias ) );
                $alias = preg_replace( '/[^\\p{L}0-9_]/u', '_', $alias );
                $alias = preg_replace( '/_+/', '_', $alias );
                $alias = trim( $alias, '_' );
                if ( !empty( $alias ) && in_array( $original_key, $valid_keys, true ) ) {
                    $sanitized['profile_field_aliases'][$original_key] = $alias;
                }
            }
        }
        // Favorite templates (max 5 slugs)
        $sanitized['favorite_templates'] = [];
        if ( isset( $input['favorite_templates'] ) && is_array( $input['favorite_templates'] ) ) {
            foreach ( array_slice( $input['favorite_templates'], 0, 6 ) as $slug ) {
                $sanitized['favorite_templates'][] = sanitize_text_field( $slug );
            }
        }
        // SCORM identification strategy
        $valid_scorm_mappings = [
            'auto',
            'email',
            'login',
            'id',
            'meta'
        ];
        $sanitized['scorm_id_mapping'] = ( isset( $input['scorm_id_mapping'] ) && in_array( $input['scorm_id_mapping'], $valid_scorm_mappings, true ) ? $input['scorm_id_mapping'] : 'auto' );
        $sanitized['scorm_id_meta_key'] = ( isset( $input['scorm_id_meta_key'] ) ? sanitize_key( $input['scorm_id_meta_key'] ) : '' );
        // CORS allowed origins (one per line)
        $sanitized['cors_allowed_origins'] = '';
        if ( isset( $input['cors_allowed_origins'] ) && !empty( $input['cors_allowed_origins'] ) ) {
            $lines = explode( "\n", $input['cors_allowed_origins'] );
            $clean = [];
            foreach ( $lines as $line ) {
                $line = trim( $line );
                if ( !empty( $line ) && filter_var( $line, FILTER_VALIDATE_URL ) ) {
                    $clean[] = rtrim( $line, '/' );
                }
            }
            $sanitized['cors_allowed_origins'] = implode( "\n", $clean );
        }
        // Guest access toggle (closed by default per WP.org compliance spec).
        $sanitized['allow_guests'] = !empty( $input['allow_guests'] );
        // CORS test mode (24 h auto-expiry)
        $previous = get_option( 'slidemind_settings', [] );
        $now_active = !empty( $input['cors_test_mode'] );
        if ( $now_active ) {
            $was_active = !empty( $previous['cors_test_mode'] );
            $sanitized['cors_test_mode'] = true;
            $sanitized['cors_test_mode_until'] = ( $was_active ? (int) ($previous['cors_test_mode_until'] ?? 0) : time() + DAY_IN_SECONDS );
        } else {
            $sanitized['cors_test_mode'] = false;
            $sanitized['cors_test_mode_until'] = 0;
        }
        return $sanitized;
    }

    /**
     * Retrieve current settings
     *
     * @return array
     */
    public function get_settings() {
        $defaults = [
            'chat_rate_limit'        => 60,
            'log_retention_days'     => 90,
            'enable_sandbox'         => true,
            'default_model'          => 'anthropic/claude-3.5-sonnet',
            'default_temperature'    => 0.7,
            'default_max_tokens'     => 1024,
            'allowed_profile_fields' => [],
            'profile_field_aliases'  => [],
            'default_editor'         => 'storyline',
            'favorite_templates'     => [
                'quiz',
                'open-question',
                'formative-eval',
                'socratic',
                'roleplay',
                'guided-exploration'
            ],
            'anonymous_session_ttl'  => 24,
            'cors_allowed_origins'   => '',
            'widget_consent_enabled' => false,
            'cors_test_mode'         => false,
            'cors_test_mode_until'   => 0,
            'scorm_id_mapping'       => 'auto',
            'scorm_id_meta_key'      => '',
            'widget_color'           => '#4f46e5',
            'widget_ai_color'        => '#f1f5f9',
            'widget_theme'           => 'light',
            'widget_show_header'     => '1',
            'widget_ai_text_color'   => '',
            'widget_border_radius'   => 12,
            'strip_markdown_qa'      => true,
            'strip_markdown_chat'    => true,
            'allow_guests'           => false,
        ];
        $settings = get_option( 'slidemind_settings', [] );
        return wp_parse_args( $settings, $defaults );
    }

    /**
     * Check if a global API key is configured
     *
     * @return bool
     */
    public function has_global_api_key() {
        $key = $this->api_key_manager->get_global_api_key();
        return !empty( $key );
    }

    /**
     * Retrieve the masked global API key
     *
     * @return string
     */
    public function get_masked_global_api_key() {
        $key = $this->api_key_manager->get_global_api_key();
        return $this->api_key_manager->mask_key( $key );
    }

    /**
     * AJAX: Test an API key
     */
    public function ajax_test_api_key() {
        check_ajax_referer( 'slidemind_admin_nonce', 'nonce' );
        if ( !current_user_can( 'manage_slidemind_settings' ) ) {
            wp_send_json_error( [
                'message' => __( 'Unauthorized access', 'slidemind' ),
            ] );
        }
        $api_key = ( isset( $_POST['api_key'] ) ? sanitize_text_field( wp_unslash( $_POST['api_key'] ) ) : '' );
        $provider = ( isset( $_POST['provider'] ) ? sanitize_text_field( wp_unslash( $_POST['provider'] ) ) : 'openrouter' );
        // Validate the provider
        $valid_providers = \SlideMind\Core\LLMProxy::get_provider_slugs();
        if ( !in_array( $provider, $valid_providers, true ) ) {
            $provider = 'openrouter';
        }
        if ( empty( $api_key ) ) {
            wp_send_json_error( [
                'message' => __( 'API key required', 'slidemind' ),
            ] );
        }
        $result = $this->api_key_manager->test_api_key( $api_key, $provider );
        if ( $result['valid'] ) {
            wp_send_json_success( [
                'message' => $result['message'],
                'credits' => $result['credits'],
            ] );
        } else {
            wp_send_json_error( [
                'message' => $result['message'],
            ] );
        }
    }

    /**
     * Returns metadata for all supported profile sources (installed or not).
     */
    public static function get_all_supported_sources() : array {
        return [
            'WordPress'       => [
                'installed' => true,
            ],
            'BuddyBoss'       => [
                'installed' => function_exists( 'bp_xprofile_get_groups' ) || function_exists( 'groups_get_groups' ),
            ],
            'LearnDash'       => [
                'installed' => defined( 'LEARNDASH_VERSION' ),
            ],
            'WooCommerce'     => [
                'installed' => class_exists( 'WooCommerce' ),
            ],
            'ACF'             => [
                'installed' => function_exists( 'acf_get_field_groups' ),
            ],
            'Ultimate Member' => [
                'installed' => class_exists( 'UM' ),
            ],
            'Tutor LMS'       => [
                'installed' => function_exists( 'tutor' ),
            ],
            'LifterLMS'       => [
                'installed' => class_exists( 'LifterLMS' ),
            ],
            'MemberPress'     => [
                'installed' => defined( 'MEPR_VERSION' ),
            ],
        ];
    }

    /**
     * Return available profile fields list (with transient cache)
     *
     * Automatically detects active plugins and exposes their user fields.
     *
     * @return array [['key' => '...', 'label' => '...', 'source' => '...'], ...]
     */
    public static function get_available_profile_fields() : array {
        $cached = get_transient( 'slidemind_profile_fields_cache' );
        if ( $cached !== false ) {
            return $cached;
        }
        $fields = self::detect_wordpress_core();
        set_transient( 'slidemind_profile_fields_cache', $fields, HOUR_IN_SECONDS );
        return $fields;
    }

    /**
     * Invalidate profile fields cache
     */
    public static function clear_profile_fields_cache() : void {
        delete_transient( 'slidemind_profile_fields_cache' );
    }

    /**
     * WordPress core fields
     */
    private static function detect_wordpress_core() : array {
        return [
            [
                'key'    => 'display_name',
                'label'  => __( 'Display name', 'slidemind' ),
                'source' => 'WordPress',
            ],
            [
                'key'    => 'email',
                'label'  => __( 'Email', 'slidemind' ),
                'source' => 'WordPress',
            ],
            [
                'key'    => 'first_name',
                'label'  => __( 'First name', 'slidemind' ),
                'source' => 'WordPress',
            ],
            [
                'key'    => 'last_name',
                'label'  => __( 'Last name', 'slidemind' ),
                'source' => 'WordPress',
            ],
            [
                'key'    => 'role',
                'label'  => __( 'Role', 'slidemind' ),
                'source' => 'WordPress',
            ]
        ];
    }

    /**
     * AJAX: Save settings
     */
    public function ajax_save_settings() {
        check_ajax_referer( 'slidemind_admin_nonce', 'nonce' );
        if ( !current_user_can( 'manage_slidemind_settings' ) ) {
            wp_send_json_error( [
                'message' => __( 'Unauthorized access', 'slidemind' ),
            ] );
        }
        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- JSON data, sanitized after decode
        $settings = ( isset( $_POST['settings'] ) ? wp_unslash( $_POST['settings'] ) : [] );
        // Normalize keys with [] (jQuery serializeArray)
        if ( isset( $settings['allowed_profile_fields[]'] ) ) {
            $val = $settings['allowed_profile_fields[]'];
            $settings['allowed_profile_fields'] = ( is_array( $val ) ? $val : [$val] );
            unset($settings['allowed_profile_fields[]']);
        }
        // Preserve settings managed by other pages (Memory, Templates)
        // to avoid overwriting them with empty defaults
        $existing = get_option( 'slidemind_settings', [] );
        $preserve_keys = ['allowed_profile_fields', 'profile_field_aliases', 'favorite_templates'];
        foreach ( $preserve_keys as $key ) {
            if ( !isset( $settings[$key] ) && isset( $existing[$key] ) ) {
                $settings[$key] = $existing[$key];
            }
        }
        // Sanitize and save — remove_filter avoids double-sanitization via register_setting
        remove_filter( 'sanitize_option_slidemind_settings', [$this, 'sanitize_settings'] );
        $sanitized = $this->sanitize_settings( $settings );
        update_option( 'slidemind_settings', $sanitized );
        add_filter( 'sanitize_option_slidemind_settings', [$this, 'sanitize_settings'] );
        // Invalidate profile fields cache (allowed fields may have changed)
        self::clear_profile_fields_cache();
        // Invalidate all model caches (the API key may have changed)
        foreach ( \SlideMind\Core\LLMProxy::get_provider_slugs() as $p ) {
            delete_transient( 'slidemind_' . $p . '_models' );
        }
        wp_send_json_success( [
            'message' => __( 'Settings saved', 'slidemind' ),
        ] );
    }

    // =========================================================================
    // BULK DATA EXPORT / IMPORT
    // =========================================================================
    /**
     * Creates a BulkDataManager instance
     *
     * @return \SlideMind\Core\BulkDataManager
     */
    private function get_bulk_data_manager() {
        $plugin = \SlideMind\Plugin::instance();
        return new \SlideMind\Core\BulkDataManager($plugin->get_config_repository(), $plugin->get_config_exporter(), $plugin->get_template_manager());
    }

    /**
     * Shared handler for bulk export AJAX actions
     *
     * @param string $method          BulkDataManager method name
     * @param string $filename_prefix Filename prefix (e.g. 'backup', 'courses')
     */
    private function do_bulk_export( string $method, string $filename_prefix ) {
        check_ajax_referer( 'slidemind_admin_nonce', 'nonce' );
        if ( !current_user_can( 'manage_slidemind_settings' ) ) {
            wp_send_json_error( [
                'message' => __( 'Unauthorized access', 'slidemind' ),
            ] );
        }
        $manager = $this->get_bulk_data_manager();
        $data = $manager->{$method}();
        $json = wp_json_encode( $data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT );
        wp_send_json_success( [
            'json'     => $json,
            'filename' => 'slidemind-' . $filename_prefix . '-' . gmdate( 'Y-m-d' ) . '.json',
        ] );
    }

    /**
     * AJAX: Export all plugin data (full backup)
     */
    public function ajax_export_all_data() {
        $this->do_bulk_export( 'export_all', 'backup' );
    }

    /**
     * AJAX: Export all courses (flat, no modules/slides)
     */
    public function ajax_export_all_courses() {
        $this->do_bulk_export( 'export_all_courses', 'courses' );
    }

    /**
     * AJAX: Export all modules (flat, no slides)
     */
    public function ajax_export_all_modules() {
        $this->do_bulk_export( 'export_all_modules', 'modules' );
    }

    /**
     * AJAX: Export all slides (flat)
     */
    public function ajax_export_all_slides() {
        $this->do_bulk_export( 'export_all_slides', 'slides' );
    }

}
