<?php

declare(strict_types=1);

require_once __DIR__ . DIRECTORY_SEPARATOR . 'admin_member_auth.php';
require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_ui_settings.php';

/**
 * 後台首頁用：彙整店家、會員、流量與待辦提醒。
 *
 * @return array{
 *   db_ok:bool,
 *   db_err:?string,
 *   admin_label:string,
 *   branding:array{title_main:string,title_sub:string},
 *   template:string,
 *   template_source:string,
 *   stores:array{ok:bool,missing:bool,count:?int,last_synced:?string,max_unix:?int,err:?string},
 *   members:array{ok:bool,missing:bool,overview:?array<string,mixed>,err:?string},
 *   traffic:array{visit_log:bool,visit_rows:?int,visitor:?array<string,mixed>,err:?string},
 *   alerts:list<array{level:string,text:string,href:?string,label:?string}>,
 *   quick_links:list<array{id:string,href:string,label:string}>
 * }
 */
function fate_admin_dashboard_collect(?PDO $pdo): array
{
    $srcHint = defined('FATE_TEMPLATE_SOURCE') ? (string) FATE_TEMPLATE_SOURCE : '';
    $srcShort = $srcHint === 'env' ? '環境變數' : ($srcHint === 'file' ? '後台設定' : ($srcHint === 'custom' ? '外部' : '預設'));

    $out = [
        'db_ok' => $pdo instanceof PDO,
        'db_err' => $pdo instanceof PDO ? null : '未取得資料庫連線',
        'admin_label' => function_exists('fate_admin_member_display_label') ? fate_admin_member_display_label() : '管理員',
        'branding' => fate_public_site_branding(),
        'template' => defined('FATE_TEMPLATE') ? (string) FATE_TEMPLATE : 'default',
        'template_source' => $srcShort,
        'stores' => ['ok' => false, 'missing' => false, 'count' => null, 'last_synced' => null, 'max_unix' => null, 'err' => null],
        'members' => ['ok' => false, 'missing' => false, 'overview' => null, 'err' => null],
        'traffic' => ['visit_log' => false, 'visit_rows' => null, 'visitor' => null, 'err' => null],
        'alerts' => [],
        'quick_links' => fate_admin_dashboard_quick_links(),
    ];

    if (!$pdo instanceof PDO) {
        $out['alerts'][] = [
            'level' => 'bad',
            'text' => '無法連線資料庫，下列數字可能無法顯示。',
            'href' => null,
            'label' => null,
        ];

        return $out;
    }

    // 店家快照
    try {
        $out['stores']['count'] = (int) $pdo->query('SELECT COUNT(*) FROM spa_store_snapshots')->fetchColumn();
        $row = $pdo->query("SELECT MAX(synced_at) AS s, MAX(source_data_as_of_unix) AS u FROM spa_store_snapshots WHERE source_type = 'api'")->fetch(PDO::FETCH_ASSOC);
        if (is_array($row)) {
            $out['stores']['last_synced'] = isset($row['s']) && $row['s'] !== null ? (string) $row['s'] : null;
            $u = isset($row['u']) ? (int) $row['u'] : 0;
            $out['stores']['max_unix'] = $u > 0 ? $u : null;
        }
        $out['stores']['ok'] = true;
    } catch (Throwable $e) {
        if (str_contains($e->getMessage(), 'spa_store_snapshots') || str_contains($e->getMessage(), "doesn't exist")) {
            $out['stores']['missing'] = true;
            $out['alerts'][] = [
                'level' => 'warn',
                'text' => '尚未建立店家快照表 spa_store_snapshots。',
                'href' => 'setup_snapshots_table.php',
                'label' => '一鍵建表',
            ];
        } else {
            $out['stores']['err'] = $e->getMessage();
        }
    }

    // 會員
    require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_admin_members.php';

    if (!fate_admin_members_table_exists($pdo)) {
        $out['members']['missing'] = true;
        $out['alerts'][] = [
            'level' => 'warn',
            'text' => '找不到會員表 ' . (fate_admin_member_auth_ready() ? FATE_MEMBER_DATABASE . '.' . FATE_MEMBER_TABLE : '') . '，請匯入 fate/sql/install.sql 建立。',
        ];
    } else {
        try {
            $out['members']['overview'] = fate_admin_members_overview($pdo);
            $out['members']['ok'] = true;
        } catch (Throwable $e) {
            $out['members']['err'] = $e->getMessage();
        }
    }

    // 流量
    require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_visit_log.php';
    require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_page_counter.php';
    require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_visitor_tracker.php';

    $out['traffic']['visit_log'] = fate_visit_log_table_exists($pdo);
    if (!$out['traffic']['visit_log']) {
        $out['alerts'][] = [
            'level' => 'warn',
            'text' => '瀏覽紀錄表 fate_visit_log 未建立，前台頁腳無法顯示瀏覽次數。',
            'href' => 'stats.php',
            'label' => '瀏覽統計',
        ];
    } else {
        try {
            $out['traffic']['visit_rows'] = fate_page_hit_stats_total_hits($pdo);
            $out['traffic']['visitor'] = fate_visitor_admin_snapshot($pdo);
        } catch (Throwable $e) {
            $out['traffic']['err'] = $e->getMessage();
        }
    }

    if ($out['stores']['ok'] && ($out['stores']['count'] ?? 0) === 0) {
        $out['alerts'][] = [
            'level' => 'warn',
            'text' => '尚無店家快照，請執行同步或新增店家。',
            'href' => 'sync.php',
            'label' => '同步店家',
        ];
    }

    $overview = is_array($out['members']['overview'] ?? null) ? $out['members']['overview'] : [];
    if (!empty($overview['features']['manual_review']) && (int) ($overview['review_pending'] ?? 0) > 0) {
        $n = (int) $overview['review_pending'];
        array_unshift($out['alerts'], [
            'level' => 'warn',
            'text' => $n . ' 位會員待人工審核。',
            'href' => 'members.php?review=pending',
            'label' => '前往審核',
        ]);
    }
    if ($out['stores']['ok']) {
        try {
            $pendingStoreCount = (int) $pdo->query("SELECT COUNT(*) FROM spa_store_snapshots WHERE is_approved = 0 AND source_type = 'manual'")->fetchColumn();
            if ($pendingStoreCount > 0) {
                array_unshift($out['alerts'], [
                    'level' => 'warn',
                    'text' => $pendingStoreCount . ' 間推薦店家待審核。',
                    'href' => 'approve_stores.php',
                    'label' => '前往審核',
                ]);
            }
        } catch (Throwable $e) {
        }
    }
    if (!empty($overview['features']['email_verified']) && (int) ($overview['email_pending'] ?? 0) > 0) {
        $n = (int) $overview['email_pending'];
        array_unshift($out['alerts'], [
            'level' => 'warn',
            'text' => $n . ' 位會員信箱待驗證。',
            'href' => 'members.php?verify=email_pending',
            'label' => '查看列表',
        ]);
    }

    return $out;
}

