import XCTest

/// Task management tests.
/// Precondition: at least one residence must exist (task creation requires it).
final class Suite5_TaskTests: AuthenticatedUITestCase {

    override var needsAPISession: Bool { true }
    override var testCredentials: (username: String, password: String) { ("testuser", "TestPass123!") }
    override var apiCredentials: (username: String, password: String) { ("testuser", "TestPass123!") }

    override func setUpWithError() throws {
        try super.setUpWithError()

        // Precondition: residence must exist for task add button
        ensureResidenceExists()

        // Dismiss any open form from previous test
        let cancelButton = app.buttons[AccessibilityIdentifiers.Task.formCancelButton].firstMatch
        if cancelButton.exists { cancelButton.tap() }

        navigateToTasks()
        // Wait for task screen to load
        let addButton = app.buttons[AccessibilityIdentifiers.Task.addButton].firstMatch
        addButton.waitForExistenceOrFail(timeout: navigationTimeout, message: "Task add button should appear")
    }

    // MARK: - 1. Validation

    func test01_cancelTaskCreation() {
        let addButton = app.buttons[AccessibilityIdentifiers.Task.addButton].firstMatch
        addButton.tap()

        let titleField = app.textFields[AccessibilityIdentifiers.Task.titleField].firstMatch
        titleField.waitForExistenceOrFail(timeout: defaultTimeout, message: "Task form should open")

        let cancelButton = app.buttons[AccessibilityIdentifiers.Task.formCancelButton].firstMatch
        cancelButton.waitForExistenceOrFail(timeout: defaultTimeout, message: "Cancel button should exist")
        cancelButton.tap()

        // Verify we're back on the task list
        let addButtonAgain = app.buttons[AccessibilityIdentifiers.Task.addButton].firstMatch
        XCTAssertTrue(addButtonAgain.waitForExistence(timeout: navigationTimeout), "Should be back on tasks list after cancel")
    }

    // MARK: - 2. View/List

    func test02_tasksTabExists() {
        let tabBar = app.tabBars.firstMatch
        XCTAssertTrue(tabBar.exists, "Tab bar should exist")
        let addButton = app.buttons[AccessibilityIdentifiers.Task.addButton].firstMatch
        XCTAssertTrue(addButton.exists, "Task add button should exist (proves we're on Tasks tab)")
    }

    func test03_viewTasksList() {
        // Tasks screen should show — verified by the add button existence from setUp
        let addButton = app.buttons[AccessibilityIdentifiers.Task.addButton].firstMatch
        XCTAssertTrue(addButton.exists, "Tasks screen should be visible with add button")
    }

    func test04_addTaskButtonEnabled() {
        let addButton = app.buttons[AccessibilityIdentifiers.Task.addButton].firstMatch
        XCTAssertTrue(addButton.isEnabled, "Task add button should be enabled when residence exists")
    }

    func test05_navigateToAddTask() {
        let addButton = app.buttons[AccessibilityIdentifiers.Task.addButton].firstMatch
        addButton.tap()

        let titleField = app.textFields[AccessibilityIdentifiers.Task.titleField].firstMatch
        titleField.waitForExistenceOrFail(timeout: defaultTimeout, message: "Task title field should appear in add form")

        let saveButton = app.buttons[AccessibilityIdentifiers.Task.saveButton].firstMatch
        XCTAssertTrue(saveButton.exists, "Save button should exist in add task form")

        // Clean up: dismiss form
        let cancelButton = app.buttons[AccessibilityIdentifiers.Task.formCancelButton].firstMatch
        if cancelButton.exists { cancelButton.tap() }
    }

    // MARK: - 3. Creation

