import Foundation
import Observation

struct Bookmark: Codable, Identifiable {
    let id: UUID
    let createdAt: Date
    let itemId: String
    let episodeId: String?
    let itemTitle: String
    var title: String
    let chapterTitle: String?
    let time: Double
}

@Observable
@MainActor
final class BookmarkManager {
    private(set) var bookmarks: [Bookmark] = []

    private var saveFile: URL {
        AppPaths.supportDirectory.appendingPathComponent("bookmarks.json")
    }

    init() { load() }

    func add(item: LibraryItem, time: Double, title: String, chapters: [Chapter]) {
        let chapter = chapters.last { $0.start <= time }
        let bm = Bookmark(
            id: UUID(),
            createdAt: Date(),
            itemId: item.id,
            episodeId: item.episodeId,
            itemTitle: item.title,
            title: title,
            chapterTitle: chapter?.title,
            time: time
        )
        bookmarks.insert(bm, at: 0)
        save()
    }

    func delete(_ bookmark: Bookmark) {
        bookmarks.removeAll { $0.id == bookmark.id }
        save()
    }

    func bookmarks(for item: LibraryItem) -> [Bookmark] {
        bookmarks.filter { $0.itemId == item.id && $0.episodeId == item.episodeId }
            .sorted { $0.time < $1.time }
    }

    /// Replaces bookmarks for an item with the server-loaded list (keeps bookmarks for other items).
    func mergeFromServer(_ serverBookmarks: [ServerBookmark], for item: LibraryItem) {
        bookmarks.removeAll { $0.itemId == item.id && $0.episodeId == item.episodeId }
        let chapters = item.chapters
        for sb in serverBookmarks {
            let chapter = chapters.last { $0.start <= sb.time }
            let bm = Bookmark(
                id: UUID(),
                createdAt: sb.createdAt.map { Date(timeIntervalSince1970: $0 / 1000) } ?? Date(),
                itemId: item.id,
                episodeId: item.episodeId,
                itemTitle: item.title,
                title: sb.title,
                chapterTitle: chapter?.title,
                time: sb.time
            )
            bookmarks.append(bm)
        }
        bookmarks.sort { $0.createdAt > $1.createdAt }
        save()
    }

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

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