/**
 * 首頁統計卡。
 *
 * @param array<string,mixed> $dash
 * @return list<array{id:string,icon:string,label:string,value:string,hint:string,href:string,tone:string}>
 */
function fate_admin_dashboard_stat_cards(array $dash): array
{
    $fmt = static fn (int $v): string => number_format($v);
    $cards = [];

    $stores = is_array($dash['stores'] ?? null) ? $dash['stores'] : [];
    if (!empty($stores['missing'])) {
        $cards[] = [
            'id' => 'stores',
            'icon' => 'stores',
            'label' => '店家快照',
            'value' => '未建表',
            'hint' => '需先建立 spa_store_snapshots',
            'href' => 'setup_snapshots_table.php',
            'tone' => 'warn',
        ];
    } elseif (!empty($stores['ok']) && isset($stores['count'])) {
        $hint = !empty($stores['last_synced']) ? '最近同步 ' . (string) $stores['last_synced'] : '尚未同步';
        $cards[] = [
            'id' => 'stores',
            'icon' => 'stores',
            'label' => '店家快照',
            'value' => $fmt((int) $stores['count']),
            'hint' => $hint,
            'href' => 'sync.php',
            'tone' => ((int) $stores['count'] > 0) ? 'ok' : 'warn',
        ];
    }

    $members = is_array($dash['members'] ?? null) ? $dash['members'] : [];
    $overview = is_array($members['overview'] ?? null) ? $members['overview'] : [];
    if (!empty($members['missing'])) {
        $cards[] = [
            'id' => 'members',
            'icon' => 'members',
            'label' => '會員',
            'value' => '未建表',
            'hint' => '請匯入 install.sql',
            'href' => 'members.php',
            'tone' => 'warn',
        ];
    } elseif (!empty($members['ok']) && $overview !== []) {
        $total = (int) ($overview['total'] ?? 0);
        $active = (int) ($overview['active'] ?? 0);
        $cards[] = [
            'id' => 'members',
            'icon' => 'members',
            'label' => '會員總數',
            'value' => $fmt($total),
            'hint' => '啟用 ' . $fmt($active),
            'href' => 'members.php',
            'tone' => 'ok',
        ];
        if (!empty($overview['features']['manual_review']) && ($overview['review_pending'] ?? null) !== null) {
            $pending = (int) $overview['review_pending'];
            $cards[] = [
                'id' => 'review',
                'icon' => 'review',
                'label' => '待審核',
                'value' => $fmt($pending),
                'hint' => $pending > 0 ? '須人工通過後可登入' : '目前無待辦',
                'href' => 'members.php?review=pending',
                'tone' => $pending > 0 ? 'warn' : 'muted',
            ];
        }
        if (!empty($overview['features']['email_verified']) && ($overview['email_pending'] ?? null) !== null) {
            $ev = (int) $overview['email_pending'];
            $cards[] = [
                'id' => 'email',
                'icon' => 'email',
                'label' => '待驗證信箱',
                'value' => $fmt($ev),
                'hint' => $ev > 0 ? '可於會員列表標記驗證' : '無待驗證',
                'href' => 'members.php?verify=email_pending',
                'tone' => $ev > 0 ? 'accent' : 'muted',
            ];
        }
    }

    $traffic = is_array($dash['traffic'] ?? null) ? $dash['traffic'] : [];
    $visitor = is_array($traffic['visitor'] ?? null) ? $traffic['visitor'] : null;
    if (empty($traffic['visit_log'])) {
        $cards[] = [
            'id' => 'traffic',
            'icon' => 'traffic',
            'label' => '瀏覽紀錄',
            'value' => '未建表',
            'hint' => '於瀏覽統計建立',
            'href' => 'stats.php',
            'tone' => 'muted',
        ];
    } else {
        if (isset($traffic['visit_rows'])) {
            $cards[] = [
                'id' => 'hits',
                'icon' => 'hits',
                'label' => '瀏覽紀錄',
                'value' => $fmt((int) $traffic['visit_rows']),
                'hint' => '累計頁面瀏覽次數',
                'href' => 'stats.php',
                'tone' => 'ok',
            ];
        }
        if ($visitor !== null) {
            $cards[] = [
                'id' => 'visitors',
                'icon' => 'visitors',
                'label' => '今日訪客',
                'value' => $fmt((int) ($visitor['today_unique'] ?? 0)),
                'hint' => '在線 ' . $fmt((int) ($visitor['online_now'] ?? 0)),
                'href' => 'stats.php',
                'tone' => 'accent',
            ];
        }
    }

    return $cards;
}

