import Foundation
import PoseCore

let args=Array(CommandLine.arguments.dropFirst())
guard args.count == 3, ["feasibility", "redetect", "import-coaching", "coaching-checklist", "validate-checklist", "audit-coaching"].contains(args[0]) else {
    print("Usage: pose-batch feasibility <session.json> <new-output-directory>")
    print("       pose-batch import-coaching <review.json> <source-bound-contexts.json>")
    print("       pose-batch coaching-checklist|validate-checklist <review.json> <checklist.json>")
    print("       pose-batch audit-coaching <session.json> <results.json>")
    exit(64)
}
do {
    if args[0] == "audit-coaching" {
        let manifest = URL(fileURLWithPath: args[1])
        let document = try ReviewStore.make(manifestURL: manifest, reportURL: URL(fileURLWithPath: args[2]))
        let url = manifest.deletingLastPathComponent().appendingPathComponent("coaching-checklist.json")
        let reviews = FileManager.default.fileExists(atPath: url.path) ? try CoachingChecklist.load(from: url, frames: document.frames) : [:]
        var pending = 0
        for frame in document.frames where frame.role == "subject" {
            let missing = CoachingChecklist.rows(review: reviews[frame.id]).filter { $0.status == .needsReview }
            pending += missing.count
            print("\(frame.id): \(CoachingTopic.allCases.count - missing.count)/\(CoachingTopic.allCases.count) topics assessed")
        }
        if pending > 0 { exit(2) }
        exit(0)
    }
    if args[0] == "coaching-checklist" || args[0] == "validate-checklist" {
        let document = try ReviewStore.load(from: URL(fileURLWithPath: args[1]))
        let destination = URL(fileURLWithPath: args[2])
        if args[0] == "validate-checklist" {
            let reviews = try CoachingChecklist.load(from: destination, frames: document.frames)
            let pending = document.frames.filter { $0.role == "subject" }.reduce(0) { total, frame in
                total + CoachingChecklist.rows(review: reviews[frame.id]).filter { $0.status == .needsReview }.count
            }
            print("Validated \(reviews.count) subject checklists; \(pending) topics still need review.")
        } else {
            guard !FileManager.default.fileExists(atPath: destination.path) else { throw PoseError.invalidInput("Checklist output already exists; use a new path to preserve findings.") }
            let reviews = document.frames.filter { $0.role == "subject" }.map { CoachingChecklistReview(frame: $0) }
            let encoder = JSONEncoder(); encoder.outputFormatting = [.prettyPrinted, .sortedKeys]
            try encoder.encode(reviews).write(to: destination, options: .withoutOverwriting)
            print("Created \(reviews.count) subject checklists. Findings await visual review.")
        }
        exit(0)
    }
    if args[0] == "import-coaching" {
        let url = URL(fileURLWithPath: args[1])
        let document = try ReviewStore.load(from: url)
        let contexts = try JSONDecoder().decode([PairContext].self, from: Data(contentsOf: URL(fileURLWithPath: args[2])))
        let updated = try PhotoCoachingImport.apply(contexts, to: document)
        try ReviewStore.save(updated, to: url, expectedRevision: document.revision)
        print("Saved photo coaching for \(contexts.count) pairs at revision \(updated.revision).")
        exit(0)
    }
    if args[0] == "redetect" {
        let request = try JSONDecoder().decode(RetryRequest.self, from: Data(contentsOf: URL(fileURLWithPath: args[1])))
        let destination = URL(fileURLWithPath: args[2])
        guard !FileManager.default.fileExists(atPath: destination.path) else { throw PoseError.invalidInput("Retry output already exists.") }
        try JSONEncoder().encode(request.run()).write(to: destination, options: .atomic)
        exit(0)
    }
    let report=try FeasibilityRunner.run(manifestURL:URL(fileURLWithPath:args[1]),outputDirectory:URL(fileURLWithPath:args[2]))
    print("Recorded \(report.crops.count) crop outcomes; inspect index.html and results.json. No coaching eligibility is implied.")
    if report.crops.contains(where: { $0.error != nil || $0.threeD?.status == "error" || $0.twoD?.status == "error" }) { exit(2) }
} catch {
    FileHandle.standardError.write(Data("Error: \(error.localizedDescription)\n".utf8)); exit(1)
}
