<?php
if ( ! defined( 'ABSPATH' ) ) { exit; }

/**
 * Global settings page - registers menu, renders page, saves option.
 */
class TNC_Flipbook_3D_Settings {

    public static function init() {
        add_action( 'admin_menu',        array( __CLASS__, 'add_menu' ) );
        add_action( 'admin_init',        array( __CLASS__, 'register_settings' ) );
        add_action( 'admin_post_tncfb3d_save_settings', array( __CLASS__, 'save_settings' ) );
    }

    // ── Menu ──────────────────────────────────────────────────────────────────

    public static function add_menu() {
        add_submenu_page(
            'edit.php?post_type=' . TNC_FLIPBOOK_3D_CPT,
            __( 'TNC FlipBook 3D Settings', 'tnc-flipbook-3d-lite' ),
            __( 'Global Settings', 'tnc-flipbook-3d-lite' ),
            'manage_options',
            'tnc-flipbook-3d-settings',
            array( __CLASS__, 'render_page' )
        );

    }

    /**
     * Render the Addons page.
     */
    public static function render_addons_page() {
        if ( ! current_user_can( 'manage_options' ) ) {
            wp_die( esc_html__( 'Unauthorized', 'tnc-flipbook-3d-lite' ) );
        }
        include TNC_FLIPBOOK_3D_DIR . 'admin/views/addons-page.php';
    }

    /**
     * Fetch ideas from the Fider API (cached 30 min).
     */
    // ── Welcome page ──────────────────────────────────────────────────────────

    /**
     * Render the Welcome / Getting Started page.
     */
    public static function render_welcome_page() {
        if ( ! current_user_can( 'manage_options' ) ) {
            wp_die( esc_html__( 'Unauthorized', 'tnc-flipbook-3d-lite' ) );
        }
        include TNC_FLIPBOOK_3D_DIR . 'admin/views/welcome-page.php';
    }

    // ── Ideas page helpers ──────────────────────────────────────────────────

    /**
     * Render the Ideas & Roadmap page.
     */
    public static function render_ideas_page() {
        // WordPress.org build: the Ideas & Roadmap page is not shipped.
    }

    // ── Settings API registration (for REST schema only; we handle saving manually) ──

    public static function register_settings() {
        register_setting( 'tnc_flipbook_3d_settings_group', TNC_FLIPBOOK_3D_OPTION, array(
            'sanitize_callback' => array( __CLASS__, 'sanitize_options' ),
        ) );
    }

    // ── Render ────────────────────────────────────────────────────────────────

    public static function render_page() {
        if ( ! current_user_can( 'manage_options' ) ) {
            return;
        }
        $options = get_option( TNC_FLIPBOOK_3D_OPTION, array() );
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only flag from settings-saved redirect.
        $saved   = isset( $_GET['tncfb3d_saved'] ) && '1' === sanitize_text_field( wp_unslash( $_GET['tncfb3d_saved'] ) );
        include TNC_FLIPBOOK_3D_DIR . 'admin/views/settings-page.php';
    }

    // ── Save ──────────────────────────────────────────────────────────────────

