'use client'

import { useActionState, useEffect, useState, useTransition } from 'react'
import { useRouter } from 'next/navigation'
import { Button, Card } from '@/components/ui'
import { askHintAction, askQuestionAction, concedeAction } from '@/app/actions'

/**
 * "I'm stuck." Asks what he tried before showing the explanation — partly so
 * there is still evidence on the item, and mostly because that sentence is the
 * one thing that says WHERE he stalled, which a blank never does.
 */
export function StuckButton({ setItemId }: { setItemId: string }) {
  const [open, setOpen] = useState(false)
  const action = concedeAction.bind(null, setItemId)
  const [state, formAction, pending] = useActionState(
    async (_prev: { error?: string } | null, fd: FormData) => (await action(fd)) ?? {},
    null,
  )

  if (!open) {
    return (
      <button
        type="button"
        onClick={() => setOpen(true)}
        className="w-full text-center text-sm text-[var(--color-muted)] underline hover:text-[var(--color-ink)]"
      >
        I&rsquo;m stuck &mdash; show me how this one works
      </button>
    )
  }

  return (
    <div className="space-y-3 rounded-lg border border-[var(--color-line)] bg-[var(--color-paper)] p-4">
      <p className="text-sm">
        Before I show you &mdash; what did you try? Even &ldquo;I don&rsquo;t know where
        to start&rdquo; is useful, and it helps me explain the right part.
      </p>
      <form action={formAction} className="space-y-3">
        <textarea
          name="attempt"
          rows={3}
          autoFocus
          placeholder="I got as far as…"
          className="w-full rounded-lg border border-[var(--color-line)] bg-white px-3 py-2 text-[15px] outline-none focus:border-[var(--color-accent)]"
        />
        {state?.error && <p className="text-sm text-[#9b3232]">{state.error}</p>}
        <div className="flex gap-2">
          <Button type="submit" disabled={pending}>
            {pending ? 'One moment…' : 'Show me how'}
          </Button>
          <Button type="button" variant="quiet" onClick={() => setOpen(false)}>
            Actually, let me keep trying
          </Button>
        </div>
      </form>
    </div>
  )
}

interface QuestionView {
  id: string
  question: string
  answer: string | null
  status: string
}

/**
 * The explanation, plus a way to ask about it. Answers come from the Mac mini
 * and take a minute or two, so the waiting state says exactly that instead of
 * pretending to be a chat that will reply in seconds.
 */
export function ExplanationPanel({
  responseId,
  explanation,
  questions,
  onDone,
}: {
  responseId: string
  explanation: string | null
  questions: QuestionView[]
  onDone: string
}) {
  const router = useRouter()
  const [pendingAsk, startAsk] = useTransition()
  const [error, setError] = useState<string | null>(null)
  const waiting = questions.some((q) => q.status === 'PENDING')

  // Poll only while something is actually being answered.
  useEffect(() => {
    if (!waiting) return
    const t = setInterval(() => router.refresh(), 6000)
    return () => clearInterval(t)
  }, [waiting, router])

  return (
    <Card className="space-y-4">
      <div>
        <p className="text-xs font-medium uppercase tracking-wide text-[var(--color-muted)]">
          How this one works
        </p>
        <div className="mt-2 text-[15px] leading-relaxed whitespace-pre-wrap">
          {explanation ?? 'The explanation for this one is still being written — sorry. Tell your dad and move on to the next question.'}
        </div>
      </div>

      {questions.length > 0 && (
        <div className="space-y-3 border-t border-[var(--color-line)] pt-3">
          {questions.map((q) => (
            <div key={q.id} className="space-y-1">
              <p className="text-sm font-medium">You asked: {q.question}</p>
              {q.status === 'ANSWERED' && q.answer ? (
                <p className="text-[15px] leading-relaxed whitespace-pre-wrap">{q.answer}</p>
              ) : q.status === 'FAILED' ? (
                <p className="text-sm text-[var(--color-muted)]">
                  Something went wrong answering that one. Try asking it a different way?
                </p>
              ) : (
                <p className="text-sm text-[var(--color-muted)]">
                  Thinking about that one&hellip; it takes a minute or two. You can keep
                  reading, or come back to it.
                </p>
              )}
            </div>
          ))}
        </div>
      )}

      <form
        action={(fd) =>
          startAsk(async () => {
            const r = await askQuestionAction(responseId, fd)
            if (r?.error) setError(r.error)
            else {
              setError(null)
              router.refresh()
            }
          })
        }
        className="space-y-2 border-t border-[var(--color-line)] pt-3"
      >
        <label htmlFor="question" className="block text-sm">
          Still not sure about something? Ask me.
        </label>
        <textarea
          id="question"
          name="question"
          rows={2}
          placeholder="Why do you divide there?"
          className="w-full rounded-lg border border-[var(--color-line)] bg-white px-3 py-2 text-[15px] outline-none focus:border-[var(--color-accent)]"
        />
        {error && <p className="text-sm text-[#9b3232]">{error}</p>}
        <div className="flex flex-wrap items-center gap-2">
          <Button type="submit" variant="secondary" disabled={pendingAsk}>
            {pendingAsk ? 'Sending…' : 'Ask'}
          </Button>
          <a
            href={onDone}
            className="rounded-lg bg-[var(--color-accent)] px-4 py-2 text-sm font-medium text-white hover:opacity-90"
          >
            Got it — next question
          </a>
        </div>
      </form>
    </Card>
  )
}

