//
//  ScenicQueueSettingsStore.swift
//  suixinkan
//
//  Created by Codex on 2026/6/25.
//

import Foundation

/// 排队管理本地设置 key。
enum ScenicQueueLocalSettings {
    static let selectedSpotIdKey = "scenic_queue_selected_spot_id"
    static let selectedSpotNameKey = "scenic_queue_selected_spot_name"
    static let customTtsTextKey = "scenic_queue_custom_tts_text"
    static let settingsSnapshotKey = "scenic_queue_settings_snapshot"
    static let photoEstimateSecondsKey = "scenic_queue_photo_estimate_seconds"
    static let broadcastIntervalSecondsKey = "scenic_queue_broadcast_interval_seconds"
    static let countdownThresholdSecondsKey = "scenic_queue_countdown_threshold_seconds"
    static let showStartShootingButtonKey = "scenic_queue_show_start_shooting_button"
    static let autoCallAheadCountKey = "scenic_queue_auto_call_ahead_count"
    static let quickCallButtonEnabledKey = "scenic_queue_quick_call_button_enabled"
    static let prepareCallButtonEnabledKey = "scenic_queue_prepare_call_button_enabled"
    static let presetVoicesKey = "scenic_queue_preset_voices"
    static let ttsEnabledKey = "scenic_queue_tts_enabled"
    static let backgroundPollEnabledKey = "scenic_queue_background_poll_enabled"
}

/// 排队管理本地设置存储，按用户、景区、打卡点隔离并兼容旧 key。
enum ScenicQueueSettingsStore {
    /// 生成景区作用域 key。
    static func scopedKey(base: String, userId: String?, scenicId: Int?) -> String {
        guard let scenicId else { return base }
        let user = normalizedUserId(userId)
        return "\(base)_user_\(user)_scenic_\(scenicId)"
    }

    /// 生成打卡点作用域 key。
    static func scopedSpotKey(base: String, userId: String?, scenicId: Int?, spotId: Int?) -> String {
        guard let scenicId, let spotId else { return scopedKey(base: base, userId: userId, scenicId: scenicId) }
        let user = normalizedUserId(userId)
        return "\(base)_user_\(user)_scenic_\(scenicId)_spot_\(spotId)"
    }

    /// 读取已选打卡点 ID。
    static func selectedSpotId(userId: String?, scenicId: Int?) -> Int? {
        guard let scenicId else { return legacyPositiveInt(forKey: ScenicQueueLocalSettings.selectedSpotIdKey) }
        let key = scopedKey(base: ScenicQueueLocalSettings.selectedSpotIdKey, userId: userId, scenicId: scenicId)
        if let value = positiveInt(forKey: key) { return value }
        if let legacy = legacyPositiveInt(forKey: ScenicQueueLocalSettings.selectedSpotIdKey) {
            UserDefaults.standard.set(legacy, forKey: key)
            return legacy
        }
        return nil
    }

    /// 读取已选打卡点名称。
    static func selectedSpotName(userId: String?, scenicId: Int?) -> String {
        guard let scenicId else {
            return UserDefaults.standard.string(forKey: ScenicQueueLocalSettings.selectedSpotNameKey) ?? ""
        }
        let key = scopedKey(base: ScenicQueueLocalSettings.selectedSpotNameKey, userId: userId, scenicId: scenicId)
        if let value = UserDefaults.standard.string(forKey: key), !value.isEmpty { return value }
        let legacy = UserDefaults.standard.string(forKey: ScenicQueueLocalSettings.selectedSpotNameKey) ?? ""
        if !legacy.isEmpty {
            UserDefaults.standard.set(legacy, forKey: key)
        }
        return legacy
    }

    /// 保存已选打卡点。
    static func saveSelectedSpot(id: Int, name: String, userId: String?, scenicId: Int) {
        let defaults = UserDefaults.standard
        defaults.set(id, forKey: ScenicQueueLocalSettings.selectedSpotIdKey)
        defaults.set(name, forKey: ScenicQueueLocalSettings.selectedSpotNameKey)
        defaults.set(id, forKey: scopedKey(base: ScenicQueueLocalSettings.selectedSpotIdKey, userId: userId, scenicId: scenicId))
        defaults.set(name, forKey: scopedKey(base: ScenicQueueLocalSettings.selectedSpotNameKey, userId: userId, scenicId: scenicId))
    }

