import { NextResponse } from 'next/server'
import { db } from '@/lib/db'
import { checkAgentAuth, checkAgentWrite } from '@/lib/agent-auth'
import { buildHintPrompt, buildQuestionPrompt } from '@/lib/prompts'
import { FEEDBACK_PROMPT_VERSION } from '@/lib/rubrics'

export const runtime = 'nodejs'

/** GET — every question waiting for an answer, with its prompt already built. */
export async function GET(req: Request) {
  if (!checkAgentAuth(req)) return new NextResponse('Unauthorized', { status: 401 })

  const pending = await db.studentQuestion.findMany({
    where: { status: 'PENDING' },
    orderBy: { askedAt: 'asc' },
    take: 20,
    include: {
      response: {
        include: {
          student: true,
          setItem: { include: { item: true } },
          questions: { where: { status: 'ANSWERED' }, orderBy: { askedAt: 'asc' } },
        },
      },
    },
  })

  // Hints first: he is mid-problem with the page open, whereas a
  // post-concession question is asked after the work is already done.
  const pendingHints = await db.hintRequest.findMany({
    where: { status: 'PENDING' },
    orderBy: { askedAt: 'asc' },
    take: 20,
    include: {
      setItem: {
        include: {
          item: true,
          set: { include: { student: true } },
          hints: { where: { status: 'ANSWERED' }, orderBy: { askedAt: 'asc' } },
        },
      },
    },
  })

  const hints = pendingHints.map((h) => ({
    id: h.id,
    kind: 'hint' as const,
    promptVersion: FEEDBACK_PROMPT_VERSION,
    prompt: buildHintPrompt({
      grade: h.setItem.set.student.grade,
      itemPrompt: h.setItem.item.prompt,
      itemStimulus: h.setItem.item.stimulus,
      rubricCriteria: h.setItem.item.rubricCriteria,
      previousHints: h.setItem.hints
        .filter((p) => p.id !== h.id && p.hint)
        .map((p) => ({ question: p.question, hint: p.hint! })),
      question: h.question,
      hintNumber: h.setItem.hints.filter((p) => p.id !== h.id).length + 1,
    }),
  }))

  return NextResponse.json({
    questions: [
      ...hints,
      ...pending.map((q) => ({
      id: q.id,
      kind: 'question' as const,
      promptVersion: FEEDBACK_PROMPT_VERSION,
      prompt: buildQuestionPrompt({
        grade: q.response.student.grade,
        itemPrompt: q.response.setItem.item.prompt,
        itemStimulus: q.response.setItem.item.stimulus,
        explanation: q.response.setItem.item.explanation ?? '(no explanation was stored)',
        attempt: q.response.typedText,
        history: q.response.questions
          .filter((h) => h.id !== q.id && h.answer)
          .map((h) => ({ question: h.question, answer: h.answer! })),
        question: q.question,
      }),
      })),
    ],
  })
}

/** POST — an answer for one question. */
export async function POST(req: Request) {
  if (!checkAgentWrite(req)) return new NextResponse('Unauthorized', { status: 401 })

  let body: {
    id?: string
    kind?: string
    answer?: string
    modelId?: string
    promptVersion?: string
    error?: string
  }
  try {
    body = await req.json()
  } catch {
    return new NextResponse('Bad JSON', { status: 400 })
  }
  if (!body.id) return NextResponse.json({ error: 'id required' }, { status: 400 })

  if (body.kind === 'hint') {
    if (body.error) {
      await db.hintRequest.update({
        where: { id: body.id },
        data: { status: 'FAILED', error: body.error.slice(0, 500), answeredAt: new Date() },
      })
      return NextResponse.json({ ok: true })
    }
    const hint = typeof body.answer === 'string' ? body.answer.trim() : ''
    if (!hint) return NextResponse.json({ error: 'answer required' }, { status: 400 })
    try {
      await db.hintRequest.update({
        where: { id: body.id },
        data: {
          hint: hint.slice(0, 3000),
          status: 'ANSWERED',
          answeredAt: new Date(),
          modelId: body.modelId ?? null,
          promptVersion: body.promptVersion ?? null,
        },
      })
    } catch {
      return NextResponse.json({ error: 'not found' }, { status: 404 })
    }
    return NextResponse.json({ ok: true })
  }

  if (body.error) {
    await db.studentQuestion.update({
      where: { id: body.id },
      data: { status: 'FAILED', error: body.error.slice(0, 500), answeredAt: new Date() },
    })
    return NextResponse.json({ ok: true })
  }

  const answer = typeof body.answer === 'string' ? body.answer.trim() : ''
  if (!answer) return NextResponse.json({ error: 'answer required' }, { status: 400 })

  try {
    await db.studentQuestion.update({
      where: { id: body.id },
      data: {
        answer: answer.slice(0, 6000),
        status: 'ANSWERED',
        answeredAt: new Date(),
        modelId: body.modelId ?? null,
        promptVersion: body.promptVersion ?? null,
      },
    })
  } catch {
    return NextResponse.json({ error: 'not found' }, { status: 404 })
  }
  return NextResponse.json({ ok: true })
}
