<?php

declare(strict_types=1);

/**
 * 會員分級：
 *  - register   註冊會員（新帳號預設）
 *  - formal     正式會員（完成信箱驗證後自動升級，僅限 register → formal）
 *  - blacklist  黑名單（管理員設定；重新驗證信箱不會自動復活）
 *
 * 停權（active=0）與黑名單不同：停權無法登入；黑名單可登入但完成驗證後仍不得參與互動。
 */

require_once __DIR__ . DIRECTORY_SEPARATOR . 'admin_member_auth.php';

function fate_member_tier_values(): array
{
    return ['register', 'formal', 'blacklist'];
}

/** @return array<string, string> */
function fate_member_tier_labels(): array
{
    return [
        'register' => '註冊會員',
        'formal' => '正式會員',
        'blacklist' => '黑名單',
    ];
}

function fate_member_tier_normalize(?string $raw): string
{
    $t = strtolower(trim((string) $raw));
    if ($t === 'formal') {
        return 'formal';
    }
    if ($t === 'blacklist') {
        return 'blacklist';
    }

    return 'register';
}

function fate_member_tier_label(?string $tier): string
{
    $key = fate_member_tier_normalize($tier);
    $labels = fate_member_tier_labels();

    return $labels[$key] ?? $labels['register'];
}

function fate_member_tier_badge_class(?string $tier): string
{
    $key = fate_member_tier_normalize($tier);
    if ($key === 'formal') {
        return 'badge badge--ok';
    }
    if ($key === 'blacklist') {
        return 'badge badge--off';
    }

    return 'badge badge--member';
}

function fate_member_tier_column_exists(PDO $pdo): bool
{
    if (!function_exists('fate_members_table_has_column')) {
        require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_member_email.php';
    }

    return fate_members_table_has_column($pdo, 'MEMBER_TIER');
}

function fate_member_tier_bootstrap_schema(PDO $pdo): void
{
    static $done = false;
    if ($done || !fate_admin_member_auth_ready()) {
        return;
    }

    if (!function_exists('fate_members_table_has_column')) {
        require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_member_email.php';
    }
    fate_member_email_bootstrap_schema($pdo);

    if (!fate_member_tier_column_exists($pdo)) {
        $db = FATE_MEMBER_DATABASE;
        $tbl = FATE_MEMBER_TABLE;
        $dbEsc = str_replace('`', '``', $db);
        $tblEsc = str_replace('`', '``', $tbl);

        try {
            $after = fate_members_table_has_column($pdo, 'EMAIL_VERIFIED_AT')
                ? ' AFTER `email_verified_at`'
                : (fate_members_table_has_column($pdo, 'EMAIL') ? ' AFTER `email`' : '');
            $pdo->exec(sprintf(
                "ALTER TABLE `%s`.`%s` ADD COLUMN `member_tier` VARCHAR(16) NOT NULL DEFAULT 'register' COMMENT '會員分級：register／formal／blacklist'%s",
                $dbEsc,
                $tblEsc,
                $after
            ));
            unset($GLOBALS['__fate_member_cols_snapshot']);
            $GLOBALS['fate_member_table_columns_reload'] = true;

            if (fate_members_table_has_column($pdo, 'EMAIL_VERIFIED_AT')) {
                $ac = str_replace('`', '``', FATE_MEMBER_ACTIVE_COLUMN);
                $pdo->exec(sprintf(
                    "UPDATE `%s`.`%s` SET `member_tier` = 'formal' WHERE `email_verified_at` IS NOT NULL AND `%s` = 1",
                    $dbEsc,
                    $tblEsc,
                    $ac
                ));
            }
        } catch (Throwable) {
            /* 無 ALTER 權限時略過 */
        }
    }

    $done = true;
}

function fate_member_tier_set(PDO $pdo, int $memberId, string $tier): bool
{
    if ($memberId <= 0 || !fate_admin_member_auth_ready()) {
        return false;
    }
    fate_member_tier_bootstrap_schema($pdo);
    if (!fate_member_tier_column_exists($pdo)) {
        return false;
    }

    $db = FATE_MEMBER_DATABASE;
    $tbl = FATE_MEMBER_TABLE;
    $norm = fate_member_tier_normalize($tier);
    try {
        $pdo->prepare(sprintf(
            'UPDATE `%s`.`%s` SET `member_tier` = ? WHERE `id` = ? LIMIT 1',
            str_replace('`', '``', $db),
            str_replace('`', '``', $tbl)
        ))->execute([$norm, $memberId]);

        return true;
    } catch (Throwable) {
        return false;
    }
}

/** @param array<string,mixed>|null $row */
function fate_member_tier_from_row(array $row): string
{
    if (!array_key_exists('member_tier', $row)) {
        $ev = $row['email_verified_at'] ?? null;
        if ($ev !== null && trim((string) $ev) !== '') {
            return 'formal';
        }

        return 'register';
    }

    return fate_member_tier_normalize((string) ($row['member_tier'] ?? 'register'));
}

/** @param array<string,mixed>|null $row */
function fate_member_row_is_blacklisted(?array $row): bool
{
    return is_array($row) && fate_member_tier_from_row($row) === 'blacklist';
}

/**
 * 僅 register 可因信箱驗證自動升為 formal；黑名單與已 formal 者不變。
 *
 * @param array<string,mixed>|null $row
 */
function fate_member_tier_may_auto_upgrade_formal(PDO $pdo, int $memberId, ?array $row = null): bool
{
    if ($memberId <= 0) {
        return false;
    }
    if ($row === null) {
        if (!function_exists('fate_admin_members_fetch_by_id')) {
            require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_admin_members.php';
        }
        $row = fate_admin_members_fetch_by_id($pdo, $memberId);
    }
    if (!is_array($row)) {
        return false;
    }

    return fate_member_tier_from_row($row) === 'register';
}

