import Foundation

enum ChatHistoryHelper {
    static let maxMessages = 80
    static let apiMaxTurns = 12
    static let apiCharBudget = 12_000

    struct HistoryTurn {
        let role: ChatRole
        let text: String
    }

    static func normalizeMessages(_ raw: [ChatMessage]) -> [ChatMessage] {
        var out: [ChatMessage] = []
        for item in raw {
            if item.role == .assistant && item.text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
                continue
            }
            out.append(item)
        }
        if out.count > maxMessages {
            return Array(out.suffix(maxMessages))
        }
        return out
    }

    static func activeThread(from file: ChatHistoryFile) -> (threadId: String, messages: [ChatMessage], thread: ChatThread?) {
        if file.threads.isEmpty {
            let legacy = normalizeMessages(file.messages ?? [])
            return (file.activeThreadId, legacy, nil)
        }
        let thread = file.threads.first(where: { $0.id == file.activeThreadId })
            ?? file.threads.sorted(by: { $0.updatedAt > $1.updatedAt }).first
        guard let thread else {
            return ("", [], nil)
        }
        return (thread.id, normalizeMessages(thread.messages), thread)
    }

    static func buildHistoryTurns(
        from messages: [ChatMessage],
        maxTurns: Int = apiMaxTurns,
        charBudget: Int = apiCharBudget
    ) -> [HistoryTurn] {
        var turns: [HistoryTurn] = []
        for m in messages {
            let text = m.text.trimmingCharacters(in: .whitespacesAndNewlines)
            guard !text.isEmpty else { continue }
            turns.append(HistoryTurn(role: m.role, text: text))
        }
        var kept: [HistoryTurn] = []
        var chars = 0
        for turn in turns.reversed() {
            if kept.count >= maxTurns { break }
            if chars + turn.text.count > charBudget && !kept.isEmpty { break }
            kept.append(turn)
            chars += turn.text.count
        }
        return kept.reversed()
    }

    static func preview(from messages: [ChatMessage]) -> String {
        for m in messages.reversed() {
            let text = m.text.trimmingCharacters(in: .whitespacesAndNewlines)
            guard !text.isEmpty else { continue }
            let prefix = m.role == .assistant ? "AI: " : ""
            return prefix + String(text.prefix(48))
        }
        return ""
    }

    static func title(from messages: [ChatMessage]) -> String? {
        for m in messages where m.role == .user {
            let text = m.text.trimmingCharacters(in: .whitespacesAndNewlines)
            guard !text.isEmpty else { continue }
            return String(text.prefix(28))
        }
        return nil
    }

    static func relativeAttachmentPath(for url: URL) -> String {
        let root = ChatHistoryStore.rootURL.path
        let full = url.path
        if full.hasPrefix(root + "/") {
            return String(full.dropFirst(root.count + 1))
        }
        return full
    }

    static func attachmentFileURL(for path: String) -> URL {
        if path.hasPrefix("/") {
            return URL(fileURLWithPath: path)
        }
        return ChatHistoryStore.rootURL.appendingPathComponent(path)
    }

    static func userDisplayText(_ text: String) -> String {
        var s = text
        let markers = [
            "\n\n(已附带截图)",
            "\n\n(已附带当前暂停画面截图)",
            "\n\n(已附带圈选区域截图)",
            "\n\n(已附带 PDF 页面/区域截图)",
        ]
        for marker in markers {
            s = s.replacingOccurrences(of: marker, with: "")
        }
        if let regex = try? NSRegularExpression(pattern: "\n\n时间范围: [0-9.]+s – [0-9.]+s", options: []) {
            s = regex.stringByReplacingMatches(in: s, range: NSRange(s.startIndex..., in: s), withTemplate: "")
        }
        return s.trimmingCharacters(in: .whitespacesAndNewlines)
    }

    static func formatThreadTime(_ iso: String) -> String {
        let formatter = ISO8601DateFormatter()
        formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
        var date = formatter.date(from: iso)
        if date == nil {
            formatter.formatOptions = [.withInternetDateTime]
            date = formatter.date(from: iso)
        }
        guard let date else { return iso }
        let timeFmt = DateFormatter()
        timeFmt.timeStyle = .short
        if Calendar.current.isDateInToday(date) {
            return timeFmt.string(from: date)
        }
        let dateFmt = DateFormatter()
        dateFmt.dateFormat = "MMM d"
        return "\(dateFmt.string(from: date)) \(timeFmt.string(from: date))"
    }
}
