/** @vitest-environment jsdom */
import { describe, expect, it } from 'vitest'
import {
  decisionAnswerSummary,
  displayEventType,
  displayStatus,
  factoryRerunCommand,
  formatEstimatedSpend,
  formatTokenCount,
  pendingDecisions,
  repoDisplayName,
  runDisplayName,
  runSubtitle,
  sortFactoryRuns,
} from './factory-helpers'
import type { FactoryDecisionView, FactoryRunView } from '../../lib/factory-types'

describe('factory helpers', () => {
  it('formats estimated spend and token counts honestly', () => {
    expect(formatEstimatedSpend(0.75)).toBe('est. $0.7500')
    expect(formatEstimatedSpend(null)).toBe('—')
    expect(formatTokenCount(6100)).toBe('6,100')
    expect(formatTokenCount(undefined)).toBe('—')
  })

  it('sorts live runs ahead of completed runs', () => {
    const runs: FactoryRunView[] = [
      {
        adwId: 'done',
        repo: '/a',
        repoName: null,
        adwName: null,
        runSlug: null,
        request: null,
        status: 'success',
        engineer: null,
        startedAt: '2026-08-05T12:00:00Z',
        endedAt: '2026-08-05T12:30:00Z',
        totalTokens: null,
        totalCost: null,
        phases: [],
        events: [],
        decisions: [],
      },
      {
        adwId: 'live',
        repo: '/b',
        repoName: null,
        adwName: null,
        runSlug: null,
        request: null,
        status: 'running',
        engineer: null,
        startedAt: '2026-08-05T11:00:00Z',
        endedAt: null,
        totalTokens: null,
        totalCost: null,
        phases: [],
        events: [],
        decisions: [],
      },
    ]

    expect(sortFactoryRuns(runs).map((run) => run.adwId)).toEqual(['live', 'done'])
  })

  it('filters pending decisions and summarizes answers by option label', () => {
    const decision: FactoryDecisionView = {
      decisionId: 'dec-1',
      phase: null,
      question: 'Pick one',
      options: [{ value: 'a', label: 'Option A' }],
      freeText: false,
      context: '',
      status: 'pending',
      answerValue: null,
      answerText: null,
      answeredBy: null,
      createdAt: '2026-08-05T11:00:00Z',
      answeredAt: null,
    }
    const run = {
      adwId: 'x', repo: null, repoName: null, adwName: null, runSlug: null, request: null, status: 'running', engineer: null,
      startedAt: null, endedAt: null, totalTokens: null, totalCost: null,
      phases: [], events: [], decisions: [decision, { ...decision, decisionId: 'dec-2', status: 'answered', answerValue: 'a' }],
    } satisfies FactoryRunView

    expect(pendingDecisions(run).map((entry) => entry.decisionId)).toEqual(['dec-1'])
    expect(decisionAnswerSummary({ ...decision, status: 'answered', answerValue: 'a' })).toBe('Option A')
    expect(decisionAnswerSummary({ ...decision, status: 'answered', answerValue: 'other' })).toBe('other')
    expect(decisionAnswerSummary({ ...decision, status: 'answered', answerText: 'free words' })).toBe('free words')
    expect(decisionAnswerSummary(decision)).toBe('—')
  })

  it('builds a rerun command from the run request and first adw token', () => {
    const base = {
      adwId: 'x', repo: '/home/user/Projects/overdeck', repoName: null, adwName: 'adw_plan + adw_build_test',
      runSlug: null,
      request: 'ship it', status: 'done', engineer: null, startedAt: null, endedAt: null,
      totalTokens: null, totalCost: null, phases: [], events: [], decisions: [],
    } satisfies FactoryRunView

    expect(factoryRerunCommand(base)).toBe("factory --repo '/home/user/Projects/overdeck' plan_build_test 'ship it'")
    expect(factoryRerunCommand({ ...base, repo: null })).toBe("factory plan_build_test 'ship it'")
    expect(factoryRerunCommand({ ...base, adwName: 'adw_test' })).toBe(
      "factory --repo '/home/user/Projects/overdeck' test 'ship it'",
    )
    expect(factoryRerunCommand({ ...base, request: null })).toBeNull()
    expect(factoryRerunCommand({ ...base, adwName: null })).toBeNull()
    expect(factoryRerunCommand({ ...base, adwName: 'adw_plan; printf PWNED' })).toBeNull()
    expect(factoryRerunCommand({ ...base, adwName: 'adw_plan + adw_bu ild' })).toBeNull()
  })

  it('prefers run slug for display name and keeps request as secondary context', () => {
    const run = {
      adwId: 'abc12345',
      repo: null,
      repoName: null,
      adwName: 'adw_plan',
      runSlug: 'incident-dispatch-selector-options-design',
      request: 'docs/specs/2026-08-09-incident-dispatch-selector-options-design.md',
      status: 'running',
      engineer: null,
      startedAt: null,
      endedAt: null,
      totalTokens: null,
      totalCost: null,
      phases: [],
      events: [],
      decisions: [],
    } satisfies FactoryRunView

    expect(runDisplayName(run)).toBe('incident-dispatch-selector-options-design')
    expect(runSubtitle(run)).toBe('docs/specs/2026-08-09-incident-dispatch-selector-options-design.md · adw_plan')
  })

  it('falls back to request and adw id for legacy runs without slug', () => {
    const withRequest = {
      adwId: 'legacy1',
      repo: null,
      repoName: null,
      adwName: null,
      runSlug: null,
      request: 'fix the bug',
      status: 'success',
      engineer: null,
      startedAt: null,
      endedAt: null,
      totalTokens: null,
      totalCost: null,
      phases: [],
      events: [],
      decisions: [],
    } satisfies FactoryRunView
    expect(runDisplayName(withRequest)).toBe('fix the bug')
    expect(runDisplayName({ ...withRequest, request: null, adwName: 'adw_test' })).toBe('adw_test')
    expect(runDisplayName({ ...withRequest, request: null, adwName: null })).toBe('legacy1')
  })

  it('prefers repoName for display and falls back for legacy worktree paths', () => {
    const worktreeRepo = '/home/user/Projects/overdeck/.worktrees/cluster-machines-hero'
    expect(repoDisplayName({
      repo: worktreeRepo,
      repoName: 'overdeck',
    })).toBe('overdeck')
    expect(repoDisplayName({
      repo: worktreeRepo,
      repoName: null,
    })).toBe('overdeck')
    expect(repoDisplayName({
      repo: '/home/user/Projects/multideal',
      repoName: null,
    })).toBe('multideal')
    expect(repoDisplayName({ repo: null, repoName: null })).toBe('unassigned')
  })

  it('keeps the exact repo path in rerun commands', () => {
    const worktreeRepo = '/home/user/Projects/overdeck/.worktrees/cluster-machines-hero'
    const run = {
      adwId: 'x',
      repo: worktreeRepo,
      repoName: 'overdeck',
      adwName: 'adw_test',
      runSlug: null,
      request: 'ship it',
      status: 'success',
      engineer: null,
      startedAt: null,
      endedAt: null,
      totalTokens: null,
      totalCost: null,
      phases: [],
      events: [],
      decisions: [],
    } satisfies FactoryRunView

    expect(factoryRerunCommand(run)).toBe(
      `factory --repo '${worktreeRepo}' test 'ship it'`,
    )
  })

  it('falls back safely for unknown event and status labels', () => {
    expect(displayStatus('')).toBe('unknown')
    expect(displayEventType({ type: null, name: null })).toBe('event')
    expect(displayEventType({ type: 'log', name: null })).toBe('log')
  })
})
