<?php

namespace App\Support;

use App\Models\SiteSetting;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Schema;

/**
 * Configurações visuais e institucionais do site, editáveis pelo master.
 *
 * Ficam em banco (tabela chave/valor) e são mantidas em cache: são lidas em
 * toda requisição, para montar cabeçalho, logo e paleta de cores.
 */
class SiteSettings
{
    private const CACHE_KEY = 'site_settings';

    /** @var array<string, string|null>|null */
    private ?array $valores = null;

    /**
     * Valores de fábrica. Também servem de lista branca: só estas chaves
     * são aceitas na gravação.
     *
     * @return array<string, string|null>
     */
    public static function padroes(): array
    {
        return [
            // Identidade
            'site_nome' => config('app.name'),
            'site_descricao' => 'Monitor de XML · SEFAZ',
            'cor_primaria' => '#215a68',
            'logo_path' => null,
            'logo_claro_path' => null,
            'favicon_path' => null,

            // Tela de login e página inicial
            'login_titulo' => 'Todo XML de compra da sua empresa, baixado sozinho.',
            'login_subtitulo' => 'O monitor consulta a SEFAZ com o seu certificado A1 e arquiva cada NF-e emitida contra o seu CNPJ — sem digitar chave, sem captcha, sem pedir XML ao fornecedor.',
            'login_destaques' => "Busca automática a cada ciclo, direto do Ambiente Nacional\nResumo e XML completo, com eventos de cancelamento e CC-e\nDownload individual ou pacote .zip por competência\nGuarda dos arquivos pelos 5 anos exigidos pelo fisco",
            'login_permitir_cadastro' => '1',

            // Desenvolvedor
            'dev_nome' => null,
            'dev_site' => null,
            'dev_email' => null,
            'dev_telefone' => null,
            'dev_creditos' => null,

            // Suporte ao cliente
            'suporte_email' => null,
            'suporte_telefone' => null,
            'suporte_whatsapp' => null,
        ];
    }

    /**
     * @return array<string, string|null>
     */
    public function todos(): array
    {
        if ($this->valores !== null) {
            return $this->valores;
        }

        return $this->valores = Cache::rememberForever(self::CACHE_KEY, function () {
            try {
                // Durante a instalação a tabela — ou o próprio banco — ainda
                // não existe. Os padrões mantêm a aplicação de pé até lá.
                if (! Schema::hasTable('site_settings')) {
                    return self::padroes();
                }

                return [...self::padroes(), ...SiteSetting::pluck('valor', 'chave')->all()];
            } catch (\Throwable) {
                return self::padroes();
            }
        });
    }

    public function get(string $chave, mixed $padrao = null): mixed
    {
        return $this->todos()[$chave] ?? $padrao;
    }

    public function bool(string $chave): bool
    {
        return filter_var($this->get($chave), FILTER_VALIDATE_BOOLEAN);
    }

    /**
     * Linhas não vazias de um campo multilinha (ex.: destaques do login).
     *
     * @return array<int, string>
     */
    public function linhas(string $chave): array
    {
        return collect(preg_split('/\R/', (string) $this->get($chave)))
            ->map(fn ($linha) => trim($linha))
            ->filter()
            ->values()
            ->all();
    }

    /**
     * @param  array<string, string|null>  $dados
     */
    public function salvar(array $dados): void
    {
        $permitidas = array_keys(self::padroes());

        foreach ($dados as $chave => $valor) {
            if (! in_array($chave, $permitidas, true)) {
                continue;
            }

            SiteSetting::updateOrCreate(['chave' => $chave], ['valor' => $valor]);
        }

        $this->limparCache();
    }

    public function limparCache(): void
    {
        $this->valores = null;
        Cache::forget(self::CACHE_KEY);
    }

    /** Nome exibido no cabeçalho, abas e rodapés. */
    public function nome(): string
    {
        return $this->get('site_nome') ?: config('app.name');
    }

    /**
     * Paleta derivada da cor primária, pronta para virar CSS custom properties.
     *
     * @return array<int, string>
     */
    public function paleta(): array
    {
        $cor = (string) $this->get('cor_primaria');

        return Paleta::gerar(Paleta::hexValido($cor) ? $cor : self::padroes()['cor_primaria']);
    }
}
