import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { projectStateOptions, type ProjectState } from "@/lib/project-state";

export async function GET(request: Request) {
  const { searchParams } = new URL(request.url);
  const projectIds = (searchParams.get("projectIds") ?? "")
    .split(",")
    .map((projectId) => projectId.trim())
    .filter(Boolean);

  if (projectIds.length === 0) {
    return NextResponse.json({ statesByProject: {} });
  }

  try {
    await ensureProjectStateTable();

    const rows = await prisma.$queryRawUnsafe<Array<{ project_id: string; state: ProjectState }>>(
      `select project_id, state from "ProjectStates" where project_id = any($1::text[])`,
      projectIds
    );

    return NextResponse.json({
      statesByProject: Object.fromEntries(rows.map((row) => [row.project_id, row.state]))
    });
  } catch (error) {
    console.error("Unable to read project states", error);
    return NextResponse.json({ statesByProject: {}, databaseAvailable: false }, { status: 503 });
  }
}

export async function POST(request: Request) {
  const body = await request.json().catch(() => null);

  if (!body || typeof body.projectId !== "string" || !isProjectState(body.state)) {
    return NextResponse.json({ error: "Invalid payload" }, { status: 400 });
  }

  try {
    await ensureProjectStateTable();

    await prisma.$executeRawUnsafe(
      `
      insert into "ProjectStates" (project_id, state, updated_at)
      values ($1, $2, now())
      on conflict (project_id)
      do update set state = excluded.state, updated_at = now()
      `,
      body.projectId,
      body.state
    );

    return NextResponse.json({ ok: true });
  } catch (error) {
    console.error("Unable to save project state", error);
    return NextResponse.json({ ok: false, databaseAvailable: false }, { status: 503 });
  }
}

function isProjectState(value: unknown): value is ProjectState {
  return typeof value === "string" && projectStateOptions.includes(value as ProjectState);
}

async function ensureProjectStateTable() {
  await prisma.$executeRawUnsafe(`
    create table if not exists "ProjectStates" (
      project_id text primary key,
      state text not null,
      updated_at timestamp with time zone not null default now()
    )
  `);
}
