import Foundation

/// Separate diagnostics for unsuccessful attempts; never writes into a session master.
@MainActor
final class CalibrationAttemptLog {
    struct Entry: Codable {
        var time: Date
        var uptime: Double
        var event: String
        var stage: String
        var reason: String?
        var retries: Int
        var sampleCounts: [String: Int]
        var angleRadians: Double?
        var rateRadiansPerSecond: Double?
        var details: String
        var build: String
    }
    private let directory: URL
    private var entries: [Entry] = []
    private(set) var url: URL?
    init(directory: URL) {
        self.directory = directory.appendingPathComponent("CalibrationLogs", isDirectory: true)
        url = (try? FileManager.default.contentsOfDirectory(at: self.directory, includingPropertiesForKeys: [.contentModificationDateKey]))?
            .filter { $0.pathExtension == "json" }.max {
                let lhs = (try? $0.resourceValues(forKeys: [.contentModificationDateKey]).contentModificationDate) ?? .distantPast
                let rhs = (try? $1.resourceValues(forKeys: [.contentModificationDateKey]).contentModificationDate) ?? .distantPast
                return lhs < rhs
            }
    }
    func begin() {
        entries = []
        url = directory.appendingPathComponent("calibration-\(Int(Date().timeIntervalSince1970))-\(UUID().uuidString).json")
    }
    func record(_ event: String, calibration: CalibrationController, details: String) throws {
        guard let url else { return }
        entries.append(Entry(time: Date(), uptime: ProcessInfo.processInfo.systemUptime,
                             event: event, stage: String(describing: calibration.stage), reason: calibration.error?.rawValue,
                             retries: calibration.automaticRetries, sampleCounts: calibration.evidenceCounts,
                             angleRadians: calibration.latestAngleRadians.flatMap { $0.isFinite ? $0 : nil },
                             rateRadiansPerSecond: calibration.latestRateRadiansPerSecond.flatMap { $0.isFinite ? $0 : nil },
                             details: details, build: Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as? String ?? "unknown"))
        let encoder = JSONEncoder()
        encoder.dateEncodingStrategy = .iso8601
        encoder.outputFormatting = [.prettyPrinted, .sortedKeys]
        try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true)
        try encoder.encode(entries).write(to: url, options: .atomic)
    }
}
