import { NextResponse } from "next/server";
import { db } from "@/db";
import { quizSessions } from "@/db/schema";
import { eq, and, desc } from "drizzle-orm";
import { getSession } from "@/lib/auth";
import { WARMUP_PARAGRAPHS } from "@/lib/warmup-paragraphs";

/**
 * Warmup progress is keyed by the auth session's createdAt timestamp.
 * This means warmup resets every time the user logs in (new session),
 * while the quiz pass is permanent.
 */

interface WarmupProgressMap {
  [sessionKey: string]: number;
}

function getWarmupCompleted(
  answersJson: string,
  sessionKey: string,
): number {
  try {
    const parsed = JSON.parse(answersJson);
    if (parsed && typeof parsed === "object" && "warmupBySession" in parsed) {
      return (parsed.warmupBySession as WarmupProgressMap)[sessionKey] ?? 0;
    }
    // Legacy format: single warmupCompleted
    if (parsed && typeof parsed === "object" && "warmupCompleted" in parsed) {
      return 0; // Reset legacy progress — they need to redo warmup
    }
    return 0;
  } catch {
    return 0;
  }
}

async function getPassedQuizSession(annotatorId: string) {
  const [session] = await db
    .select()
    .from(quizSessions)
    .where(
      and(
        eq(quizSessions.annotatorId, annotatorId),
        eq(quizSessions.passed, true),
      ),
    )
    .orderBy(desc(quizSessions.startedAt))
    .limit(1);
  return session ?? null;
}

export async function GET() {
  const session = await getSession();
  if (!session) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const quizSession = await getPassedQuizSession(session.annotatorId);
  if (!quizSession) {
    return NextResponse.json(
      { error: "Quiz not passed" },
      { status: 403 },
    );
  }

  const sessionKey = String(session.createdAt);
  const warmupCompleted = getWarmupCompleted(quizSession.answers, sessionKey);

  if (warmupCompleted >= WARMUP_PARAGRAPHS.length) {
    return NextResponse.json({ done: true, warmupCompleted });
  }

  const next = WARMUP_PARAGRAPHS[warmupCompleted];
  return NextResponse.json({
    done: false,
    warmupCompleted,
    paragraph: {
      id: next.id,
      text: next.text,
      index: warmupCompleted,
      total: WARMUP_PARAGRAPHS.length,
    },
  });
}

export async function POST(request: Request) {
  const session = await getSession();
  if (!session) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const quizSession = await getPassedQuizSession(session.annotatorId);
  if (!quizSession) {
    return NextResponse.json(
      { error: "Quiz not passed" },
      { status: 403 },
    );
  }

  const body = await request.json();
  const { category, specificity, warmupIndex } = body as {
    category?: string;
    specificity?: number;
    warmupIndex?: number;
  };

  if (!category || !specificity || warmupIndex === undefined) {
    return NextResponse.json(
      { error: "Missing required fields: category, specificity, warmupIndex" },
      { status: 400 },
    );
  }

  const sessionKey = String(session.createdAt);
  const warmupCompleted = getWarmupCompleted(quizSession.answers, sessionKey);

  if (warmupIndex !== warmupCompleted) {
    return NextResponse.json(
      { error: "Warmup index mismatch" },
      { status: 400 },
    );
  }

  if (warmupIndex >= WARMUP_PARAGRAPHS.length) {
    return NextResponse.json(
      { error: "Warmup already complete" },
      { status: 400 },
    );
  }

  const gold = WARMUP_PARAGRAPHS[warmupIndex];
  const newCompleted = warmupIndex + 1;
  const categoryCorrect = category === gold.goldCategory;
  const specificityCorrect = specificity === gold.goldSpecificity;

  // Store warmup progress keyed by auth session
  let existingData: Record<string, unknown>;
  try {
    const parsed = JSON.parse(quizSession.answers);
    if (Array.isArray(parsed)) {
      existingData = { quizAnswers: parsed };
    } else {
      existingData = parsed;
    }
  } catch {
    existingData = {};
  }

  const warmupBySession = (existingData.warmupBySession as WarmupProgressMap) ?? {};
  warmupBySession[sessionKey] = newCompleted;

  await db
    .update(quizSessions)
    .set({
      answers: JSON.stringify({
        ...existingData,
        warmupBySession,
      }),
    })
    .where(eq(quizSessions.id, quizSession.id));

  return NextResponse.json({
    categoryCorrect,
    specificityCorrect,
    goldCategory: gold.goldCategory,
    goldSpecificity: gold.goldSpecificity,
    explanation: gold.explanation,
    warmupCompleted: newCompleted,
    done: newCompleted >= WARMUP_PARAGRAPHS.length,
  });
}
