//
//  BaseUITestCase.swift
//  Tests iOS
//
//  Base class for all UI tests. Handles launch arguments,
//  state reset, and screenshot capture on failure.
//

import XCTest

class BaseUITestCase: XCTestCase {

    var app: XCUIApplication!

    // MARK: - Configuration (override in subclasses)

    /// Fixture to seed. Override to use a specific data set.
    var seedFixture: String? { nil }

    /// Whether to bypass the subscription paywall. Default: true.
    var bypassSubscription: Bool { true }

    /// Whether to skip onboarding. Default: true.
    var skipOnboarding: Bool { true }

    /// Whether to force the trial to be expired. Default: false.
    var expireTrial: Bool { false }

    // MARK: - Lifecycle

    override func setUp() {
        super.setUp()
        continueAfterFailure = false

        app = launchApp(resetState: true)
    }

    override func tearDown() {
        if let failure = testRun?.failureCount, failure > 0 {
            captureScreenshot(name: "FAILURE-\(name)")
        }
        app = nil
        super.tearDown()
    }

    // MARK: - Launch Configuration

    private func buildLaunchArguments(resetState: Bool) -> [String] {
        var args = ["--ui-testing", "--disable-animations", "-AppleLanguages", "(en)", "-AppleLocale", "en_US"]
        if resetState {
            args.append("--reset-state")
        }
        if bypassSubscription {
            args.append("--bypass-subscription")
        }
        if skipOnboarding {
            args.append("--skip-onboarding")
        }
        if expireTrial {
            args.append("--expire-trial")
        }
        return args
    }

    private func buildLaunchEnvironment() -> [String: String] {
        var env = [String: String]()
        if let fixture = seedFixture {
            env["UI_TEST_FIXTURE"] = fixture
        }
        return env
    }

    // MARK: - Screenshots

    func captureScreenshot(name: String) {
        let screenshot = XCTAttachment(screenshot: app.screenshot())
        screenshot.name = name
        screenshot.lifetime = .keepAlways
        add(screenshot)
    }

    // MARK: - Shared Test Utilities

    @discardableResult
    func launchApp(resetState: Bool) -> XCUIApplication {
        let application = XCUIApplication()
        application.launchArguments = buildLaunchArguments(resetState: resetState)
        application.launchEnvironment = buildLaunchEnvironment()
        application.launch()
        return application
    }

    @discardableResult
    func relaunchPreservingState() -> XCUIApplication {
        app.terminate()
        let relaunched = launchApp(resetState: false)
        app = relaunched
        return relaunched
    }

    func assertDayContentVisible(timeout: TimeInterval = 8, file: StaticString = #file, line: UInt = #line) {
        let hasEntry = app.firstEntryRow.waitForExistence(timeout: timeout)
        let hasMoodHeader = app.element(UITestID.Day.moodHeader).waitForExistence(timeout: 2)
        XCTAssertTrue(hasEntry || hasMoodHeader, "Day view should show entry list or mood header", file: file, line: line)
    }
}
