<?php
declare(strict_types=1);

/**
 * 寫入新手村 spa 資料庫（spa_stores）；與 fate 本地庫分開連線。
 */

if (!function_exists('fate_spa_stores_pdo')) {
    function fate_spa_stores_pdo(): PDO
    {
        static $spaPdo = null;
        if ($spaPdo instanceof PDO) {
            return $spaPdo;
        }
        require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_path_safe.php';
        require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_db_connect.php';
        $legacy = dirname(__DIR__, 2) . DIRECTORY_SEPARATOR . 'newbies' . DIRECTORY_SEPARATOR . 'db_connect.php';
        if (!fate_path_is_file_safe($legacy)) {
            throw new RuntimeException('此功能需同層 newbies 專案（spa 來源站）；公開／獨立部署時不適用。');
        }
        require_once $legacy;
        if (!isset($pdo) || !$pdo instanceof PDO) {
            throw new RuntimeException('無法連線 spa 資料庫');
        }
        $spaPdo = $pdo;

        return $spaPdo;
    }
}

if (!function_exists('fate_spa_stores_upload_dir')) {
    function fate_spa_stores_upload_dir(): string
    {
        return dirname(__DIR__, 2) . DIRECTORY_SEPARATOR . 'newbies' . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . 'stores';
    }
}

if (!function_exists('fate_spa_stores_save_uploaded_image')) {
    /**
     * @param array<string,mixed> $file $_FILES['field']
     * @return string 相對路徑 /uploads/stores/...
     */
    function fate_spa_stores_save_uploaded_image(array $file, string $prefix): string
    {
        if (($file['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK) {
            throw new InvalidArgumentException('上傳失敗（錯誤碼 ' . (int) ($file['error'] ?? 0) . '）');
        }
        $tmp = (string) ($file['tmp_name'] ?? '');
        if ($tmp === '' || !is_uploaded_file($tmp)) {
            throw new InvalidArgumentException('無效的上傳檔案');
        }
        if (($file['size'] ?? 0) > 8 * 1024 * 1024) {
            throw new InvalidArgumentException('檔案超過 8MB');
        }
        $ext = strtolower(pathinfo((string) ($file['name'] ?? ''), PATHINFO_EXTENSION));
        $allowed = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
        if (!in_array($ext, $allowed, true)) {
            throw new InvalidArgumentException('僅支援 jpg、png、gif、webp');
        }
        $dir = fate_spa_stores_upload_dir();
        if (!fate_path_is_dir_safe($dir)) {
            if (!fate_path_is_within_open_basedir($dir)) {
                throw new RuntimeException('此功能需同層 newbies 專案（spa 來源站）；公開／獨立部署時不適用。');
            }
            if (!@mkdir($dir, 0775, true) && !fate_path_is_dir_safe($dir)) {
                throw new RuntimeException('無法建立上傳目錄');
            }
        }
        $name = $prefix . '_' . time() . '_' . bin2hex(random_bytes(4)) . '.' . ($ext === 'jpeg' ? 'jpg' : $ext);
        $dest = $dir . DIRECTORY_SEPARATOR . $name;
        if (!move_uploaded_file($tmp, $dest)) {
            throw new RuntimeException('無法儲存上傳檔案');
        }

        return '/uploads/stores/' . $name;
    }
}

if (!function_exists('fate_spa_stores_insert')) {
    /**
     * @param array<string,mixed> $fields 欄位名 => 值
     * @return int 新 spa_stores.id
     */
    function fate_spa_stores_insert(array $fields): int
    {
        $pdo = fate_spa_stores_pdo();
        $cols = [];
        $vals = [];
        foreach ($fields as $k => $v) {
            if (!is_string($k) || $k === '' || !preg_match('/^[a-zA-Z0-9_]+$/', $k)) {
                continue;
            }
            $cols[] = '`' . $k . '`';
            $vals[] = $v;
        }
        if ($cols === []) {
            throw new InvalidArgumentException('沒有可寫入的欄位');
        }
        $sql = 'INSERT INTO spa_stores (' . implode(', ', $cols) . ') VALUES (' . implode(', ', array_fill(0, count($cols), '?')) . ')';
        $st = $pdo->prepare($sql);
        $st->execute($vals);
        $id = (int) $pdo->lastInsertId();
        if ($id <= 0) {
            throw new RuntimeException('新增店家後未取得 ID');
        }

        return $id;
    }
}
