<?php

declare(strict_types=1);

namespace App\Controllers\Admin;

use App\Core\Auth;
use App\Core\MailService;
use App\Core\Recaptcha;
use App\Core\Request;
use App\Core\Response;
use App\Core\Session;
use App\Core\Settings;
use App\Core\View;

final class SettingsController extends AdminController
{
    /** Champ => type de traitement. */
    private const FIELDS = [
        'site_title'                => 'text',
        'tagline'                   => 'text',
        'image_author'              => 'text',
        'default_lang'              => 'lang',
        'contact_enabled'           => 'bool',
        'menu_show_contact'         => 'bool',
        'contact_email'             => 'text',
        'mail_from_email'           => 'text',
        'mail_from_name'            => 'text',
        'mail_smtp_host'            => 'text',
        'mail_smtp_port'            => 'text',
        'mail_smtp_user'            => 'text',
        'mail_smtp_pass'            => 'text',
        'mail_smtp_secure'          => 'text',
        'contact_recaptcha_enabled' => 'bool',
        'recaptcha_site_key'        => 'text',
        'recaptcha_secret_key'      => 'text',
        'seo_noindex'               => 'bool',
        'gallery_lazyload_enabled'  => 'bool',
        'menu_mode'                 => 'menu_mode',
        'nav_breakpoint'            => 'int',
        'galleries_label'           => 'text',
        'gallery_batch_size'        => 'int',
        'upload_min_landscape_w'    => 'int',
        'upload_min_landscape_h'    => 'int',
        'upload_min_portrait_w'     => 'int',
        'upload_min_portrait_h'     => 'int',
        'theme_color_bg'              => 'color',
        'theme_color_text'            => 'color',
        'theme_color_gallery_title'   => 'color',
        'theme_color_breadcrumb_link'    => 'color',
        'theme_color_breadcrumb_current' => 'color',
        'theme_color_link'            => 'color',
        'theme_color_link_hover'      => 'color',
        'theme_color_header_bg'       => 'color',
        'theme_color_header_border'   => 'color',
        'theme_color_menu_text'       => 'color',
        'theme_color_accent'          => 'color',
        'theme_color_submenu_bg'      => 'color',
        'theme_color_submenu_hover_bg' => 'color',
        'theme_color_footer_bg'       => 'color',
        'theme_color_hover'           => 'color',
    ];

    /** Plancher par champ entier (ratio 3:2 basé sur 1920×1280). Défaut : 1. */
    private const INT_MIN = [
        'upload_min_landscape_w' => 1000,
        'upload_min_landscape_h' => 667,
        'upload_min_portrait_w'  => 667,
        'upload_min_portrait_h'  => 1000,
    ];

    private const DEFAULTS = [
        'site_title'                => 'DANIEL TIZIANI',
        'tagline'                   => 'Simple, fort & juste',
        'image_author'              => '',
        'default_lang'              => 'fr',
        'contact_enabled'           => '0',
        'menu_show_contact'         => '1',
        'contact_email'             => '',
        'mail_from_email'           => '',
        'mail_from_name'            => '',
        'mail_smtp_host'            => '',
        'mail_smtp_port'            => '',
        'mail_smtp_user'            => '',
        'mail_smtp_pass'            => '',
        'mail_smtp_secure'          => 'tls',
        'contact_recaptcha_enabled' => '0',
        'recaptcha_site_key'        => '',
        'recaptcha_secret_key'      => '',
        'seo_noindex'               => '0',
        'gallery_lazyload_enabled'  => '1',
        'menu_mode'                 => 'offcanvas',
        'nav_breakpoint'            => '992',
        'galleries_label'           => 'Galeries',
        'gallery_batch_size'        => '12',
        'upload_min_landscape_w'    => '1920',
        'upload_min_landscape_h'    => '1280',
        'upload_min_portrait_w'     => '1280',
        'upload_min_portrait_h'     => '1920',
        'theme_color_bg'              => '#e6e6e6',
        'theme_color_text'            => '#7a7a7a',
        'theme_color_gallery_title'   => '#5a5a5a',
        'theme_color_breadcrumb_link'    => '#7a7a7a',
        'theme_color_breadcrumb_current' => '#5a5a5a',
        'theme_color_link'            => '#337ab7',
        'theme_color_link_hover'      => '#23527c',
        'theme_color_header_bg'       => '#a6a8a9',
        'theme_color_header_border'   => '#8f9193',
        'theme_color_menu_text'       => '#444444',
        'theme_color_accent'          => '#e2041a',
        'theme_color_submenu_bg'      => '#ffffff',
        'theme_color_submenu_hover_bg' => '#f4f4f4',
        'theme_color_footer_bg'       => '#a6a8a9',
        'theme_color_hover'           => '#4e4e4e',
    ];

