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

class Falcify_Settings {
    const OPTION = 'falcify_settings';

    public static function defaults() {
        return array(
            'saas_url'             => 'https://falcify.fr',
            'api_key'              => '',
            'enabled_post_types'   => array( 'page', 'post' ),
            'auto_inject'          => 1,
            'button_position'      => 'before',
            'button_text_falc'     => __( 'Lire en FALC', 'falcify-connector' ),
            'button_text_normal'   => __( 'Lire la version normale', 'falcify-connector' ),
            'button_color'         => '#0b2a4a',
            'high_contrast'        => 0,
            'floating_button'      => 0,
            'builder_mode'         => 0,
            'content_selector'     => '',
            'load_assets_only_active' => 1,
            'strict_mode'          => 0,
            'show_pictos'          => 1,
            // Affichage des pictogrammes par contexte d'insertion
            // (granularité ajoutée en v2.5.2 — `show_pictos` reste la valeur
            // master/legacy pour les types de contenu non couverts ici).
            'show_pictos_pages'      => 1,
            'show_pictos_posts'      => 1,
            'show_pictos_shortcode'  => 1,
            // Personnalisation visuelle des pictogrammes (v2.6.3)
            // taille en px, couleur hex (vide = couleur du texte), espacement en px.
            'picto_size'             => '100',
            'picto_color'            => '',
            'picto_spacing'          => '20',
        );
    }

    public static function set_defaults() {
        if ( false === get_option( self::OPTION ) ) {
            update_option( self::OPTION, self::defaults() );
        }
    }

    public static function init() {
        add_action( 'admin_init', array( __CLASS__, 'register' ) );
    }

    public static function register() {
        register_setting( 'falcify_settings_group', self::OPTION, array(
            'type' => 'array',
            'sanitize_callback' => array( __CLASS__, 'sanitize' ),
            'default' => self::defaults(),
        ) );
    }

    /**
     * Onglet partiel : on conserve TOUTES les valeurs existantes et on ne met
     * à jour que les clés réellement présentes dans le formulaire soumis.
     * Les checkboxes sont gérées via un champ caché `__falcify_fields[]`
     * listant les checkboxes attendues sur le formulaire courant.
     */
    public static function sanitize( $input ) {
        $out = self::get();
        if ( ! is_array( $input ) ) return $out;

        $declared = isset( $input['__falcify_fields'] ) && is_array( $input['__falcify_fields'] )
            ? array_map( 'sanitize_key', $input['__falcify_fields'] )
            : array();

        // saas_url est verrouillé côté plugin
        $out['saas_url'] = 'https://falcify.fr';
        if ( array_key_exists( 'api_key', $input ) ) {
            $out['api_key'] = sanitize_text_field( $input['api_key'] );
        }
        if ( array_key_exists( 'enabled_post_types', $input ) || in_array( 'enabled_post_types', $declared, true ) ) {
            $val = isset( $input['enabled_post_types'] ) && is_array( $input['enabled_post_types'] ) ? $input['enabled_post_types'] : array();
            $out['enabled_post_types'] = array_map( 'sanitize_key', $val );
        }
        if ( array_key_exists( 'button_position', $input ) ) {
            $allowed = array( 'before', 'after', 'both', 'floating' );
            if ( in_array( $input['button_position'], $allowed, true ) ) {
                $out['button_position'] = $input['button_position'];
            }
        }
        foreach ( array( 'button_text_falc', 'button_text_normal', 'content_selector' ) as $k ) {
            if ( array_key_exists( $k, $input ) ) {
                $out[ $k ] = sanitize_text_field( $input[ $k ] );
            }
        }
        if ( array_key_exists( 'button_color', $input ) ) {
            $c = sanitize_hex_color( $input['button_color'] );
            if ( $c ) $out['button_color'] = $c;
        }
        // Pictogrammes : taille (px) et espacement (px) — clamp dans une plage sûre
        // pour préserver l'accessibilité (lisibilité minimale, pas de débordement).
        foreach ( array( 'picto_size' => array(40, 200), 'picto_spacing' => array(0, 60) ) as $k => $bounds ) {
            if ( array_key_exists( $k, $input ) ) {
                $v = str_replace( ',', '.', (string) $input[ $k ] );
                if ( is_numeric( $v ) ) {
                    $f = (float) $v;
                    if ( $f < $bounds[0] ) $f = $bounds[0];
                    if ( $f > $bounds[1] ) $f = $bounds[1];
                    $out[ $k ] = number_format( $f, 2, '.', '' );
                }
            }
        }
        if ( array_key_exists( 'picto_color', $input ) ) {
            $raw = trim( (string) $input['picto_color'] );
            if ( $raw === '' ) {
                $out['picto_color'] = '';
            } else {
                $c = sanitize_hex_color( $raw );
                if ( $c ) $out['picto_color'] = $c;
            }
        }
        // Checkboxes : utiliser la liste déclarée pour distinguer "absent" de "décoché"
        foreach ( array(
            'auto_inject', 'high_contrast', 'floating_button', 'builder_mode',
            'load_assets_only_active', 'strict_mode', 'show_pictos',
            'show_pictos_pages', 'show_pictos_posts', 'show_pictos_shortcode',
        ) as $k ) {
            if ( in_array( $k, $declared, true ) ) {
                $out[ $k ] = ! empty( $input[ $k ] ) ? 1 : 0;
            }
        }
        return $out;
    }

    public static function get() {
        $opts = get_option( self::OPTION, array() );
        return wp_parse_args( is_array( $opts ) ? $opts : array(), self::defaults() );
    }

    public static function get_value( $key ) {
        $o = self::get();
        return isset( $o[ $key ] ) ? $o[ $key ] : null;
    }

    /**
     * Génère les <input hidden> listant les checkboxes du formulaire courant
     * pour que sanitize() sache lesquelles ont été soumises (même décochées).
     */
    public static function declare_fields( array $checkbox_keys ) {
        $opt = esc_attr( self::OPTION );
        $allowed = array( 'input' => array( 'type' => array(), 'name' => array(), 'value' => array() ) );
        $html = '';
        foreach ( $checkbox_keys as $k ) {
            $html .= '<input type="hidden" name="' . $opt . '[__falcify_fields][]" value="' . esc_attr( $k ) . '">';
        }
        return wp_kses( $html, $allowed );
    }
}