    public static function save_settings() {
        if ( ! current_user_can( 'manage_options' ) ) {
            wp_die( esc_html__( 'Permission denied.', 'tnc-flipbook-3d-lite' ) );
        }
        check_admin_referer( 'tncfb3d_save_settings', 'tncfb3d_settings_nonce' );

        $raw     = isset( $_POST[ TNC_FLIPBOOK_3D_OPTION ] ) ? (array) wp_unslash( $_POST[ TNC_FLIPBOOK_3D_OPTION ] ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitized in self::sanitize_options() per-field.
        $clean   = self::sanitize_options( $raw );
        update_option( TNC_FLIPBOOK_3D_OPTION, $clean );

        do_action( 'tncfb3d_settings_saved', $clean );


        wp_safe_redirect( add_query_arg( array(
            'page'        => 'tnc-flipbook-3d-settings',
            'post_type'   => TNC_FLIPBOOK_3D_CPT,
            'tncfb3d_saved' => '1',
        ), admin_url( 'edit.php' ) ) );
        exit;
    }

    // ── Sanitize ──────────────────────────────────────────────────────────────

    public static function sanitize_options( $raw ) {
        if ( ! is_array( $raw ) ) {
            return array();
        }
        $schema  = TNC_Flipbook_3D_Meta_Schema::get();
        $p       = TNC_FLIPBOOK_3D_PREFIX;
        $cleaned = array();

        // Sanitize all overridable fields using the meta schema
        foreach ( $schema as $meta_key => $config ) {
            if ( empty( $config['overridable'] ) || empty( $config['global_key'] ) ) {
                continue; // Content-source fields etc. have no global default
            }
            $global_key = $config['global_key'];

            if ( isset( $raw[ $global_key ] ) ) {
                $cleaned[ $global_key ] = TNC_Flipbook_3D_Meta_Schema::sanitize( $meta_key, $raw[ $global_key ] );
            } elseif ( 'bool' === $config['type'] ) {
                // Toolbar items not exposed in the settings UI should keep their
                // schema default instead of being forced to false when absent from POST.
                $hidden_toolbar = array( 'toolbar_moreMenu', 'toolbar_flipbookStyles', 'toolbar_viewModes' );
                // In Lite, toolbar-item visibility is a Pro-only control: every toggle
                // renders disabled with no name attribute, so toolbar_* keys never reach
                // POST. Forcing them to false would hide the whole toolbar after any
                // settings save (and the off-values would persist into a later Lite->Pro
                // upgrade). Keep the schema default for locked toolbar items.
                $is_locked_toolbar = false; // WordPress.org build: toolbar visibility is fully configurable.
                if ( in_array( $global_key, $hidden_toolbar, true ) || $is_locked_toolbar ) {
                    $cleaned[ $global_key ] = $config['default'];
                } else {
                    // Unchecked checkboxes are absent from POST - explicitly set to false
                    $cleaned[ $global_key ] = false;
                }
            }
        }

        // Integration keys (global-only, not in meta schema)
        $integration_keys = array(
            // Analytics
            'ga4MeasurementId',
            // Protection
            'protection_admin_bypass',
            // Custom CSS
            'custom_css',
            // Custom flip sound
            'flipSoundCustom_id',
            // TTS
            'tts_google_key', 'tts_elevenlabs_key', 'tts_azure_key', 'tts_azure_region',
            'tts_amazon_key', 'tts_amazon_secret', 'tts_amazon_region',
            // AI services
            'openai_key', 'anthropic_key', 'google_ai_key',
            // Branding
            'loadingLogo_id', 'loadingLogoDark_id', 'favicon_id',
            // Advanced
            'show_attribution',
            'delete_data_on_uninstall',
        );

        /**
         * Filter the list of integration keys that are saved from the Integrations tab.
         * Addons can append their own keys here so they get persisted in the same option.
         *
         * @param array $integration_keys List of option keys.
         */
        $integration_keys = apply_filters( 'tncfb3d_integration_keys', $integration_keys );

        foreach ( $integration_keys as $ik ) {
            if ( isset( $raw[ $ik ] ) ) {
                $cleaned[ $ik ] = sanitize_text_field( $raw[ $ik ] );
            }
        }

        // Only the fully-sanitized values are exposed to the filter; the raw
        // (unsanitized) POST array is intentionally not passed to callbacks.
        return apply_filters( 'tncfb3d_settings_sanitize', $cleaned );
    }

    /**
     * Get a single global setting value by its global_key, with fallback to schema default.
     */
    public static function get( $global_key, $fallback = null ) {
        $options = get_option( TNC_FLIPBOOK_3D_OPTION, array() );
        if ( isset( $options[ $global_key ] ) ) {
            return $options[ $global_key ];
        }
        // Try schema default - find the meta entry with this global_key
        $schema = TNC_Flipbook_3D_Meta_Schema::get();
        foreach ( $schema as $meta_key => $config ) {
            if ( ! empty( $config['global_key'] ) && $config['global_key'] === $global_key ) {
                return $config['default'];
            }
        }
        return $fallback;
    }

    // ── Integration key API ────────────────────────────────────────────────

    /**
     * Get an integration key / credential by name.
     *
     * Addons should use this (or the wrapper function tncfb3d_get_key()) instead
     * of reading the option directly.
     *
     * @param  string $key_name  e.g. 'openai_key', 'anthropic_key', 'tts_google_key', 'ga4MeasurementId'.
     * @param  string $default   Fallback if not set.
     * @return string
     */
    public static function get_integration_key( $key_name, $default = '' ) {
        $options = get_option( TNC_FLIPBOOK_3D_OPTION, array() );
        $value   = isset( $options[ $key_name ] ) ? $options[ $key_name ] : '';
        return $value ? $value : $default;
    }

    /**
     * Check whether an integration key is configured (non-empty).
     *
     * @param  string $key_name
     * @return bool
     */
    public static function has_integration_key( $key_name ) {
        return '' !== self::get_integration_key( $key_name );
    }
}

// ── Global helper functions ────────────────────────────────────────────────

if ( ! function_exists( 'tncfb3d_get_key' ) ) {
    /**
     * Retrieve an integration API key / credential.
     *
     * Usage:
     *   $openai  = tncfb3d_get_key( 'openai_key' );
     *   $ga4     = tncfb3d_get_key( 'ga4MeasurementId' );
     *   $azure   = tncfb3d_get_key( 'tts_azure_key' );
     *   $custom  = tncfb3d_get_key( 'my_addon_key' );  // addon-registered key
     *
     * @param  string $key_name  The integration key identifier.
     * @param  string $default   Fallback value if the key is not configured.
     * @return string
     */
    function tncfb3d_get_key( $key_name, $default = '' ) {
        return TNC_Flipbook_3D_Settings::get_integration_key( $key_name, $default );
    }
}

if ( ! function_exists( 'tncfb3d_has_key' ) ) {
    /**
     * Check whether an integration key is configured.
     *
     * @param  string $key_name
     * @return bool
     */
    function tncfb3d_has_key( $key_name ) {
        return TNC_Flipbook_3D_Settings::has_integration_key( $key_name );
    }
}
