<?php

declare(strict_types=1);

/**
 * 店家文字評論（與推薦技師模組分開，可單獨啟用）。
 *
 * - fate_store_reviews  會員對店家的文字評論
 */

require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_masseur_rewards.php';
require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_store_masseurs.php';

function fate_store_reviews_table_ddl(): string
{
    return <<<'SQL'
CREATE TABLE IF NOT EXISTS `fate_store_reviews` (
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `spa_store_id` INT UNSIGNED NOT NULL,
  `member_id` INT UNSIGNED NOT NULL,
  `body` TEXT NOT NULL,
  `is_hidden` TINYINT NOT NULL DEFAULT 0,
  `edited_by_admin` TINYINT NOT NULL DEFAULT 0,
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `idx_store` (`spa_store_id`, `is_hidden`, `id`),
  KEY `idx_member_store` (`member_id`, `spa_store_id`, `created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
SQL;
}

function fate_store_reviews_ensure_table(PDO $pdo): void
{
    static $done = false;
    if ($done) {
        return;
    }
    try {
        $pdo->exec(fate_store_reviews_table_ddl());
        $done = true;
    } catch (Throwable) {
        /* 無建表權限時略過 */
    }
}

function fate_store_reviews_enabled(): bool
{
    $s = fate_masseur_rewards_settings();

    return !empty($s['store_reviews_enabled']);
}

function fate_store_reviews_formal_only(): bool
{
    return false;
}

function fate_store_reviews_per_page(): int
{
    return 10;
}

function fate_store_reviews_count(PDO $pdo, int $storeId, bool $includeHidden = false): int
{
    fate_store_reviews_ensure_table($pdo);
    if ($storeId <= 0) {
        return 0;
    }
    $sql = 'SELECT COUNT(*) FROM `fate_store_reviews` WHERE `spa_store_id` = ?';
    if (!$includeHidden) {
        $sql .= ' AND `is_hidden` = 0';
    }
    try {
        $st = $pdo->prepare($sql);
        $st->execute([$storeId]);

        return (int) $st->fetchColumn();
    } catch (Throwable) {
        return 0;
    }
}

/**
 * @return list<array<string,mixed>>
 */
function fate_store_reviews_for(
    PDO $pdo,
    int $storeId,
    bool $includeHidden = false,
    ?int $limit = null,
    int $offset = 0
): array {
    fate_store_reviews_ensure_table($pdo);
    if ($storeId <= 0) {
        return [];
    }
    $memberQt = fate_masseur_member_table_qualified();
    $sql = 'SELECT r.*, p.`avatar_rel` AS author_avatar, ';
    $sql .= $memberQt !== null
        ? "COALESCE(NULLIF(TRIM(mb.`display_name`), ''), mb.`username`, CONCAT('會員#', r.`member_id`)) AS author_name "
        : "CONCAT('會員#', r.`member_id`) AS author_name ";
    $sql .= 'FROM `fate_store_reviews` r ';
    $sql .= 'LEFT JOIN `fate_site_member_profiles` p ON p.`member_id` = r.`member_id` ';
    if ($memberQt !== null) {
        $sql .= "LEFT JOIN $memberQt mb ON mb.`id` = r.`member_id` ";
    }
    $sql .= 'WHERE r.`spa_store_id` = ? ';
    if (!$includeHidden) {
        $sql .= 'AND r.`is_hidden` = 0 ';
    }
    $sql .= 'ORDER BY r.`id` DESC';
    if ($limit !== null) {
        $limit = max(1, min(100, $limit));
        $offset = max(0, $offset);
        $sql .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
    }

    try {
        $st = $pdo->prepare($sql);
        $st->execute([$storeId]);

        return $st->fetchAll(PDO::FETCH_ASSOC) ?: [];
    } catch (Throwable) {
        return [];
    }
}

/**
 * @return array{ok:bool,error:?string,id:?int}
 */
function fate_store_review_create(PDO $pdo, int $storeId, int $memberId, string $body, string $username = ''): array
{
    fate_store_reviews_ensure_table($pdo);
    if ($storeId <= 0 || $memberId <= 0) {
        return ['ok' => false, 'error' => '參數錯誤。', 'id' => null];
    }
    if (!fate_store_reviews_enabled()) {
        return ['ok' => false, 'error' => '本站暫停店家文字評論。', 'id' => null];
    }
    $body = trim($body);
    if (function_exists('mb_substr')) {
        $body = mb_substr($body, 0, 1000);
    }
    if ($body === '') {
        return ['ok' => false, 'error' => '請輸入評論內容。', 'id' => null];
    }

    $cfg = fate_masseur_rewards_settings();
    $weekStart = fate_masseur_week_start();
    try {
        $st = $pdo->prepare(
            'SELECT COUNT(*) FROM `fate_store_reviews` WHERE `member_id` = ? AND `spa_store_id` = ? AND `created_at` >= ?'
        );
        $st->execute([$memberId, $storeId, $weekStart]);
        $usedThisWeek = (int) $st->fetchColumn();
    } catch (Throwable $e) {
        return ['ok' => false, 'error' => '資料庫錯誤：' . $e->getMessage(), 'id' => null];
    }
    if ($usedThisWeek >= $cfg['review_per_week']) {
        return ['ok' => false, 'error' => '您本週對這家店的評論次數已用完（每週 ' . $cfg['review_per_week'] . ' 次，週日 24:00 重置）。', 'id' => null];
    }

    try {
        $st = $pdo->prepare('INSERT INTO `fate_store_reviews` (`spa_store_id`, `member_id`, `body`) VALUES (?, ?, ?)');
        $st->execute([$storeId, $memberId, $body]);
        $id = (int) $pdo->lastInsertId();
    } catch (Throwable $e) {
        return ['ok' => false, 'error' => '評論失敗：' . $e->getMessage(), 'id' => null];
    }

    fate_store_review_reward_grant($pdo, $memberId, $id, $username);

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

function fate_store_review_reward_grant(PDO $pdo, int $memberId, int $reviewId, string $username = ''): int
{
    if ($memberId <= 0 || $reviewId <= 0 || !fate_store_reviews_enabled()) {
        return 0;
    }
    $cfg = fate_masseur_rewards_settings();
    $amount = max(0, (int) ($cfg['reward_store_review'] ?? $cfg['reward_review'] ?? 0));
    if ($amount <= 0) {
        return 0;
    }

    fate_reward_ledger_ensure_table($pdo);
    try {
        $st = $pdo->prepare(
            'INSERT IGNORE INTO `fate_reward_ledger` (`member_id`, `action`, `ref_id`, `amount`, `note`) VALUES (?, ?, ?, ?, ?)'
        );
        $st->execute([$memberId, 'store_review', $reviewId, $amount, '店家評論 #' . $reviewId]);
        if ($st->rowCount() < 1) {
            return 0;
        }
        $ledgerId = (int) $pdo->lastInsertId();
    } catch (Throwable) {
        return 0;
    }

    $applied = fate_ncoin_credit_member($pdo, $memberId, $amount, $username);
    try {
        $pdo->prepare('UPDATE `fate_reward_ledger` SET `applied_local` = ?, `applied_spa` = ? WHERE `id` = ?')
            ->execute([$applied['local'] ? 1 : 0, $applied['spa'] ? 1 : 0, $ledgerId]);
    } catch (Throwable) {
        /* 略過 */
    }

    return $amount;
}
