import Foundation

/// Drafts live as individual JSON files in Documents/Drafts — one tiny recipe
/// per draft, so many drafts of the same footage cost no extra video storage.
@MainActor
final class DraftStore: ObservableObject {
    @Published private(set) var drafts: [Draft] = []

    private let directory: URL = {
        let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
            .appendingPathComponent("Drafts", isDirectory: true)
        try? FileManager.default.createDirectory(at: dir, withIntermediateDirectories: true)
        return dir
    }()

    init() {
        load()
    }

    private func load() {
        let files = (try? FileManager.default.contentsOfDirectory(at: directory, includingPropertiesForKeys: nil)) ?? []
        drafts = files
            .filter { $0.pathExtension == "json" }
            .compactMap { url in
                guard let data = try? Data(contentsOf: url) else { return nil }
                return try? JSONDecoder().decode(Draft.self, from: data)
            }
        sort()
    }

    func create(name: String) -> Draft {
        let draft = Draft(id: UUID(), name: name, createdAt: Date(), modifiedAt: Date(), clips: [])
        drafts.append(draft)
        sort()
        write(draft)
        return draft
    }

    func save(_ draft: Draft) {
        var stamped = draft
        stamped.modifiedAt = Date()
        if let index = drafts.firstIndex(where: { $0.id == draft.id }) {
            drafts[index] = stamped
        } else {
            drafts.append(stamped)
        }
        sort()
        write(stamped)
    }

    /// "Save As New Draft" — duplicates the recipe (a few KB of JSON), never the video.
    @discardableResult
    func duplicate(_ draft: Draft) -> Draft {
        let copy = Draft(
            id: UUID(),
            name: draft.name + " copy",
            createdAt: Date(),
            modifiedAt: Date(),
            clips: draft.clips
        )
        drafts.append(copy)
        sort()
        write(copy)
        return copy
    }

    func delete(_ draft: Draft) {
        drafts.removeAll { $0.id == draft.id }
        try? FileManager.default.removeItem(at: fileURL(for: draft.id))
    }

    private func sort() {
        drafts.sort { $0.modifiedAt > $1.modifiedAt }
    }

    private func write(_ draft: Draft) {
        guard let data = try? JSONEncoder().encode(draft) else { return }
        try? data.write(to: fileURL(for: draft.id), options: .atomic)
    }

    private func fileURL(for id: UUID) -> URL {
        directory.appendingPathComponent("\(id.uuidString).json")
    }
}
