//
//  DayScreen.swift
//  Tests iOS
//
//  Screen object for the Day (main) view — mood logging and entry list.
//

import XCTest

struct DayScreen {
    let app: XCUIApplication

    // MARK: - Mood Buttons (via accessibilityIdentifier)

    var greatButton: XCUIElement { app.buttons["mood_button_great"] }
    var goodButton: XCUIElement { app.buttons["mood_button_good"] }
    var averageButton: XCUIElement { app.buttons["mood_button_average"] }
    var badButton: XCUIElement { app.buttons["mood_button_bad"] }
    var horribleButton: XCUIElement { app.buttons["mood_button_horrible"] }

    /// The mood header container
    var moodHeader: XCUIElement { app.element(UITestID.Day.moodHeader) }

    // MARK: - Entry List

    /// Find an entry row by its raw identifier date payload (yyyyMMdd).
    func entryRow(dateString: String) -> XCUIElement {
        app.element("\(UITestID.Day.entryRowPrefix)\(dateString)")
    }

    var anyEntryRow: XCUIElement {
        app.firstEntryRow
    }

    // MARK: - Actions

    /// Tap a mood button by mood name. Waits for the celebration animation to complete.
    func logMood(_ mood: MoodChoice, file: StaticString = #file, line: UInt = #line) {
        let button = moodButton(for: mood)
        guard button.waitForExistence(timeout: 5) else {
            XCTFail("Mood button '\(mood.rawValue)' not found", file: file, line: line)
            return
        }
        button.tapWhenReady(timeout: 5, file: file, line: line)

        // Wait for the celebration animation to finish and entry to appear.
        // The mood header disappears after logging today's mood.
        // Give extra time for animation + data save.
        _ = moodHeader.waitForDisappearance(timeout: 8)
    }

    // MARK: - Assertions

    func assertMoodHeaderVisible(file: StaticString = #file, line: UInt = #line) {
        XCTAssertTrue(
            moodHeader.waitForExistence(timeout: 5),
            "Mood voting header should be visible",
            file: file, line: line
        )
    }

    func assertMoodHeaderHidden(file: StaticString = #file, line: UInt = #line) {
        // After logging, the header should either disappear or the buttons should not be hittable
        let hidden = moodHeader.waitForDisappearance(timeout: 8)
        XCTAssertTrue(hidden, "Mood header should be hidden after logging today's mood", file: file, line: line)
    }

    func assertEntryExists(dateString: String, file: StaticString = #file, line: UInt = #line) {
        let row = entryRow(dateString: dateString)
        XCTAssertTrue(
            row.waitForExistence(timeout: 5),
            "Entry row for \(dateString) should exist",
            file: file, line: line
        )
    }

    func assertAnyEntryExists(file: StaticString = #file, line: UInt = #line) {
        XCTAssertTrue(
            anyEntryRow.waitForExistence(timeout: 5),
            "At least one entry row should exist",
            file: file, line: line
        )
    }

    // MARK: - Private

    private func moodButton(for mood: MoodChoice) -> XCUIElement {
        switch mood {
        case .great: return greatButton
        case .good: return goodButton
        case .average: return averageButton
        case .bad: return badButton
        case .horrible: return horribleButton
        }
    }
}

/// Represents the 5 selectable mood values for test code.
enum MoodChoice: String {
    case great, good, average, bad, horrible
}
