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

import Foundation

/// 排队语音播报内容。
struct ScenicQueueAnnouncement: Equatable {
    enum Kind: Equatable {
        case newTickets(count: Int)
        case calledTicket(id: Int64)
    }

    let kind: Kind
    let text: String
}

/// 排队播报去重状态，避免同一批队列反复播报。
struct ScenicQueueAnnouncementState {
    private var knownTicketIds = Set<Int64>()
    private var calledTicketIds = Set<Int64>()

    /// 根据最新统计和列表计算下一条需要播报的内容。
    mutating func nextAnnouncement(
        stats: ScenicQueueStatsData,
        tickets: [ScenicQueueTicket],
        customCallText: String?
    ) -> ScenicQueueAnnouncement? {
        let currentIds = Set(tickets.map(\.id))
        let newTickets = tickets.filter { !knownTicketIds.contains($0.id) }
        knownTicketIds = currentIds

        if let ticket = tickets.first(where: { ($0.isCalled == 1 || $0.statusText.contains("已叫号")) && !calledTicketIds.contains($0.id) }) {
            calledTicketIds.insert(ticket.id)
            return ScenicQueueAnnouncement(kind: .calledTicket(id: ticket.id), text: Self.callText(for: ticket, customText: customCallText))
        }

        guard !newTickets.isEmpty else { return nil }
        let text = "排队提醒，当前新增\(newTickets.count)位游客，在排人数\(stats.queueCount)人。"
        return ScenicQueueAnnouncement(kind: .newTickets(count: newTickets.count), text: text)
    }

    /// 重置播报去重状态。
    mutating func reset() {
        knownTicketIds.removeAll()
        calledTicketIds.removeAll()
    }

    /// 生成叫号播报文案。
    static func callText(for ticket: ScenicQueueTicket, customText: String?) -> String {
        callText(forQueueCode: ticket.queueCode, customText: customText)
    }

    /// 生成叫号播报文案。
    static func callText(forQueueCode queueCode: String, customText: String?) -> String {
        let custom = customText?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
        if !custom.isEmpty, custom != "A0001" {
            return custom.replacingOccurrences(of: "{number}", with: queueCode)
        }
        let code = queueCode.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ? "当前游客" : ttsLabel(for: queueCode)
        return "请\(code)到拍摄点拍摄。"
    }

    /// 将排队号拆成更适合语音播报的文本。
    static func ttsLabel(for queueCode: String) -> String {
        let trimmed = queueCode.trimmingCharacters(in: .whitespacesAndNewlines)
        guard !trimmed.isEmpty else { return "当前游客" }
        return trimmed.map(String.init).joined(separator: " ")
    }
}