    /** @param array<string,string> $params */
    public function edit(Request $request, array $params): Response
    {
        if ($r = $this->guard()) {
            return $r;
        }

        $values = [];
        foreach (self::FIELDS as $key => $type) {
            $values[$key] = (string) Settings::get($key, self::DEFAULTS[$key]);
        }

        return Response::html(View::render('admin/settings/index', [
            'pageTitle' => 'Paramètres',
            'v'         => $values,
            'flash'     => Session::pull('flash'),
        ], 'layouts/admin'));
    }

    /** @param array<string,string> $params */
    public function update(Request $request, array $params): Response
    {
        if ($r = $this->guard()) {
            return $r;
        }
        if (!$this->csrfValid($request)) {
            return Response::redirect(base_url('admin/settings'));
        }

        foreach (self::FIELDS as $key => $type) {
            $raw = $request->input($key);
            switch ($type) {
                case 'text':
                    Settings::set($key, trim((string) $raw));
                    break;
                case 'lang':
                    $val = (string) $raw;
                    Settings::set($key, in_array($val, ['fr', 'en'], true) ? $val : 'fr');
                    break;
                case 'menu_mode':
                    $val = (string) $raw;
                    Settings::set($key, in_array($val, ['offcanvas', 'collapse'], true) ? $val : 'offcanvas');
                    break;
                case 'bool':
                    Settings::set($key, $raw ? '1' : '0');
                    break;
                case 'int':
                    Settings::set($key, (string) max(self::INT_MIN[$key] ?? 1, (int) $raw));
                    break;
                case 'color':
                    $val = (string) $raw;
                    if (preg_match('/^#([0-9a-f]{3}|[0-9a-f]{6})$/i', $val) === 1) {
                        Settings::set($key, $val);
                    }
                    break;
            }
        }

        // Sécurité : reCAPTCHA ne peut pas rester activé sans clés valides (réglages ou config).
        if ((string) Settings::get('contact_recaptcha_enabled', '0') === '1' && !Recaptcha::isActive()) {
            Settings::set('contact_recaptcha_enabled', '0');
            Session::set('flash', 'reCAPTCHA non activé : renseignez la clé du site et la clé secrète.');
            return Response::redirect(base_url('admin/settings'));
        }

        Session::set('flash', 'Paramètres enregistrés.');
        return Response::redirect(base_url('admin/settings'));
    }

    /**
     * Envoi d'un e-mail de test avec la configuration enregistrée (AJAX, JSON).
     * @param array<string,string> $params
     */
    public function testEmail(Request $request, array $params): Response
    {
        if (!Auth::check()) {
            return $this->json(['success' => false, 'message' => 'Session expirée.'], 401);
        }
        if (!$this->csrfValid($request)) {
            return $this->json(['success' => false, 'message' => 'Jeton invalide, rechargez la page.'], 400);
        }

        $to = trim((string) Settings::get('contact_email', ''));
        if ($to === '') {
            return $this->json(['success' => false, 'message' => 'Renseignez d\'abord l\'email de réception, puis enregistrez.']);
        }

        $ok = MailService::send(
            'Test — configuration e-mail du site',
            "Ceci est un e-mail de test envoyé depuis l'administration.\n\n"
            . "Si vous le recevez, l'envoi des messages du formulaire de contact fonctionne.",
            $to,
            'Test'
        );

        return $ok
            ? $this->json(['success' => true, 'message' => 'E-mail de test envoyé à ' . $to . '.'])
            : $this->json(['success' => false, 'message' => 'Échec de l\'envoi. Vérifiez les réglages SMTP (et enregistrez avant de tester).']);
    }

    /** @param array<string,mixed> $data */
    private function json(array $data, int $code = 200): Response
    {
        return new Response((string) json_encode($data), $code, ['Content-Type' => 'application/json']);
    }
}
