<?php

declare(strict_types=1);

/**
 * 後台 UI 持久設定（JSON）。
 * 路徑：fate/data/fate_ui_settings.json
 *
 * 欄位：template、網站名稱／副標、社群連結（LINE、LINE 社群、X、Telegram、其它）。
 */

function fate_ui_settings_path(): string
{
    return dirname(__DIR__) . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'fate_ui_settings.json';
}

/** @return array<string, mixed> */
function fate_ui_settings_default(): array
{
    return [
        'template' => 'default',
        'site_display_name' => '',
        'site_display_tagline' => '',
        'url_line' => '',
        'url_line_community' => '',
        'url_x' => '',
        'url_telegram' => '',
        'label_other' => '',
        'url_other' => '',
    ];
}

/** @return array<string, mixed> */
function fate_ui_settings_read(): array
{
    $p = fate_ui_settings_path();
    if (!is_file($p)) {
        return [];
    }
    $raw = file_get_contents($p);
    if ($raw === false || $raw === '') {
        return [];
    }
    $j = json_decode($raw, true);

    return is_array($j) ? $j : [];
}

function fate_ui_validate_template_id(string $raw): ?string
{
    $tid = strtolower(trim($raw));

    return preg_match('/^[a-z0-9_-]{1,64}$/', $tid) === 1 ? $tid : null;
}

function fate_ui_sanitize_short_text(?string $raw, int $maxLen): string
{
    $s = trim((string) $raw);
    if ($s === '') {
        return '';
    }
    if (function_exists('mb_substr')) {
        return mb_substr($s, 0, $maxLen);
    }

    return strlen($s) > $maxLen ? substr($s, 0, $maxLen) : $s;
}

/** 允許空字串；非空須為合理 http(s) URL（自動補 https://）。 */
function fate_ui_sanitize_optional_url(?string $raw): string
{
    $s = trim((string) $raw);
    if ($s === '') {
        return '';
    }
    if (strlen($s) > 2048) {
        return '';
    }
    if (!preg_match('#^https?://#i', $s)) {
        $s = 'https://' . ltrim($s, '/');
    }
    if (filter_var($s, FILTER_VALIDATE_URL) === false) {
        return '';
    }

    return $s;
}

/**
 * 合併檔案與預設值並清理所有已知鍵。
 *
 * @param array<string, mixed> $merge 覆寫（通常為檔案內容或 POST 合併結果）
 * @return array<string, string>
 */
function fate_ui_settings_normalize(array $merge): array
{
    $d = fate_ui_settings_default();
    foreach ($d as $k => $_) {
        if (array_key_exists($k, $merge)) {
            $d[$k] = $merge[$k];
        }
    }

    $tid = fate_ui_validate_template_id((string) $d['template']);
    $d['template'] = $tid ?? 'default';

    $d['site_display_name'] = fate_ui_sanitize_short_text(is_string($d['site_display_name']) ? $d['site_display_name'] : '', 80);
    $d['site_display_tagline'] = fate_ui_sanitize_short_text(is_string($d['site_display_tagline']) ? $d['site_display_tagline'] : '', 80);

    foreach (['url_line', 'url_line_community', 'url_x', 'url_telegram', 'url_other'] as $uk) {
        $d[$uk] = fate_ui_sanitize_optional_url(is_string($d[$uk]) ? $d[$uk] : '');
    }
    $d['label_other'] = fate_ui_sanitize_short_text(is_string($d['label_other']) ? $d['label_other'] : '', 64);

    /** @var array<string, string> */
    return $d;
}

