import XCTest

final class PullRequestMutatingUITests: ForgejoUITestBase {

    // MARK: - PR Tab Actions (add comment, edit sheet, submit review, close/reopen)

    @MainActor
    func testPRTabActions() throws {
        loginAndWaitForHome()
        navigateToPRTab()

        let prCell = app.staticTexts["Add feature file"].firstMatch
        XCTAssertTrue(prCell.waitForExistence(timeout: 10))
        prCell.tap()

        XCTAssertTrue(app.staticTexts["pr-detail-title"].waitForExistence(timeout: 10))

        // Add comment via sheet
        expandActionMenu()
        let commentButton = app.buttons["pr-comment-button"]
        XCTAssertTrue(commentButton.waitForExistence(timeout: 5))
        commentButton.tap()

        XCTAssertTrue(app.staticTexts["New Comment"].waitForExistence(timeout: 5))

        let commentEditor = app.textViews["markdown-text-editor"].firstMatch
        XCTAssertTrue(commentEditor.waitForExistence(timeout: 5))
        commentEditor.tap()
        commentEditor.typeText("UI test comment on PR")

        let submitButton = app.buttons["Submit"]
        XCTAssertTrue(submitButton.waitForExistence(timeout: 5))
        submitButton.tap()

        // Wait for sheet to dismiss and scroll to bottom to find new comment
        XCTAssertTrue(app.staticTexts["pr-detail-title"].waitForExistence(timeout: 10))
        app.swipeUp()
        app.swipeUp()
        XCTAssertTrue(app.staticTexts["UI test comment on PR"].waitForExistence(timeout: 10))

        // Scroll back up
        app.swipeDown()
        app.swipeDown()

        // Edit sheet
        expandActionMenu()
        let editButton = app.buttons["pr-edit-button"]
        XCTAssertTrue(editButton.waitForExistence(timeout: 5))
        editButton.tap()

        let titleField = app.textFields["pr-edit-title-field"]
        XCTAssertTrue(titleField.waitForExistence(timeout: 5))
        app.buttons["Cancel"].tap()
        XCTAssertTrue(app.staticTexts["pr-detail-title"].waitForExistence(timeout: 10))

        // Submit review sheet
        app.swipeUp()

        expandActionMenu()
        let reviewButton = app.buttons["pr-submit-review"]
        XCTAssertTrue(reviewButton.waitForExistence(timeout: 10))
        reviewButton.tap()

        XCTAssertTrue(app.staticTexts["Submit Review"].waitForExistence(timeout: 5))
        XCTAssertTrue(app.staticTexts["Approve"].waitForExistence(timeout: 5))
        app.buttons["Cancel"].tap()

        // Close and reopen
        expandActionMenu()
        let closeButton = app.buttons["pr-toggle-state"]
        XCTAssertTrue(closeButton.waitForExistence(timeout: 10))
        closeButton.tap()

        app.swipeDown()
        app.swipeDown()
        XCTAssertTrue(app.staticTexts["Closed"].waitForExistence(timeout: 10))

        app.swipeUp()
        expandActionMenu()
        let reopenButton = app.buttons["pr-toggle-state"]
        XCTAssertTrue(reopenButton.waitForExistence(timeout: 5))
        reopenButton.tap()

        app.swipeDown()
        app.swipeDown()
        XCTAssertTrue(app.staticTexts["Open"].waitForExistence(timeout: 10))
    }

    // MARK: - PR Merge Button from Overview

    @MainActor
    func testPRMergeButtonVisibleFromOverview() throws {
        loginAndWaitForHome()

        app.tabBars.buttons["Pull Requests"].tap()

        let prCell = app.staticTexts["Add feature file"].firstMatch
        XCTAssertTrue(prCell.waitForExistence(timeout: 10))
        prCell.tap()

        XCTAssertTrue(app.staticTexts["pr-detail-title"].waitForExistence(timeout: 10))

        app.swipeUp()
        expandActionMenu()

        let mergeButton = app.buttons["pr-merge-button"]
        XCTAssertTrue(
            mergeButton.waitForExistence(timeout: 10),
            "Merge button should be visible when navigating from Pull Requests overview"
        )
    }

    // MARK: - PR Merge Methods

    @MainActor
    func testPRMergeCommit() throws {
        loginAndWaitForHome()
        mergePR(titled: "Merge test PR", method: "Merge Commit")
    }

    @MainActor
    func testPRSquashMerge() throws {
        loginAndWaitForHome()
        mergePR(titled: "Squash merge test PR", method: "Squash")
    }

    @MainActor
    func testPRRebaseMerge() throws {
        loginAndWaitForHome()
        mergePR(titled: "Rebase merge test PR", method: "Rebase")
    }

    // MARK: - Merge Helper

    private func mergePR(titled prTitle: String, method: String) {
        navigateToPRTab()

        let prCell = app.staticTexts[prTitle].firstMatch
        XCTAssertTrue(prCell.waitForExistence(timeout: 10), "PR '\(prTitle)' not found")
        prCell.tap()

        XCTAssertTrue(app.staticTexts["pr-detail-title"].waitForExistence(timeout: 10))

        app.swipeUp()

        expandActionMenu()
        let mergeButton = app.buttons["pr-merge-button"]
        XCTAssertTrue(mergeButton.waitForExistence(timeout: 10), "Merge button not found for '\(prTitle)'")
        mergeButton.tap()

        XCTAssertTrue(app.staticTexts["Merge Pull Request"].waitForExistence(timeout: 5))

        // Select merge method
        let methodPicker = app.segmentedControls["merge-method-picker"]
        XCTAssertTrue(methodPicker.waitForExistence(timeout: 5))
        methodPicker.buttons[method].tap()

        // Confirm merge
        let mergeConfirm = app.buttons["merge-confirm"]
        XCTAssertTrue(mergeConfirm.waitForExistence(timeout: 5))
        mergeConfirm.tap()

        // Verify merge succeeded: wait for PR detail to reappear (sheet dismissed)
        XCTAssertTrue(
            app.staticTexts["pr-detail-title"].waitForExistence(timeout: 15),
            "Should return to PR detail after successful \(method) merge"
        )
    }
}
