import Link from 'next/link'
import { notFound } from 'next/navigation'
import { db } from '@/lib/db'
import { Card, Caveat, DimensionBar, Label } from '@/components/ui'
import { formatDuration, summarisePacing } from '@/lib/timing'
import { GradeButton, Adjudicator } from './controls'

/**
 * The evidence screen. Deliberately shows the per-item justifications next to
 * every estimate: the likeliest failure mode of this whole project is the grader
 * under-scoring a child's explanation and the app reporting a decline that never
 * happened. A number with no way to check it invites exactly that.
 */
export default async function Results({
  params,
}: {
  params: Promise<{ studentId: string }>
}) {
  const { studentId } = await params

  const student = await db.student.findUnique({
    where: { id: studentId },
    include: {
      states: {
        include: {
          construct: true,
          dimensions: {
            include: { dimension: true },
            orderBy: { dimension: { sortOrder: 'asc' } },
          },
        },
      },
    },
  })
  if (!student) notFound()

  const sets = await db.itemSet.findMany({
    where: { studentId, status: { in: ['IN_PROGRESS', 'COMPLETE'] } },
    orderBy: { round: 'desc' },
    include: { items: { include: { item: true, response: true } } },
  })

  // What he has asked, and whether a later item has checked that it landed.
  // The single most specific evidence in the app about what he does not
  // understand — a score says he found something hard, a question names the idea.
  const questions = await db.studentQuestion.findMany({
    where: { studentId },
    orderBy: { askedAt: 'desc' },
    include: {
      response: { include: { setItem: { include: { item: { include: { construct: true } } } } } },
    },
  })

  const responses = await db.response.findMany({
    where: { studentId },
    orderBy: { submittedAt: 'desc' },
    include: {
      gradings: {
        include: { scores: { include: { dimension: true } } },
        orderBy: [{ gradedBy: 'asc' }, { pass: 'asc' }],
      },
      setItem: {
        include: { item: { include: { construct: true } }, set: true },
      },
    },
  })

  return (
    <div className="space-y-6">
      <div>
        <Link href="/parent" className="text-xs text-[var(--color-muted)] hover:underline">
          &larr; Back
        </Link>
        <h1 className="mt-2 text-xl font-semibold">{student.name}</h1>
        <p className="text-sm text-[var(--color-muted)]">
          Grade {student.grade}
          {student.courseNote ? ` · ${student.courseNote}` : ''} &middot;{' '}
          {responses.length} response{responses.length === 1 ? '' : 's'} on record
        </p>
      </div>

      {sets.map((set) => {
        const pacing = summarisePacing(
          set.items
            .filter((si) => si.response)
            .map((si) => ({ timeSpentMs: si.response!.timeSpentMs, format: si.item.format })),
          set.startedAt,
          set.completedAt,
        )
        if (!pacing.itemsTimed && !pacing.totalMs) return null
        return (
          <Card key={set.id} className="space-y-2">
            <Label>
              How he worked &middot; {set.title} (round {set.round})
            </Label>
            <div className="flex flex-wrap gap-x-6 gap-y-1 text-sm">
              <span>
                Total <strong>{formatDuration(pacing.totalMs)}</strong>
              </span>
              <span>
                Median per item <strong>{formatDuration(pacing.medianMsPerItem)}</strong>
              </span>
              <span>
                Fastest <strong>{formatDuration(pacing.fastestMs)}</strong>
              </span>
            </div>
            {pacing.warning ? (
              <Caveat>{pacing.warning}</Caveat>
            ) : (
              <p className="text-xs text-[var(--color-muted)]">Nothing looks rushed.</p>
            )}
          </Card>
        )
      })}

      {student.states.map((state) => (
        <Card key={state.id} className="space-y-3">
          <div>
            <h2 className="text-base font-semibold">{state.construct.label}</h2>
            {state.construct.reportArea && (
              <p className="text-xs text-[var(--color-muted)]">
                Reports into &ldquo;{state.construct.reportArea}&rdquo; on the state test
              </p>
            )}
          </div>
          {state.dimensions.map((d) => (
            <DimensionBar
              key={d.id}
              label={d.dimension.label}
              estimate={d.estimate}
              itemsObserved={d.itemsObserved}
              itemsFlagged={d.itemsFlagged}
              itemsHinted={state.itemsHinted}
              movement={
                d.recentEstimate !== null && d.previousEstimate !== null
                  ? Math.round((d.recentEstimate - d.previousEstimate) * 100)
                  : null
              }
            />
          ))}
          {state.summary && (
            <p className="text-xs leading-relaxed text-[var(--color-muted)]">
              {state.summary}
            </p>
          )}
        </Card>
      ))}

      {questions.length > 0 && (
        <Card className="space-y-3">
          <div>
            <h2 className="text-base font-semibold">What he asked</h2>
            <p className="text-xs text-[var(--color-muted)]">
              Questions after giving up on an item. Each one names an idea he
              couldn&rsquo;t get hold of, so the generator writes a later item that
              re-tests it &mdash; in a different context, and unsignposted.
            </p>
          </div>
          {questions.map((q) => (
            <div key={q.id} className="space-y-1 border-t border-[var(--color-line)] pt-3">
              <div className="flex flex-wrap items-baseline justify-between gap-2">
                <span className="text-[11px] uppercase tracking-wide text-[var(--color-muted)]">
                  {q.response.setItem.item.construct.label} &middot;{' '}
                  {q.askedAt.toLocaleDateString()}
                </span>
                <span
                  className={
                    q.addressedBySetId
                      ? 'text-[11px] text-[var(--color-accent)]'
                      : 'text-[11px] text-[var(--color-warn)]'
                  }
                >
                  {q.addressedBySetId ? 'followed up in a later set' : 'not yet followed up'}
                </span>
              </div>
              <p className="text-sm">&ldquo;{q.question}&rdquo;</p>
              {q.answer && (
                <details className="text-xs text-[var(--color-muted)]">
                  <summary className="cursor-pointer">What he was told</summary>
                  <p className="mt-1 leading-relaxed whitespace-pre-wrap">{q.answer}</p>
                </details>
              )}
            </div>
          ))}
        </Card>
      )}

      <h2 className="pt-2 text-base font-semibold">Every response</h2>
      {responses.length === 0 && (
        <p className="text-sm text-[var(--color-muted)]">Nothing submitted yet.</p>
      )}

      {responses.map((r) => {
        const aiPasses = r.gradings.filter((g) => g.gradedBy === 'AI')
        const human = r.gradings.find((g) => g.gradedBy === 'HUMAN')
        const images = Array.isArray(r.imagePaths) ? (r.imagePaths as string[]) : []

        return (
          <Card key={r.id} className="space-y-3">
            <div className="flex flex-wrap items-baseline justify-between gap-2">
              <Label>
                {r.setItem.item.construct.label} &middot; round {r.setItem.set.round}
              </Label>
              <span className="text-[11px] text-[var(--color-muted)]">
                {r.submittedAt.toLocaleDateString()}
                {r.timeSpentMs ? ` · took ${formatDuration(r.timeSpentMs)}` : ''}
              </span>
            </div>

            <p className="text-sm leading-relaxed whitespace-pre-wrap">
              {r.setItem.item.prompt}
            </p>

            <div className="rounded-lg bg-[var(--color-paper)] p-3">
              <Label>His response</Label>
              {r.typedText && (
                <p className="mt-1 text-sm leading-relaxed whitespace-pre-wrap">
                  {r.typedText}
                </p>
              )}
              {r.choiceKey && (
                <p className="mt-1 text-sm">
                  Chose {r.choiceKey}
                  {r.setItem.item.answerKey &&
                    ` (key: ${r.setItem.item.answerKey})`}
                </p>
              )}
              {images.map((p) => (
                // eslint-disable-next-line @next/next/no-img-element
                <img
                  key={p}
                  src={`/api/image/${p}`}
                  alt="Handwritten work"
                  className="mt-2 max-w-full rounded border border-[var(--color-line)]"
                />
              ))}
            </div>

            {r.hintsUsed > 0 && !r.conceded && (
              <p className="text-xs text-[var(--color-muted)]">
                Needed {r.hintsUsed} hint{r.hintsUsed === 1 ? '' : 's'} before answering
                &mdash; the score below includes that help.
              </p>
            )}

            {r.flagged && (
              <Caveat>
                <strong>Needs your score.</strong> {r.flagReason} This response is excluded
                from the estimates above until you score it yourself. A high rate of
                these means the <em>rubric</em> is underspecified, not that he is
                inconsistent.
              </Caveat>
            )}

            {r.conceded ? (
              <p className="text-xs leading-relaxed text-[var(--color-muted)]">
                <strong>Not graded, on purpose.</strong> He gave up on this one and
                asked to see how it worked, so a score here would measure the
                explanation rather than him. It is excluded from the estimates and
                counted as a concession instead &mdash; which is the more useful
                signal: it says where he is finding it hardest.
              </p>
            ) : aiPasses.length === 0 ? (
              <GradeButton responseId={r.id} />
            ) : (
              <div className="space-y-3">
                {aiPasses.map((g) => (
                  <div key={g.id} className="space-y-1.5">
                    <Label>
                      Pass {g.pass} &middot; {g.modelId} &middot; rubric {g.rubricVersion}
                    </Label>
                    {g.scores.map((s) => (
                      <p key={s.id} className="text-sm">
                        <span className="font-medium">
                          {s.dimension.label} {s.value}/{s.dimension.maxValue}
                        </span>
                        {s.justification && (
                          <span className="text-[var(--color-muted)]"> — {s.justification}</span>
                        )}
                      </p>
                    ))}
                  </div>
                ))}
                {human && (
                  <div className="space-y-1.5 rounded-lg border border-[var(--color-accent)] bg-[var(--color-accent-soft)] p-3">
                    <Label>Your score</Label>
                    {human.scores.map((s) => (
                      <p key={s.id} className="text-sm">
                        {s.dimension.label} {s.value}/{s.dimension.maxValue}
                      </p>
                    ))}
                    {human.justification && (
                      <p className="text-xs text-[var(--color-muted)]">{human.justification}</p>
                    )}
                  </div>
                )}
                <Adjudicator
                  responseId={r.id}
                  dimensions={
                    aiPasses[0]?.scores.map((s) => ({
                      code: s.dimension.code,
                      label: s.dimension.label,
                      maxValue: s.dimension.maxValue,
                    })) ?? []
                  }
                  flagged={r.flagged}
                />
              </div>
            )}

            {r.feedbackForStudent && (
              <details className="text-xs text-[var(--color-muted)]">
                <summary className="cursor-pointer">What he was told</summary>
                <p className="mt-2 leading-relaxed whitespace-pre-wrap">
                  {r.feedbackForStudent}
                </p>
              </details>
            )}
          </Card>
        )
      })}
    </div>
  )
}