interface HintView {
  id: string
  question: string
  hint: string | null
  status: string
}

/**
 * "I'm stuck on part of this." A rung between struggling alone and giving up.
 * He is still going to answer the item himself, so what comes back is a nudge —
 * never the answer.
 */
export function HintPanel({
  setItemId,
  hints,
  maxHints,
}: {
  setItemId: string
  hints: HintView[]
  maxHints: number
}) {
  const router = useRouter()
  const [open, setOpen] = useState(false)
  const [pending, start] = useTransition()
  const [error, setError] = useState<string | null>(null)
  const waiting = hints.some((h) => h.status === 'PENDING')
  const spent = hints.length
  const exhausted = spent >= maxHints

  useEffect(() => {
    if (!waiting) return
    const t = setInterval(() => router.refresh(), 5000)
    return () => clearInterval(t)
  }, [waiting, router])

  return (
    <div className="space-y-3">
      {hints.map((h, i) => (
        <div
          key={h.id}
          className="rounded-lg border border-[var(--color-line)] bg-[var(--color-accent-soft)] px-3 py-2"
        >
          <p className="text-[11px] font-medium uppercase tracking-wide text-[var(--color-accent)]">
            Hint {i + 1}
          </p>
          <p className="mt-0.5 text-xs text-[var(--color-muted)]">You asked: {h.question}</p>
          {h.status === 'ANSWERED' && h.hint ? (
            <p className="mt-1 text-[15px] leading-relaxed whitespace-pre-wrap">{h.hint}</p>
          ) : h.status === 'FAILED' ? (
            <p className="mt-1 text-sm text-[var(--color-muted)]">
              That one didn&rsquo;t work — try asking a different way. It won&rsquo;t count
              against your hints.
            </p>
          ) : (
            <p className="mt-1 text-sm text-[var(--color-muted)]">
              Thinking&hellip; about a minute. Keep working on it while you wait &mdash;
              you might not need me.
            </p>
          )}
        </div>
      ))}

      {!open && !exhausted && (
        <button
          type="button"
          onClick={() => setOpen(true)}
          className="w-full text-center text-sm text-[var(--color-accent)] underline"
        >
          {spent === 0
            ? 'Stuck on part of this? Ask for a hint'
            : `Ask for another hint (${maxHints - spent} left)`}
        </button>
      )}

      {exhausted && (
        <p className="text-center text-xs text-[var(--color-muted)]">
          That&rsquo;s all the hints for this one. Have another go &mdash; and if it still
          won&rsquo;t come, use &ldquo;show me how&rdquo; below.
        </p>
      )}

      {open && (
        <form
          action={(fd) =>
            start(async () => {
              const r = await askHintAction(setItemId, fd)
              if (r?.error) setError(r.error)
              else {
                setError(null)
                setOpen(false)
                router.refresh()
              }
            })
          }
          className="space-y-2 rounded-lg border border-[var(--color-line)] bg-[var(--color-paper)] p-3"
        >
          <label htmlFor="hintq" className="block text-sm">
            What are you stuck on? Tell me how far you got &mdash; I&rsquo;ll point you
            at the next bit, not give you the answer.
          </label>
          <textarea
            id="hintq"
            name="question"
            rows={2}
            autoFocus
            placeholder="I worked out the volume but I don't know what to do next"
            className="w-full rounded-lg border border-[var(--color-line)] bg-white px-3 py-2 text-[15px] outline-none focus:border-[var(--color-accent)]"
          />
          {error && <p className="text-sm text-[#9b3232]">{error}</p>}
          <div className="flex gap-2">
            <Button type="submit" variant="secondary" disabled={pending}>
              {pending ? 'Sending…' : 'Ask'}
            </Button>
            <Button type="button" variant="quiet" onClick={() => setOpen(false)}>
              Cancel
            </Button>
          </div>
        </form>
      )}
    </div>
  )
}
