import XCTest

/// Screenshot every chapter of the textbook — one top + one bottom frame each —
/// so you can visually audit parsing / rendering issues across all 30 chapters.
final class AllChaptersScreenshotTests: XCTestCase {

    override func setUpWithError() throws {
        continueAfterFailure = true
    }

    func testScreenshotEveryChapter() throws {
        let app = XCUIApplication()
        app.launchArguments += ["-onboardingComplete", "YES"]
        app.launch()

        let courseTab = app.tabBars.buttons["Course"]
        XCTAssertTrue(courseTab.waitForExistence(timeout: 5))
        courseTab.tap()

        let textbookRow = app.buttons.containing(NSPredicate(
            format: "label CONTAINS[c] 'Complete Spanish'"
        )).firstMatch
        XCTAssertTrue(textbookRow.waitForExistence(timeout: 5))
        textbookRow.tap()

        // NOTE: SwiftUI List preserves scroll position across navigation pushes,
        // so visiting chapters in-order means the next one is already visible
        // after we return from the previous one. No need to reset.
        attach(app, name: "00-chapter-list-top")

        for chapter in 1...30 {
            guard let row = findChapterRow(app: app, chapter: chapter) else {
                XCTFail("Chapter \(chapter) row not reachable")
                continue
            }
            row.tap()

            // Chapter body — wait until the chapter's title appears as a nav bar label
            _ = app.navigationBars.firstMatch.waitForExistence(timeout: 3)

            attach(app, name: String(format: "ch%02d-top", chapter))
            // One big scroll to sample the bottom of the chapter
            dragFullScreen(app, direction: .up)
            dragFullScreen(app, direction: .up)
            attach(app, name: String(format: "ch%02d-bottom", chapter))

            tapNavBack(app)
            // Small settle wait
            _ = app.navigationBars.firstMatch.waitForExistence(timeout: 2)
        }
    }

    // MARK: - Helpers

    private enum DragDirection { case up, down }

    private func dragFullScreen(_ app: XCUIApplication, direction: DragDirection) {
        let top = app.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.12))
        let bot = app.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.88))
        switch direction {
        case .up:   bot.press(forDuration: 0.1, thenDragTo: top)
        case .down: top.press(forDuration: 0.1, thenDragTo: bot)
        }
    }

    private func findChapterRow(app: XCUIApplication, chapter: Int) -> XCUIElement? {
        // Chapter row accessibility label: "<n>, <title>, ..." (SwiftUI composes
        // label from inner Texts). Match by starting number.
        let predicate = NSPredicate(format: "label BEGINSWITH %@", "\(chapter),")
        let row = app.buttons.matching(predicate).firstMatch

        if row.exists && row.isHittable { return row }

        // Scroll down up to 8 times searching for the row — chapters visited
        // in order, so usually 0–2 swipes suffice.
        for _ in 0..<8 {
            if row.exists && row.isHittable { return row }
            dragFullScreen(app, direction: .up)
        }
        return row.exists ? row : nil
    }

    private func tapNavBack(_ app: XCUIApplication) {
        let back = app.navigationBars.buttons.firstMatch
        if back.exists && back.isHittable { back.tap() }
    }

    private func attach(_ app: XCUIApplication, name: String) {
        let screenshot = app.screenshot()
        let attachment = XCTAttachment(screenshot: screenshot)
        attachment.name = name
        attachment.lifetime = .keepAlways
        add(attachment)
    }
}
