import Foundation
import ForgejoKit
import SwiftUI
import Testing
@testable import Forji

struct WorkflowStatusIconTests {

    @Test func successShowsCheckmark() {
        let style = WorkflowStatusStyle.forStatus("success")
        #expect(style.symbol == "checkmark.circle.fill")
        #expect(style.isAnimated == false)
        #expect(style.label == "Success")
    }

    @Test func failureShowsXmark() {
        let style = WorkflowStatusStyle.forStatus("failure")
        #expect(style.symbol == "xmark.circle.fill")
        #expect(style.label == "Failed")
    }

    @Test func cancelledShowsSlash() {
        let style = WorkflowStatusStyle.forStatus("cancelled")
        #expect(style.symbol == "slash.circle.fill")
    }

    @Test func skippedShowsForward() {
        let style = WorkflowStatusStyle.forStatus("skipped")
        #expect(style.symbol == "forward.circle.fill")
    }

    @Test func runningIsAnimated() {
        let style = WorkflowStatusStyle.forStatus("running")
        #expect(style.symbol == "circle.dotted")
        #expect(style.isAnimated == true)
    }

    @Test func waitingShowsClock() {
        let style = WorkflowStatusStyle.forStatus("waiting")
        #expect(style.symbol == "clock")
    }

    @Test func blockedShowsHand() {
        let style = WorkflowStatusStyle.forStatus("blocked")
        #expect(style.symbol == "hand.raised.fill")
    }

    @Test func unknownStatusShowsQuestionMark() {
        let style = WorkflowStatusStyle.forStatus("unknown")
        #expect(style.symbol == "questionmark.circle")
    }

    @Test func arbitraryStatusFallsBackToQuestionMark() {
        let style = WorkflowStatusStyle.forStatus("weird")
        #expect(style.symbol == "questionmark.circle")
        #expect(style.label == "Weird")
    }

    // MARK: - WorkflowRun helpers

    @Test func shortCommitShaTruncatesToSeven() {
        let run = WorkflowRun(
            id: 1, status: "success",
            commitSha: "abcdef0123456789",
        )
        #expect(run.shortCommitSha == "abcdef0")
    }

    @Test func shortCommitShaPassesThroughIfShorter() {
        let run = WorkflowRun(id: 1, status: "success", commitSha: "abc")
        #expect(run.shortCommitSha == "abc")
    }

    @Test func shortCommitShaIsNilWhenSourceIsNil() {
        let run = WorkflowRun(id: 1, status: "success")
        #expect(run.shortCommitSha == nil)
    }

    @Test func displayNamePrefersTitle() {
        let run = WorkflowRun(
            id: 1, title: "Fix login bug", status: "success",
            workflowId: "ci.yml", indexInRepo: 5,
        )
        #expect(run.displayName == "Fix login bug")
    }

    @Test func displayNameFallsBackToWorkflowId() {
        let run = WorkflowRun(
            id: 1, title: nil, status: "running",
            workflowId: "ci.yml", indexInRepo: 5,
        )
        #expect(run.displayName == "ci.yml")
    }

    @Test func displayNameFallsBackWhenTitleIsEmpty() {
        let run = WorkflowRun(
            id: 1, title: "", status: "running",
            workflowId: "ci.yml", indexInRepo: 5,
        )
        #expect(run.displayName == "ci.yml")
    }

    @Test func displayNameFallsBackToIndex() {
        let run = WorkflowRun(
            id: 1, title: nil, status: "running", indexInRepo: 7,
        )
        #expect(run.displayName == "Run #7")
    }

    @Test func displayNameFallsBackToIdWhenNothingElse() {
        let run = WorkflowRun(id: 99, status: "running")
        #expect(run.displayName == "Run 99")
    }

    @Test func durationFromNanos() {
        let run = WorkflowRun(id: 1, status: "success", durationNanos: 90_000_000_000)
        #expect(run.duration == 90)
    }

    @Test func durationFallsBackToTimestamps() {
        // Both timestamps must be sane (post-2000) for the fallback to apply.
        let start = Date(timeIntervalSince1970: 1_700_000_000)
        let stop = Date(timeIntervalSince1970: 1_700_000_120)
        let run = WorkflowRun(
            id: 1, status: "success",
            started: start, stopped: stop, durationNanos: 0,
        )
        #expect(run.duration == 120)
    }

    @Test func durationIsNilWithNoData() {
        let run = WorkflowRun(id: 1, status: "running")
        #expect(run.duration == nil)
    }

    // MARK: - Sanitised date helpers (zero-Date guard)

    @Test func startedDisplayHidesPre2000Date() {
        // Forgejo's unset time.Time decodes to year 0001.
        let zero = Date(timeIntervalSince1970: -62_135_596_800)
        let run = WorkflowRun(id: 1, status: "cancelled", started: zero)
        #expect(run.startedDisplay == nil)
    }

    @Test func startedDisplayKeepsRecentDate() {
        let recent = Date(timeIntervalSince1970: 1_700_000_000)
        let run = WorkflowRun(id: 1, status: "success", started: recent)
        #expect(run.startedDisplay == recent)
    }

    @Test func durationIsNilWhenStartedIsZeroDate() {
        // Bogus duration ("493 906h") came from `stopped - zeroStarted`.
        let zero = Date(timeIntervalSince1970: -62_135_596_800)
        let now = Date(timeIntervalSince1970: 1_700_000_000)
        let run = WorkflowRun(
            id: 1, status: "cancelled",
            started: zero, stopped: now, durationNanos: 0,
        )
        #expect(run.duration == nil)
    }
}