/** @param array<string, mixed> $normalized fate_ui_settings_normalize の結果 */
function fate_ui_settings_persist(array $normalized): bool
{
    $dir = dirname(fate_ui_settings_path());
    if (!is_dir($dir)) {
        if (!@mkdir($dir, 0775, true) && !is_dir($dir)) {
            return false;
        }
    }
    $payload = json_encode($normalized, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
    if ($payload === false) {
        return false;
    }

    return file_put_contents(fate_ui_settings_path(), $payload . "\n", LOCK_EX) !== false;
}

/**
 * 前台／模版用：網站抬頭與連結（空欄位時沿用預設「FATE」「店家探索」）。
 *
 * @return array{
 *   title_main:string,
 *   title_sub:string,
 *   url_line:string,
 *   url_line_community:string,
 *   url_x:string,
 *   url_telegram:string,
 *   label_other:string,
 *   url_other:string,
 *   has_social:bool
 * }
 */
function fate_public_site_branding(): array
{
    $n = fate_ui_settings_normalize(fate_ui_settings_read());
    $main = $n['site_display_name'] !== '' ? $n['site_display_name'] : 'FATE';
    $sub = $n['site_display_tagline'] !== '' ? $n['site_display_tagline'] : '店家探索';
    $hasSocial = $n['url_line'] !== '' || $n['url_line_community'] !== '' || $n['url_x'] !== ''
        || $n['url_telegram'] !== '' || $n['url_other'] !== '';

    return [
        'title_main' => $main,
        'title_sub' => $sub,
        'url_line' => $n['url_line'],
        'url_line_community' => $n['url_line_community'],
        'url_x' => $n['url_x'],
        'url_telegram' => $n['url_telegram'],
        'label_other' => $n['label_other'],
        'url_other' => $n['url_other'],
        'has_social' => $hasSocial,
    ];
}

/** @param list<string> $allowedIds */
function fate_ui_settings_save_template(string $id, array $allowedIds): bool
{
    $v = fate_ui_validate_template_id($id);
    if ($v === null || !in_array($v, $allowedIds, true)) {
        return false;
    }
    $cur = fate_ui_settings_normalize(fate_ui_settings_read());
    $cur['template'] = $v;

    return fate_ui_settings_persist($cur);
}

/**
 * 僅更新網站名稱與社群連結（保留 template）。
 *
 * @param array<string, mixed> $patch 可含 site_display_name、url_line …
 */
function fate_ui_settings_save_site_patch(array $patch): bool
{
    $cur = fate_ui_settings_normalize(fate_ui_settings_read());
    foreach (
        [
            'site_display_name',
            'site_display_tagline',
            'url_line',
            'url_line_community',
            'url_x',
            'url_telegram',
            'label_other',
            'url_other',
        ] as $k
    ) {
        if (array_key_exists($k, $patch)) {
            $cur[$k] = $patch[$k];
        }
    }

    return fate_ui_settings_persist(fate_ui_settings_normalize($cur));
}

/**
 * 後台一次儲存：網站設定 + 可選模版（模版由呼叫端驗證 allowedIds）。
 *
 * @param array<string, mixed> $sitePatch
 * @param list<string> $installedTemplateIds
 * @return array{ok:bool, error:?string}
 */
function fate_ui_settings_save_admin_post(array $sitePatch, ?string $templatePick, bool $skipTemplate, array $installedTemplateIds): array
{
    $cur = fate_ui_settings_normalize(fate_ui_settings_read());

    foreach (
        [
            'site_display_name',
            'site_display_tagline',
            'url_line',
            'url_line_community',
            'url_x',
            'url_telegram',
            'label_other',
            'url_other',
        ] as $k
    ) {
        if (array_key_exists($k, $sitePatch)) {
            $cur[$k] = $sitePatch[$k];
        }
    }

    if (!$skipTemplate) {
        $pick = $templatePick !== null ? trim($templatePick) : '';
        $v = fate_ui_validate_template_id($pick);
        if ($v === null || !in_array($v, $installedTemplateIds, true)) {
            return ['ok' => false, 'error' => '模版辨識名無效或未安裝。'];
        }
        $cur['template'] = $v;
    }

    if (!fate_ui_settings_persist(fate_ui_settings_normalize($cur))) {
        return ['ok' => false, 'error' => '無法寫入 fate/data/fate_ui_settings.json（請檢查目錄權限）。'];
    }

    return ['ok' => true, 'error' => null];
}
