<?php

declare(strict_types=1);

/**
 * 會員推薦店家（manual）寫入 spa_store_snapshots。
 */

require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_store_listing.php';
require_once __DIR__ . DIRECTORY_SEPARATOR . 'fate_member_stores.php';
require_once __DIR__ . DIRECTORY_SEPARATOR . 'google_place_opening_hours.php';

function fate_member_store_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 = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . 'stores';
    if (!is_dir($dir) && !mkdir($dir, 0775, true) && !is_dir($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;
}

/**
 * @param array<string,mixed> $fields
 * @return array{ok:bool,store_id?:int,error?:string}
 */
function fate_member_store_insert_manual(PDO $pdo, int $memberId, array $fields, string $listingKind): array
{
    if ($memberId <= 0) {
        return ['ok' => false, 'error' => '無效的會員。'];
    }

    $kind = fate_store_listing_normalize_kind($listingKind);
    $storeName = trim((string) ($fields['store_name'] ?? ''));
    $coverPath = trim((string) ($fields['cover_photo_path'] ?? ''));
    if ($storeName === '') {
        return ['ok' => false, 'error' => '請填寫名稱。'];
    }
    if ($coverPath === '') {
        return ['ok' => false, 'error' => '請上傳封面照片。'];
    }

    $phone = trim((string) ($fields['phone'] ?? ''));
    $mobile = trim((string) ($fields['mobile'] ?? ''));
    $line = trim((string) ($fields['line'] ?? ''));
    $wechat = trim((string) ($fields['wechat'] ?? ''));

    if ($kind === FATE_STORE_LISTING_MOBILE) {
        $city = trim((string) ($fields['city_name'] ?? ''));
        $district = trim((string) ($fields['district_name'] ?? ''));
        if ($city === '' || $district === '') {
            return ['ok' => false, 'error' => '請選擇服務區域（城市與地區）。'];
        }
        if (!fate_store_listing_has_contact(compact('phone', 'mobile', 'line', 'wechat'))) {
            return ['ok' => false, 'error' => '非定點服務至少需填寫一項聯絡方式（電話、手機、LINE 或 WeChat）。'];
        }
        $serviceArea = fate_store_listing_format_service_area($city, $district);
        $street = '';
        $placeAddr = '';
        $gml = '';
        $displayAddress = '服務區域：' . $serviceArea;
        $payloadExtra = ['service_area' => $serviceArea];
    } else {
        $city = trim((string) ($fields['city_name'] ?? ''));
        $district = trim((string) ($fields['district_name'] ?? ''));
        $street = trim((string) ($fields['street_address'] ?? ''));
        if ($city === '' || $district === '' || $street === '') {
            return ['ok' => false, 'error' => '請填寫店名、城市、地區與街道地址。'];
        }
        $placeAddr = trim((string) ($fields['place_formatted_address'] ?? ''));
        $gml = trim((string) ($fields['google_map_location'] ?? ''));
        $displayAddress = $placeAddr !== '' ? $placeAddr : fate_member_store_format_address([
            'city_name' => $city,
            'district_name' => $district,
            'street_address' => $street,
        ]);
        $payloadExtra = [];
    }

    $photoPaths = $fields['photo_paths'] ?? [];
    if (!is_array($photoPaths)) {
        $photoPaths = [];
    }

    $basicCharge = $fields['basic_charge'] ?? '';
    $basicVal = ($basicCharge !== '' && is_numeric($basicCharge)) ? (float) $basicCharge : null;

    $multiHours = $fields['multi_hours'] ?? [];
    if (!is_array($multiHours)) {
        $multiHours = [];
    }
    $multiHoursJson = json_encode($multiHours, JSON_UNESCAPED_UNICODE);
    if (!is_string($multiHoursJson)) {
        $multiHoursJson = '{}';
    }

    try {
        $maxSt = $pdo->query('SELECT MAX(`spa_store_id`) FROM `spa_store_snapshots`');
        $maxId = $maxSt !== false ? (int) $maxSt->fetchColumn() : 0;
        $newStoreId = max(1000000, $maxId + 1);

        $payloadJson = $kind === FATE_STORE_LISTING_MOBILE
            ? fate_store_listing_build_payload($kind, $payloadExtra)
            : null;

        $st = $pdo->prepare(
            'INSERT INTO `spa_store_snapshots` (
                `spa_store_id`, `synced_at`, `source_data_as_of_unix`, `store_name`, `display_address`,
                `city_name`, `district_name`, `street_address`, `place_formatted_address`, `google_map_location`,
                `phone`, `mobile`, `line`, `wechat`, `website`, `facebook`, `basic_charge`, `cover_photo_path`, `photos_json`,
                `business_hours_start`, `business_hours_end`, `place_opening_hours_raw`, `business_hours_json`,
                `business_type`, `appointment_required`, `parking`, `payment_method`, `spa_type`,
                `payload_json`, `source_type`, `is_approved`, `created_member_id`
            ) VALUES (
                ?, NOW(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
            )'
        );
        $st->execute([
            $newStoreId,
            time(),
            $storeName,
            $displayAddress,
            $city !== '' ? $city : null,
            $district !== '' ? $district : null,
            $street !== '' ? $street : null,
            $placeAddr !== '' ? $placeAddr : null,
            $gml !== '' ? $gml : null,
            $phone !== '' ? $phone : null,
            $mobile !== '' ? $mobile : null,
            $line !== '' ? $line : null,
            $wechat !== '' ? $wechat : null,
            trim((string) ($fields['website'] ?? '')) ?: null,
            trim((string) ($fields['facebook'] ?? '')) ?: null,
            $basicVal,
            $coverPath,
            json_encode($photoPaths, JSON_UNESCAPED_SLASHES) ?: '[]',
            trim((string) ($fields['business_hours_start'] ?? '')) ?: null,
            trim((string) ($fields['business_hours_end'] ?? '')) ?: null,
            fate_generate_google_place_hours($multiHours) ?: null,
            $multiHoursJson,
            trim((string) ($fields['business_type'] ?? '')) ?: null,
            trim((string) ($fields['appointment_required'] ?? '')) ?: null,
            trim((string) ($fields['parking'] ?? '')) ?: null,
            trim((string) ($fields['payment_method'] ?? '')) ?: null,
            trim((string) ($fields['spa_type'] ?? '')) ?: null,
            $payloadJson,
            'manual',
            0,
            $memberId,
        ]);

        return ['ok' => true, 'store_id' => $newStoreId];
    } catch (Throwable $e) {
        error_log('fate_member_store_insert_manual: ' . $e->getMessage());

        return ['ok' => false, 'error' => '儲存失敗：' . $e->getMessage()];
    }
}