/**
 * @return list<array{title:string,items:list<array{id:string,href:string,label:string,desc:string}>}>
 */
function fate_admin_dashboard_action_groups(): array
{
    require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_plugins.php';
    $hasPlugins = fate_plugins_feature_available();
    $siteModesDesc = $hasPlugins
        ? '一鍵切換店家／技師／評論／討論區'
        : '一鍵切換店家／技師／評論';

    $groups = [
        [
            'title' => '店家與內容',
            'items' => [
                ['id' => 'sync', 'href' => 'sync.php', 'label' => '同步店家', 'desc' => '從新手村更新快照'],
                ['id' => 'add_store', 'href' => 'add_store.php', 'label' => '新增店家', 'desc' => '手動建立並寫入快照'],
                ['id' => 'approve_stores', 'href' => 'approve_stores.php', 'label' => '審核推薦店家', 'desc' => '審核會員推薦的店家'],
                ['id' => 'masseurs', 'href' => 'masseurs.php', 'label' => '推薦技師', 'desc' => '預設頭像與推薦設定'],
                ['id' => 'site_modes', 'href' => 'site_modes.php', 'label' => '功能快速設定', 'desc' => $siteModesDesc],
            ],
        ],
        [
            'title' => '會員與訊息',
            'items' => [
                ['id' => 'members', 'href' => 'members.php', 'label' => '會員管理', 'desc' => '審核、停權、信箱驗證'],
                ['id' => 'email', 'href' => 'email_settings.php', 'label' => 'Email 驗證', 'desc' => '反向 IMAP 回寄驗證'],
                ['id' => 'ncoin', 'href' => 'ncoin.php', 'label' => '站內貨幣設定/紀錄', 'desc' => '轉帳、獎勵、發放與帳本'],
            ],
        ],
        [
            'title' => '站台與變現',
            'items' => [
                ['id' => 'template', 'href' => 'template.php', 'label' => '網站與模版', 'desc' => '站名、副標、社群連結'],
                ['id' => 'adsense', 'href' => 'adsense.php', 'label' => 'Google AdSense', 'desc' => '廣告代碼設定'],
                ['id' => 'stats', 'href' => 'stats.php', 'label' => '瀏覽統計', 'desc' => '訪客、在線、紀錄表'],
            ],
        ],
        [
            'title' => '整合',
            'items' => array_values(array_filter([
                ['id' => 'spa_api', 'href' => 'spa_api_key.php', 'label' => '新手村 API', 'desc' => '金鑰與連線狀態'],
                $hasPlugins
                    ? ['id' => 'plugins', 'href' => 'plugins.php', 'label' => '外掛管理', 'desc' => '啟用或停用已安裝的外掛']
                    : null,
                ['id' => 'site_modes', 'href' => 'site_modes.php', 'label' => '功能快速設定', 'desc' => $hasPlugins ? '四種預設模式一鍵套用' : '三種預設模式一鍵套用'],
            ])),
        ],
    ];

    return $groups;
}