    /// 读取自定义语音文本。
    static func customTtsText(userId: String?, scenicId: Int?, spotId: Int?) -> String {
        guard let scenicId, let spotId else {
            return UserDefaults.standard.string(forKey: ScenicQueueLocalSettings.customTtsTextKey) ?? ""
        }
        let key = scopedSpotKey(base: ScenicQueueLocalSettings.customTtsTextKey, userId: userId, scenicId: scenicId, spotId: spotId)
        if let value = UserDefaults.standard.string(forKey: key) { return value }
        let legacy = UserDefaults.standard.string(forKey: ScenicQueueLocalSettings.customTtsTextKey) ?? ""
        if !legacy.isEmpty {
            UserDefaults.standard.set(legacy, forKey: key)
        }
        return legacy
    }

    /// 保存自定义语音文本。
    static func saveCustomTtsText(_ text: String, userId: String?, scenicId: Int?, spotId: Int?) {
        let trimmed = text.trimmingCharacters(in: .whitespacesAndNewlines)
        UserDefaults.standard.set(trimmed, forKey: ScenicQueueLocalSettings.customTtsTextKey)
        if let scenicId, let spotId {
            UserDefaults.standard.set(
                trimmed,
                forKey: scopedSpotKey(base: ScenicQueueLocalSettings.customTtsTextKey, userId: userId, scenicId: scenicId, spotId: spotId)
            )
        }
    }

    /// 读取设置快照。
    static func settingsSnapshot(userId: String?, scenicId: Int, spotId: Int) -> ScenicQueueSettingsSnapshot? {
        let keys = [
            scopedSpotKey(base: ScenicQueueLocalSettings.settingsSnapshotKey, userId: userId, scenicId: scenicId, spotId: spotId),
            "scenic_\(scenicId)_spot_\(spotId)_\(ScenicQueueLocalSettings.settingsSnapshotKey)",
            "scenic_\(scenicId)_\(ScenicQueueLocalSettings.settingsSnapshotKey)"
        ]
        for key in keys {
            guard let data = UserDefaults.standard.data(forKey: key),
                  let snapshot = try? JSONDecoder().decode(ScenicQueueSettingsSnapshot.self, from: data)
            else { continue }
            return snapshot
        }
        return nil
    }

    /// 保存设置快照。
    static func saveSettingsSnapshot(_ snapshot: ScenicQueueSettingsSnapshot, userId: String?, scenicId: Int, spotId: Int) {
        guard let data = try? JSONEncoder().encode(snapshot) else { return }
        UserDefaults.standard.set(
            data,
            forKey: scopedSpotKey(base: ScenicQueueLocalSettings.settingsSnapshotKey, userId: userId, scenicId: scenicId, spotId: spotId)
        )
        UserDefaults.standard.set(data, forKey: "scenic_\(scenicId)_spot_\(spotId)_\(ScenicQueueLocalSettings.settingsSnapshotKey)")
    }

    /// 读取语音预设。
    static func presetVoices(userId: String?, scenicId: Int?, spotId: Int?) -> [String] {
        guard let scenicId, let spotId else { return [] }
        let keys = [
            scopedSpotKey(base: ScenicQueueLocalSettings.presetVoicesKey, userId: userId, scenicId: scenicId, spotId: spotId),
            "scenic_\(scenicId)_spot_\(spotId)_\(ScenicQueueLocalSettings.presetVoicesKey)"
        ]
        for key in keys {
            guard let data = UserDefaults.standard.data(forKey: key),
                  let voices = try? JSONDecoder().decode([String].self, from: data)
            else { continue }
            return voices
        }
        return []
    }

    /// 保存语音预设。
    static func savePresetVoices(_ voices: [String], userId: String?, scenicId: Int, spotId: Int) {
        let normalized = Array(voices.map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }.filter { !$0.isEmpty }.prefix(5))
        guard let data = try? JSONEncoder().encode(normalized) else { return }
        UserDefaults.standard.set(
            data,
            forKey: scopedSpotKey(base: ScenicQueueLocalSettings.presetVoicesKey, userId: userId, scenicId: scenicId, spotId: spotId)
        )
        UserDefaults.standard.set(data, forKey: "scenic_\(scenicId)_spot_\(spotId)_\(ScenicQueueLocalSettings.presetVoicesKey)")
    }

    private static func normalizedUserId(_ userId: String?) -> String {
        let text = userId?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
        return text.isEmpty ? "anonymous" : text
    }

    private static func positiveInt(forKey key: String) -> Int? {
        guard UserDefaults.standard.object(forKey: key) != nil else { return nil }
        let value = UserDefaults.standard.integer(forKey: key)
        return value > 0 ? value : nil
    }

    private static func legacyPositiveInt(forKey key: String) -> Int? {
        positiveInt(forKey: key)
    }
}