    func test06_createBasicTask() {
        let addButton = app.buttons[AccessibilityIdentifiers.Task.addButton].firstMatch
        addButton.tap()

        let titleField = app.textFields[AccessibilityIdentifiers.Task.titleField].firstMatch
        titleField.waitForExistenceOrFail(timeout: defaultTimeout, message: "Task title field should appear")

        let timestamp = Int(Date().timeIntervalSince1970)
        let taskTitle = "UITest Task \(timestamp)"
        fillTextField(identifier: AccessibilityIdentifiers.Task.titleField, text: taskTitle)

        dismissKeyboard()
        app.swipeUp()

        let saveButton = app.buttons[AccessibilityIdentifiers.Task.saveButton].firstMatch
        saveButton.waitForExistenceOrFail(timeout: defaultTimeout, message: "Save button should exist")
        saveButton.tap()

        // Wait for form to dismiss
        _ = saveButton.waitForNonExistence(timeout: navigationTimeout)

        // Verify task was created via API (also gives the server time to process)
        if let items = TestAccountAPIClient.listTasks(token: session.token),
           let created = items.first(where: { $0.title.contains(taskTitle) }) {
            cleaner.trackTask(created.id)
        }

        // Navigate to tasks tab and refresh to pick up the newly created task
        navigateToTasks()
        refreshTasks()
        let taskListScreen = TaskListScreen(app: app)
        let newTask = taskListScreen.findTask(title: taskTitle)
        XCTAssertTrue(newTask.waitForExistence(timeout: loginTimeout), "New task '\(taskTitle)' should appear in the list")
    }

    // MARK: - 4. View Details

    func test07_viewTaskDetails() {
        // Create a task first
        let timestamp = Int(Date().timeIntervalSince1970)
        let taskTitle = "UITest Detail \(timestamp)"

        let addButton = app.buttons[AccessibilityIdentifiers.Task.addButton].firstMatch
        addButton.tap()

        fillTextField(identifier: AccessibilityIdentifiers.Task.titleField, text: taskTitle)
        dismissKeyboard()
        app.swipeUp()

        let saveButton = app.buttons[AccessibilityIdentifiers.Task.saveButton].firstMatch
        saveButton.waitForExistenceOrFail(timeout: defaultTimeout)
        saveButton.tap()
        _ = saveButton.waitForNonExistence(timeout: navigationTimeout)

        // Verify task was created via API (also gives the server time to process)
        if let items = TestAccountAPIClient.listTasks(token: session.token),
           let created = items.first(where: { $0.title.contains(taskTitle) }) {
            cleaner.trackTask(created.id)
        }

        // Navigate to tasks tab and refresh to pick up the newly created task
        navigateToTasks()
        refreshTasks()
        let taskListScreen = TaskListScreen(app: app)
        let taskCard = taskListScreen.findTask(title: taskTitle)
        taskCard.waitForExistenceOrFail(timeout: loginTimeout, message: "Created task should appear in list")

        // Verify the task card is accessible and the actions menu exists
        // (There is no task detail screen — cards are self-contained with a context menu)
        let actionsMenu = app.buttons["Task actions"].firstMatch
        XCTAssertTrue(actionsMenu.waitForExistence(timeout: navigationTimeout), "Task actions menu should be accessible")
    }

    // MARK: - 5. Navigation

    func test08_navigateToContractors() {
        navigateToContractors()
        let addButton = app.buttons[AccessibilityIdentifiers.Contractor.addButton].firstMatch
        XCTAssertTrue(addButton.waitForExistence(timeout: navigationTimeout), "Contractors screen should load")
    }

    func test09_navigateToDocuments() {
        navigateToDocuments()
        let addButton = app.buttons[AccessibilityIdentifiers.Document.addButton].firstMatch
        XCTAssertTrue(addButton.waitForExistence(timeout: navigationTimeout), "Documents screen should load")
    }

    func test10_navigateBetweenTabs() {
        navigateToResidences()
        let resAddButton = app.buttons[AccessibilityIdentifiers.Residence.addButton].firstMatch
        XCTAssertTrue(resAddButton.waitForExistence(timeout: navigationTimeout), "Residences screen should load")

        navigateToTasks()
        let taskAddButton = app.buttons[AccessibilityIdentifiers.Task.addButton].firstMatch
        XCTAssertTrue(taskAddButton.waitForExistence(timeout: navigationTimeout), "Tasks screen should load after navigating back")
    }
}
