import XCTest
@testable import PoseCore

final class PairWorkflowTests: XCTestCase {
    func testBothRidersWithdrawalUndoFailedSaveAndReopen() throws {
        let folder = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString)
        try FileManager.default.createDirectory(at: folder, withIntermediateDirectories: true)
        defer { try? FileManager.default.removeItem(at: folder) }
        let url = folder.appendingPathComponent("review.json")
        var doc = try reviewedPair()
        let pair = try XCTUnwrap(PairReview.resolve(doc.frames).first)
        try ReviewStore.save(doc, to: url, expectedRevision: nil)
        for i in doc.frames.indices {
            try doc.frames[i].setJoint("left_elbow", point: Point2(x: 200 + Double(i) * 10, y: 210), state: .corrected)
            doc.revision += 1
        }
        let edited = try PairAnalysis.analyze(doc, pair: pair)
        let before = doc.frames[0].edits["left_knee"]
        try doc.frames[0].setJoint("left_knee", point: nil, state: .occluded); doc.revision += 1
        XCTAssertNil(try PairAnalysis.analyze(doc, pair: pair).observations.first { $0.feature == .leftKnee }?.delta)
        doc.frames[0].restore("left_knee", to: before); doc.revision += 1
        XCTAssertEqual(try PairAnalysis.analyze(doc, pair: pair).observations, edited.observations)
        let disk = try Data(contentsOf: url)
        XCTAssertThrowsError(try ReviewStore.save(doc, to: url, expectedRevision: 999))
        XCTAssertEqual(try Data(contentsOf: url), disk)
        XCTAssertEqual(try PairAnalysis.analyze(doc, pair: pair).revision, 4)
        XCTAssertEqual(try PairAnalysis.analyze(ReviewStore.load(from: url), pair: pair).revision, 0)
        try ReviewStore.save(doc, to: url, expectedRevision: 0)
        let reopened = try ReviewStore.load(from: url)
        XCTAssertEqual(try PairAnalysis.analyze(reopened, pair: pair), try PairAnalysis.analyze(doc, pair: pair))
        for (a, b) in zip(doc.frames, reopened.frames) { XCTAssertEqual(a.edits, b.edits); XCTAssertEqual(a.history.count, b.history.count) }
    }
    func testRetryOnlySeedsDoNotQualifyOrChangeReviewedFindings() throws {
        var doc = pairDocument()
        let pair = try XCTUnwrap(PairReview.resolve(doc.frames).first)
        let pose = PoseResult(kind: "2D", status: "needsReview", requestRevision: 1, durationSeconds: 0,
            joints: [JointResult(name: "left_elbow", point: Point2(x: 20, y: 20), confidence2D: 1)], candidateCount: 1)
        let initial = try PairAnalysis.analyze(doc, pair: pair)
        doc.frames[0].addRetry(DetectionRetry(crop: doc.frames[0].panel, twoD: pose, threeD: nil)); doc.revision += 1
        XCTAssertNotNil(doc.frames[0].displayPoint("left_elbow", kind: "2D"))
        let retried = try PairAnalysis.analyze(doc, pair: pair)
        XCTAssertEqual(retried.observations, initial.observations)
        XCTAssertEqual(retried.focus, initial.focus)
        XCTAssertEqual(retried.revision, 1)
    }
}