/**
 * 信箱驗證完成時呼叫：僅 register → formal。
 */
function fate_member_tier_upgrade_formal_if_eligible(PDO $pdo, int $memberId, ?array $row = null): void
{
    if (!fate_member_tier_may_auto_upgrade_formal($pdo, $memberId, $row)) {
        return;
    }
    fate_member_tier_set($pdo, $memberId, 'formal');
}

/** @deprecated 請改用 fate_member_tier_upgrade_formal_if_eligible */
function fate_member_tier_upgrade_formal(PDO $pdo, int $memberId): void
{
    fate_member_tier_upgrade_formal_if_eligible($pdo, $memberId);
}

function fate_member_tier_downgrade_register(PDO $pdo, int $memberId): void
{
    fate_member_tier_set($pdo, $memberId, 'register');
}

/**
 * 正式會員：分級為 formal、帳號啟用、非待審核。
 * 黑名單與停權皆不是正式會員。
 *
 * @param array<string,mixed>|null $row
 */
function fate_member_is_formal_member(PDO $pdo, int $memberId, ?array $row = null): bool
{
    if ($memberId <= 0) {
        return false;
    }

    fate_member_tier_bootstrap_schema($pdo);

    if ($row === null) {
        if (!function_exists('fate_admin_members_fetch_by_id')) {
            require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_admin_members.php';
        }
        $row = fate_admin_members_fetch_by_id($pdo, $memberId);
    }
    if (!is_array($row)) {
        return false;
    }

    if (fate_member_row_is_blacklisted($row)) {
        return false;
    }
    if ((int) ($row['_mem_active'] ?? 0) !== 1) {
        return false;
    }
    if (fate_member_row_pending_approval($row)) {
        return false;
    }

    return fate_member_tier_from_row($row) === 'formal';
}

/** 前台：目前登入會員是否為正式會員。 */
function fate_public_member_is_formal(PDO $pdo): bool
{
    if (!function_exists('fate_public_member_current')) {
        require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_public_member_auth.php';
    }
    $member = fate_public_member_current();
    if ($member === null) {
        return false;
    }

    return fate_member_is_formal_member($pdo, (int) ($member['id'] ?? 0));
}

/**
 * 正式會員專區：管理員、站方版主、論壇版主可略過限制。
 */
function fate_member_can_access_formal_only(PDO $pdo, int $memberId, bool $formalOnlyEnabled): bool
{
    if (!$formalOnlyEnabled) {
        return true;
    }
    if ($memberId <= 0) {
        return false;
    }
    if (fate_member_is_formal_member($pdo, $memberId)) {
        return true;
    }
    require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_public_member_auth.php';
    require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_store_masseurs.php';
    fate_public_member_ensure_admin_flag($pdo);

    return fate_masseur_member_is_site_staff($pdo);
}

/**
 * 正式會員專區鎖定提示（如標籤、年齡／身材）。
 */
function fate_masseur_formal_only_view_message(PDO $pdo, int $memberId, string $featureLabel): string
{
    if ($memberId <= 0) {
        return '請先登入並完成 Email 驗證成為正式會員後即可查看' . $featureLabel . '。';
    }
    if (fate_public_member_is_blacklisted($pdo)) {
        return '您的帳號已被列入黑名單，無法查看' . $featureLabel . '。';
    }
    require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_public_member_auth.php';
    if (!fate_public_member_session_email_verified()) {
        return '請先完成 Email 驗證成為正式會員後即可查看' . $featureLabel . '。';
    }

    return '僅正式會員可查看' . $featureLabel . '。';
}

/** 前台：目前登入會員是否在黑名單。 */
function fate_public_member_is_blacklisted(PDO $pdo): bool
{
    if (!function_exists('fate_public_member_current')) {
        require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_public_member_auth.php';
    }
    $member = fate_public_member_current();
    if ($member === null) {
        return false;
    }
    $memberId = (int) ($member['id'] ?? 0);
    if ($memberId <= 0) {
        return false;
    }
    if (!function_exists('fate_admin_members_fetch_by_id')) {
        require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_admin_members.php';
    }
    $row = fate_admin_members_fetch_by_id($pdo, $memberId);

    return fate_member_row_is_blacklisted($row);
}

/**
 * 會員是否可參與站內互動：須已完成信箱驗證；黑名單不可（未驗證黑名單與一般未驗證相同）。
 * 站方人員（admin／mod／論壇版主）豁免。
 *
 * @param array<string,mixed>|null $row
 */
function fate_member_can_interact(PDO $pdo, int $memberId, ?array $row = null): bool
{
    if ($memberId <= 0 || !fate_admin_member_auth_ready()) {
        return false;
    }

    require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_public_member_auth.php';
    require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_store_masseurs.php';
    require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_member_email.php';
    fate_member_email_bootstrap_schema($pdo);

    if ($row === null) {
        if (!function_exists('fate_admin_members_fetch_by_id')) {
            require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_admin_members.php';
        }
        $row = fate_admin_members_fetch_by_id($pdo, $memberId);
    }
    if (!is_array($row)) {
        return false;
    }

    fate_public_member_ensure_admin_flag($pdo);
    if (fate_masseur_member_is_site_staff($pdo)) {
        return true;
    }

    if (fate_member_row_pending_approval($row)) {
        return false;
    }
    if ((int) ($row['_mem_active'] ?? 0) !== 1) {
        return false;
    }
    if (fate_member_row_is_blacklisted($row)) {
        return false;
    }
    if (fate_member_requires_email_verify_for_row($pdo, $row)) {
        return false;
    }

    return true;
}
