import { useState } from 'react'
import type { JSX } from 'react'
import { Button, formatRelativeTime, TextField } from '@overdeck/deck-ui'
import { postCollectorAction } from '../../lib/action-client'
import type { FactoryDecisionView } from '../../lib/factory-types'
import { decisionAnswerSummary, parseTimestampMs } from './factory-helpers'

type AnswerState = 'idle' | 'submitting' | 'answered' | 'error'

function PendingDecision(props: { decision: FactoryDecisionView }): JSX.Element {
  const { decision } = props
  const [state, setState] = useState<AnswerState>('idle')
  const [error, setError] = useState('')
  const [freeText, setFreeText] = useState('')
  const [answeredSummary, setAnsweredSummary] = useState('')

  const submit = async (choice: string, summary: string) => {
    setState('submitting')
    try {
      await postCollectorAction('factory.decision.answer', {
        args: { decisionId: decision.decisionId, choice },
        requestedBy: 'deck-web',
      })
      setAnsweredSummary(summary)
      setState('answered')
    } catch (cause) {
      setError(cause instanceof Error ? cause.message : 'answer failed')
      setState('error')
    }
  }

  if (state === 'answered') {
    return (
      <div className="rounded-md border border-border bg-surface-raised px-3 py-2" data-testid="factory-decision-pending">
        <p className="text-sm text-fg">{decision.question}</p>
        <p className="mt-1 text-xs text-success">Answered: {answeredSummary} — the run continues with this choice.</p>
      </div>
    )
  }

  return (
    <div
      className="rounded-md border border-warning/60 bg-warning/5 px-3 py-2"
      data-testid="factory-decision-pending"
      data-decision-id={decision.decisionId}
    >
      <p className="text-sm font-medium text-fg">{decision.question}</p>
      {decision.context.trim() ? (
        <p className="mt-1 whitespace-pre-wrap text-xs text-fg-muted">{decision.context.trim()}</p>
      ) : null}
      <div className="mt-2 flex flex-wrap items-center gap-2">
        {decision.options.map((option) => (
          <Button
            key={option.value}
            variant="outline"
            tone={option.recommended ? 'accent' : 'neutral'}
            size="sm"
            disabled={state === 'submitting'}
            onClick={() => void submit(option.value, option.label)}
          >
            {option.label}
            {option.recommended ? ' ★' : ''}
          </Button>
        ))}
      </div>
      {decision.freeText ? (
        <form
          className="mt-2 flex items-center gap-2"
          onSubmit={(event) => {
            event.preventDefault()
            const text = freeText.trim()
            if (text) void submit(text, text)
          }}
        >
          <TextField
            label="Answer in your own words"
            labelMode="hidden"
            value={freeText}
            onValueChange={setFreeText}
            placeholder="Or answer in your own words…"
          />
          <Button
            type="submit"
            variant="outline"
            tone="neutral"
            size="sm"
            disabled={state === 'submitting' || !freeText.trim()}
          >
            Send
          </Button>
        </form>
      ) : null}
      {state === 'submitting' ? <p className="mt-1 text-xs text-fg-muted">Sending answer…</p> : null}
      {state === 'error' ? <p className="mt-1 text-xs text-danger">{error}</p> : null}
    </div>
  )
}

function answeredAtLabel(answeredAt: string): JSX.Element {
  const epochMs = parseTimestampMs(answeredAt)
  if (epochMs === null) return <>{answeredAt}</>
  return <time dateTime={answeredAt} title={answeredAt}>{formatRelativeTime(epochMs)}</time>
}

function SettledDecision(props: { decision: FactoryDecisionView }): JSX.Element {
  const { decision } = props
  if (decision.status === 'canceled') {
    return (
      <div className="rounded-md border border-border px-3 py-2" data-testid="factory-decision-settled">
        <p className="text-xs text-fg-muted">{decision.question}</p>
        <p className="mt-0.5 text-xs text-fg-subtle">Canceled — the run ended before this was answered.</p>
      </div>
    )
  }
  return (
    <div className="rounded-md border border-border px-3 py-2" data-testid="factory-decision-settled">
      <p className="text-xs text-fg-muted">{decision.question}</p>
      <p className="mt-0.5 text-xs text-fg">
        <span className="text-fg-muted">You answered: </span>
        {decisionAnswerSummary(decision)}
        {decision.answeredAt ? <span className="text-fg-subtle"> · {answeredAtLabel(decision.answeredAt)}</span> : null}
      </p>
    </div>
  )
}

export function FactoryDecisionPanel(props: { decisions: FactoryDecisionView[] }): JSX.Element | null {
  const { decisions } = props
  if (decisions.length === 0) return null
  const pending = decisions.filter((decision) => decision.status === 'pending')
  const settled = decisions.filter((decision) => decision.status !== 'pending')

  return (
    <section className="flex flex-col gap-2" data-testid="factory-decision-panel">
      <h4 className="text-xs font-semibold uppercase tracking-wide text-fg-muted">
        Decisions{pending.length > 0 ? ` — ${pending.length} waiting for you` : ''}
      </h4>
      {pending.map((decision) => (
        <PendingDecision key={decision.decisionId} decision={decision} />
      ))}
      {settled.map((decision) => (
        <SettledDecision key={decision.decisionId} decision={decision} />
      ))}
    </section>
  )
}
