import XCTest

final class PaginationUITests: ForgejoReadOnlyUITestBase {

    override func tearDown() {
        navigateBackToHome()
        super.tearDown()
    }

    // MARK: - Issue List Pagination

    @MainActor
    func testIssueListPaginationLoadsAllItems() throws {
        navigateToRepoDetail("test-repo-2")
        app.buttons["Issues"].firstMatch.tap()

        // Wait for page 1 issues to load (25 issues in test-repo-2, page size 20)
        XCTAssertTrue(app.staticTexts["Pagination test issue 25"].waitForExistence(timeout: 10),
                       "Should show recent issues on page 1")

        // Scroll to bottom to trigger page 2 auto-load
        for _ in 0..<10 {
            app.swipeUp()
        }

        // Verify older issues from page 2 have loaded
        let olderIssue = app.staticTexts["Pagination test issue 1"]
        var found = false
        for _ in 0..<5 {
            if olderIssue.exists {
                found = true
                break
            }
            app.swipeUp()
            // Wait for element to appear instead of fixed sleep
            if olderIssue.waitForExistence(timeout: 2) {
                found = true
                break
            }
        }
        XCTAssertTrue(found, "Page 2 issues should have loaded after scrolling to bottom")
    }

    @MainActor
    func testIssueListFilterResetsPagination() throws {
        navigateToIssueTab()

        // Wait for open issues to load (test-repo has only 2 open issues)
        XCTAssertTrue(app.staticTexts["Test issue 1 from integration tests"].waitForExistence(timeout: 10))

        // Switch to Closed filter
        let closedButton = app.buttons["Closed"]
        XCTAssertTrue(closedButton.waitForExistence(timeout: 5))
        closedButton.tap()

        // Only 1 closed issue (#3), should not show load-more
        XCTAssertTrue(app.staticTexts["Test issue 3 from integration tests"].waitForExistence(timeout: 10))

        let loadMore = app.activityIndicators["load-more-indicator"]
        // Wait briefly for UI to settle, then check absence
        _ = loadMore.waitForExistence(timeout: 2)
        XCTAssertFalse(loadMore.exists, "load-more should not exist with <20 closed issues")
    }

    // MARK: - Pull Request List (few items)

    @MainActor
    func testPullRequestListNoLoadMoreWhenFewItems() throws {
        navigateToPRTab()

        // Only 2 PRs exist
        XCTAssertTrue(app.staticTexts["Add feature file"].waitForExistence(timeout: 10))
        XCTAssertTrue(app.staticTexts["Merge test PR"].waitForExistence(timeout: 5))

        let loadMore = app.activityIndicators["load-more-indicator"]
        _ = loadMore.waitForExistence(timeout: 2)
        XCTAssertFalse(loadMore.exists, "load-more should not exist when there are only 2 PRs")
    }

    // MARK: - Notifications (few items)

    @MainActor
    func testNotificationsLoadWithoutLoadMore() throws {
        app.tabBars.buttons["Notifications"].tap()

        // Wait for notifications to load
        let firstNotification = app.staticTexts["Test issue 1 from integration tests"]
        XCTAssertTrue(firstNotification.waitForExistence(timeout: 15),
                       "Should show at least one notification")

        let loadMore = app.activityIndicators["load-more-indicator"]
        _ = loadMore.waitForExistence(timeout: 2)
        XCTAssertFalse(loadMore.exists, "load-more should not exist with few notifications")
    }
}