/** @return list<array{id:string,href:string,label:string}> */
function fate_admin_dashboard_quick_links(): array
{
    require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_plugins.php';
    $items = [
        ['id' => 'sync', 'href' => 'sync.php', 'label' => '同步店家'],
        ['id' => 'add_store', 'href' => 'add_store.php', 'label' => '新增店家'],
        ['id' => 'approve_stores', 'href' => 'approve_stores.php', 'label' => '審核推薦店家'],
        ['id' => 'members', 'href' => 'members.php', 'label' => '會員管理'],
        ['id' => 'stats', 'href' => 'stats.php', 'label' => '瀏覽統計'],
        ['id' => 'template', 'href' => 'template.php', 'label' => '網站與模版'],
        ['id' => 'email', 'href' => 'email_settings.php', 'label' => 'Email 驗證'],
        ['id' => 'spa_api', 'href' => 'spa_api_key.php', 'label' => '新手村 API'],
        ['id' => 'adsense', 'href' => 'adsense.php', 'label' => 'Google AdSense'],
        ['id' => 'site_modes', 'href' => 'site_modes.php', 'label' => '功能快速設定'],
    ];
    if (fate_plugins_feature_available()) {
        $items[] = ['id' => 'plugins', 'href' => 'plugins.php', 'label' => '外掛管理'];
    }

    return $items;
}

/**
 * 首頁一行摘要（緊湊）。
 *
 * @param array<string,mixed> $dash
 * @return list<string>
 */
function fate_admin_dashboard_summary_segments(array $dash): array
{
    $fmt = static fn (int $v): string => number_format($v);
    $parts = [];

    $stores = is_array($dash['stores'] ?? null) ? $dash['stores'] : [];
    if (!empty($stores['missing'])) {
        $parts[] = '店家：表未建立';
    } elseif (!empty($stores['ok']) && isset($stores['count'])) {
        $line = '店家 ' . $fmt((int) $stores['count']) . ' 筆';
        if (!empty($stores['last_synced'])) {
            $line .= '，最近同步 ' . (string) $stores['last_synced'];
        }
        $parts[] = $line;
    } elseif (!empty($stores['err'])) {
        $parts[] = '店家：讀取失敗';
    }

    $members = is_array($dash['members'] ?? null) ? $dash['members'] : [];
    if (!empty($members['missing'])) {
        $parts[] = '會員：表未建立';
    } elseif (!empty($members['overview']) && is_array($members['overview'])) {
        require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_admin_members.php';
        foreach (fate_admin_members_summary_segments($members['overview']) as $seg) {
            $parts[] = $seg;
        }
    } elseif (!empty($members['err'])) {
        $parts[] = '會員：讀取失敗';
    }

    $traffic = is_array($dash['traffic'] ?? null) ? $dash['traffic'] : [];
    if (empty($traffic['visit_log'])) {
        $parts[] = '流量：瀏覽紀錄未建立';
    } elseif (isset($traffic['visit_rows'])) {
        $line = '瀏覽紀錄 ' . $fmt((int) $traffic['visit_rows']) . ' 筆';
        $visitor = is_array($traffic['visitor'] ?? null) ? $traffic['visitor'] : null;
        if ($visitor !== null) {
            $line .= sprintf(
                '；今日訪客 %s、在線 %s',
                $fmt((int) ($visitor['today_unique'] ?? 0)),
                $fmt((int) ($visitor['online_now'] ?? 0))
            );
        }
        $parts[] = $line;
    }

    $parts[] = sprintf(
        '模版 %s（%s）',
        (string) ($dash['template'] ?? 'default'),
        (string) ($dash['template_source'] ?? '')
    );

    return $parts;
}

/**
 * @param array<string,mixed> $dash
 */
function fate_admin_dashboard_template_source_label(array $dash): string
{
    return (string) ($dash['template_source'] ?? '預設');
}
