import Foundation

struct VideoRecord: Identifiable, Equatable {
    let title: String
    let publishTimeText: String
    let videoURL: URL
    let publishDate: Date

    var id: String {
        videoURL.absoluteString
    }

    static func from(row: [String: String]) -> VideoRecord? {
        guard
            let title = value(in: row, for: ["title", "标题", "最新视频标题"])?.trimmingCharacters(in: .whitespacesAndNewlines),
            let publishTimeText = value(in: row, for: ["publish_time", "发布时间", "time", "date", "published_at"])?.trimmingCharacters(in: .whitespacesAndNewlines),
            let videoURLText = value(in: row, for: ["video_url", "视频链接", "url", "link"])?.trimmingCharacters(in: .whitespacesAndNewlines),
            let record = VideoRecord(title: title, publishTimeText: publishTimeText, videoURLText: videoURLText)
        else {
            return nil
        }

        return record
    }

    init?(title: String, publishTimeText: String, videoURLText: String) {
        let normalizedURLText = videoURLText.trimmingCharacters(in: .whitespacesAndNewlines)
        guard
            !title.isEmpty,
            let videoURL = URL(string: normalizedURLText),
            let publishDate = Date.bilibiliPublishDate(from: publishTimeText)
        else {
            return nil
        }

        self.title = title
        self.publishTimeText = publishTimeText
        self.videoURL = videoURL
        self.publishDate = publishDate
    }

    static func diagnosticMessage(for row: [String: String]) -> String {
        let title = value(in: row, for: ["title", "标题", "最新视频标题"])?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
        let publishTimeText = value(in: row, for: ["publish_time", "发布时间", "time", "date", "published_at"])?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
        let videoURLText = value(in: row, for: ["video_url", "视频链接", "url", "link"])?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""

        let titleState = title.isEmpty ? "标题为空" : "标题正常"
        let timeState = Date.bilibiliPublishDate(from: publishTimeText) == nil
            ? "时间无法解析：\(publishTimeText)"
            : "时间正常"
        let urlState = URL(string: videoURLText) == nil
            ? "链接无法解析：\(videoURLText)"
            : "链接正常"

        return "\(titleState)，\(timeState)，\(urlState)"
    }

    private static func value(in row: [String: String], for keys: [String]) -> String? {
        for key in keys {
            if let value = row[key] {
                return value
            }
        }
        return nil
    }
}

extension Date {
    static func bilibiliPublishDate(from text: String) -> Date? {
        let trimmedText = text.trimmingCharacters(in: .whitespacesAndNewlines)
        let timeTextWithoutZone = trimmedText
            .replacingOccurrences(
                of: #"\s+[A-Z]{2,5}$"#,
                with: "",
                options: .regularExpression
            )

        if let date = bilibiliPublishFormatter.date(from: timeTextWithoutZone) {
            return date
        }

        if let date = bilibiliPublishWithZoneFormatter.date(from: trimmedText) {
            return date
        }

        return ISO8601DateFormatter().date(from: trimmedText)
    }

    private static let bilibiliPublishFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.timeZone = TimeZone(identifier: "Asia/Shanghai")
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        return formatter
    }()

    private static let bilibiliPublishWithZoneFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.timeZone = TimeZone(identifier: "Asia/Shanghai")
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss zzz"
        return formatter
    }()

    static let dashboardFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.locale = Locale(identifier: "zh_CN")
        formatter.timeZone = TimeZone(identifier: "Asia/Shanghai")
        formatter.dateFormat = "M月d日 HH:mm"
        return formatter
    }()

    var dashboardText: String {
        Self.dashboardFormatter.string(from: self)
    }
}
