import Foundation
import CBORCoding

/*
class HistoryManagerBase: ObservableObject {

    @Published
    var entries: [HistoryItem] = []
}

protocol HistoryManagerProtocol: HistoryManagerBase {

    var entries: [HistoryItem] { get }
    
    func save(item: HistoryItem) throws

    func delete(item: HistoryItem) -> Bool
}

final class HistoryManager: HistoryManagerBase, HistoryManagerProtocol {
    
    private let encoder = CBOREncoder(dateEncodingStrategy: .secondsSince1970)

    private var fm: FileManager {
        .default
    }

    static var documentDirectory: URL {
        try! FileManager.default.url(
        for: .documentDirectory,
        in: .userDomainMask,
        appropriateFor: nil, create: true)
    }

    private let fileUrl: URL
    
    override init() {
        self.fileUrl = HistoryManager.documentDirectory.appendingPathComponent("history2.bin")
        super.init()
        Task {
            print("Loading history...")
            let all = loadEntries()
            DispatchQueue.main.async {
                self.entries = all
                print("History loaded (\(self.entries.count) entries)")
            }
        }
    }
    
    private func loadEntries() -> [HistoryItem] {
        guard fm.fileExists(atPath: fileUrl.path) else {
            print("No history data found")
            return []
        }
        let content: Data
        do {
            content = try Data(contentsOf: fileUrl)
        } catch {
            print("Failed to read history data: \(error)")
            return []
        }
        let decoder = CBORDecoder()
        var index = 0
        var entries = [HistoryItem]()
        while index < content.count {
            let length = Int(content[index])
            index += 1
            if index + length > content.count {
                print("Missing bytes in history file: needed \(length), has only \(content.count - index)")
                return entries
            }
            let entryData = content[index..<index+length]
            index += length
            do {
                let entry: HistoryItem = try decoder.decode(from: entryData)
                entries.append(entry)
            } catch {
                print("Failed to decode history (index: \(index), length \(length)): \(error)")
                return entries
            }
        }
        return entries.sorted().reversed()
    }

    func save(item: HistoryItem) throws {
        let data = try convertForStorage(item)
        guard fm.fileExists(atPath: fileUrl.path) else {
            try data.write(to: fileUrl)
            print("First history item written (\(data[0]))")
            return
        }
        let handle = try FileHandle(forWritingTo: fileUrl)
        try handle.seekToEnd()
        try handle.write(contentsOf: data)
        try handle.close()
        print("History item written (\(data[0]))")
    }

    @discardableResult
    func delete(item: HistoryItem) -> Bool {
        let newItems = entries
            .filter { $0 != item }

        let data: FlattenSequence<[Data]>
        do {
            data = try newItems
                .map(convertForStorage)
                .joined()
        } catch {
            print("Failed to encode items: \(error)")
            return false
        }
        do {
            try Data(data).write(to: fileUrl)
        } catch {
            print("Failed to save items: \(error)")
            return false
        }
        entries = newItems
        return true
    }

    private func convertForStorage(_ item: HistoryItem) throws -> Data {
        let entryData = try encoder.encode(item)
        return Data([UInt8(entryData.count)]) + entryData
    }
}

final class HistoryManagerMock: HistoryManagerBase, HistoryManagerProtocol {

    override init() {
        super.init()
        self.entries = [.mock]
    }
    
    func save(item: HistoryItem) throws {
        entries.append(item)
    }

    func delete(item: HistoryItem) -> Bool {
        entries = entries.filter { $0 != item }
        return true
    }
}
*/
