import XCTest

final class MergedInstanceReadOnlyUITests: XCTestCase, UITestNavigating {

    static var sharedApp: XCUIApplication!
    static var sharedServerURL: String!

    override class func setUp() {
        super.setUp()

        guard let url = ForgejoUITestBase.resolveTestServerURL(),
            !url.isEmpty
        else { return }
        sharedServerURL = url

        guard let url2 = resolveSecondServerURL(), !url2.isEmpty else { return }

        let app = XCUIApplication()

        // Reset data and add first instance
        app.launchArguments = ["-dev_skipAutoLogin", "true", "-dev_resetData", "true"]
        app.launch()
        app.terminate()

        addInstance(app: app, serverURL: url)
        addInstance(app: app, serverURL: url2)

        // Relaunch to instance list and enter merged mode
        app.launchArguments = ["-dev_skipAutoLogin", "true"]
        app.launch()

        let allRow = app.buttons["all-instances-row"]
        guard allRow.waitForExistence(timeout: 10) else {
            XCTFail("All Instances row not found in class setUp")
            return
        }
        allRow.tap()

        let reposTab = app.tabBars.buttons["Repositories"]
        guard reposTab.waitForExistence(timeout: 20) else {
            XCTFail("Merged HomeView did not load in class setUp")
            return
        }
        sharedApp = app
    }

    override class func tearDown() {
        sharedApp = nil
        sharedServerURL = nil
        super.tearDown()
    }

    var app: XCUIApplication! { Self.sharedApp }
    var serverURL: String! { Self.sharedServerURL }

    override func setUpWithError() throws {
        continueAfterFailure = true

        guard Self.sharedServerURL != nil, Self.sharedApp != nil else {
            throw XCTSkip("Integration server not running or merged setup failed")
        }

        XCUIDevice.shared.orientation = .portrait

        // Ensure we're on the Repositories tab
        let reposTab = app.tabBars.buttons["Repositories"]
        if reposTab.exists && reposTab.isHittable {
            reposTab.tap()
        }
    }

    func navigateToRepoDetail(_ repoName: String = "test-repo") {
        app.tabBars.buttons["Repositories"].tap()
        let repoCell = app.staticTexts[repoName].firstMatch
        XCTAssertTrue(repoCell.waitForExistence(timeout: 10))
        repoCell.tap()
    }

    // MARK: - Tests

    @MainActor
    func testMergedViewLoads() throws {
        let reposTab = app.tabBars.buttons["Repositories"]
        XCTAssertTrue(reposTab.waitForExistence(timeout: 5), "Merged view should be loaded")
    }

    @MainActor
    func testMergedIssuesShowInstanceBadges() throws {
        app.tabBars.buttons["Issues"].tap()

        let badge = app.staticTexts.matching(identifier: "instance-badge")
        XCTAssertTrue(
            badge.firstMatch.waitForExistence(timeout: 15),
            "Instance badges should appear in merged issues view"
        )
    }

    @MainActor
    func testMergedPullRequestsShowInstanceBadges() throws {
        app.tabBars.buttons["Pull Requests"].tap()

        let badge = app.staticTexts.matching(identifier: "instance-badge")
        XCTAssertTrue(
            badge.firstMatch.waitForExistence(timeout: 15),
            "Instance badges should appear in merged PRs view"
        )
    }

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

        let navTitle = app.navigationBars["Notifications"]
        XCTAssertTrue(navTitle.waitForExistence(timeout: 10), "Notifications tab should load in merged mode")
    }

    // MARK: - Helpers

    private static func addInstance(
        app: XCUIApplication,
        serverURL url: String,
        username: String = "testadmin",
        password: String = "admin1234"
    ) {
        app.launchArguments = [
            "-dev_serverURL", url,
            "-dev_username", username,
            "-dev_password", password,
            "-dev_skipAutoLogin", "true",
        ]
        app.launch()

        let addButton = app.buttons["instance-add-button"]
        guard addButton.waitForExistence(timeout: 15) else {
            XCTFail("Instance list did not appear for \(url)")
            return
        }
        addButton.tap()

        app.swipeUp()

        let loginButton = app.buttons["login-button"]
        guard loginButton.waitForExistence(timeout: 5) else {
            XCTFail("Login button not found for \(url)")
            return
        }
        loginButton.tap()

        let reposTab = app.tabBars.buttons["Repositories"]
        guard reposTab.waitForExistence(timeout: 20) else {
            XCTFail("HomeView did not appear after login for \(url)")
            return
        }
    }

    private static func resolveSecondServerURL() -> String? {
        let deviceName = (ProcessInfo.processInfo.environment["SIMULATOR_DEVICE_NAME"] ?? "")
            .replacingOccurrences(of: " ", with: "_")
        let specificPath = "/tmp/forgejo_test_url2_\(deviceName).txt"
        let genericPath = "/tmp/forgejo_test_url2.txt"

        return ((try? String(contentsOfFile: specificPath, encoding: .utf8))
            ?? (try? String(contentsOfFile: genericPath, encoding: .utf8)))
            .map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
    }
}
