import Foundation
import Observation

struct HistoryEntry: Codable, Identifiable {
    let id: UUID
    let timestamp: Date
    let itemId: String
    let episodeId: String?
    let itemTitle: String
    let itemAuthor: String
    let chapterTitle: String?
    let position: Double
}

@Observable
@MainActor
final class HistoryManager {
    private(set) var entries: [HistoryEntry] = []

    private static let maxEntries = 200
    private var saveFile: URL {
        AppPaths.supportDirectory.appendingPathComponent("history.json")
    }

    init() { load() }

    func record(item: LibraryItem, position: Double, chapters: [Chapter]) {
        guard position >= 0 else { return }
        if let last = entries.first,
           last.itemId == item.id,
           last.episodeId == item.episodeId,
           abs(last.position - position) < 15 { return }
        let chapter = chapters.last { $0.start <= position }
        let entry = HistoryEntry(
            id: UUID(),
            timestamp: Date(),
            itemId: item.id,
            episodeId: item.episodeId,
            itemTitle: item.title,
            itemAuthor: item.author,
            chapterTitle: chapter?.title,
            position: position
        )
        entries.insert(entry, at: 0)
        if entries.count > Self.maxEntries { entries.removeLast() }
        save()
    }

    func clear() {
        entries.removeAll()
        save()
    }

    func exportXML() -> URL? {
        let formatter = ISO8601DateFormatter()
        var xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        xml += "<history exported=\"\(formatter.string(from: Date()))\">\n"
        for entry in entries {
            xml += "  <entry>\n"
            xml += "    <timestamp>\(formatter.string(from: entry.timestamp))</timestamp>\n"
            xml += "    <itemTitle>\(xmlEscape(entry.itemTitle))</itemTitle>\n"
            xml += "    <itemAuthor>\(xmlEscape(entry.itemAuthor))</itemAuthor>\n"
            if let chapter = entry.chapterTitle {
                xml += "    <chapter>\(xmlEscape(chapter))</chapter>\n"
            }
            if let epId = entry.episodeId {
                xml += "    <episodeId>\(xmlEscape(epId))</episodeId>\n"
            }
            xml += "    <position>\(entry.position)</position>\n"
            xml += "  </entry>\n"
        }
        xml += "</history>\n"

        let tmpURL = FileManager.default.temporaryDirectory
            .appendingPathComponent("hoerverlauf.xml")
        try? xml.write(to: tmpURL, atomically: true, encoding: .utf8)
        return tmpURL
    }

    private func xmlEscape(_ s: String) -> String {
        s.replacingOccurrences(of: "&", with: "&amp;")
         .replacingOccurrences(of: "<", with: "&lt;")
         .replacingOccurrences(of: ">", with: "&gt;")
    }

    private func save() {
        try? FileManager.default.createDirectory(
            at: AppPaths.supportDirectory, withIntermediateDirectories: true)
        if let data = try? JSONEncoder().encode(entries) {
            try? data.write(to: saveFile)
        }
    }

    private func load() {
        guard let data = try? Data(contentsOf: saveFile) else { return }
        entries = (try? JSONDecoder().decode([HistoryEntry].self, from: data)) ?? []
    }
}
