import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { requireAnyRole } from "@/lib/auth";

const STATUSES = ["UPCOMING", "RUNNING", "COMPLETED", "CANCELLED"];

/** Competitions with club info + result/publish counts. */
export async function GET() {
  const session = await requireAnyRole(["INSTITUTION_ADMIN", "TEACHER", "STUDENT", "PARENT"]);
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const competitions = await prisma.competition.findMany({
    where: { institutionId: session.institutionId },
    orderBy: { scheduledAt: "desc" },
    include: {
      club: { select: { id: true, name: true, nameBn: true } },
      results: { select: { id: true, publishedAt: true, points: true, rank: true, studentId: true } },
    },
  });

  return NextResponse.json({
    competitions: competitions.map((c) => ({
      id: c.id,
      name: c.name,
      nameBn: c.nameBn,
      description: c.description,
      venue: c.venue,
      scheduledAt: c.scheduledAt,
      status: c.status,
      club: c.club,
      resultCount: c.results.length,
      publishedCount: c.results.filter((r) => r.publishedAt !== null).length,
    })),
  });
}

/** Schedule a competition under a club (or standalone). */
export async function POST(req: Request) {
  const session = await requireAnyRole(["INSTITUTION_ADMIN", "TEACHER"]);
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  try {
    const body = await req.json();
    const name = String(body.name ?? "").trim();
    const scheduledAt = body.scheduledAt ? new Date(String(body.scheduledAt)) : null;
    if (!name || !scheduledAt || Number.isNaN(scheduledAt.getTime())) {
      return NextResponse.json({ error: "Missing fields" }, { status: 400 });
    }
    const clubId = Number(body.clubId) || null;

    const competition = await prisma.competition.create({
      data: {
        institutionId: session.institutionId,
        clubId,
        name,
        nameBn: String(body.nameBn ?? "").trim() || null,
        description: String(body.description ?? "").trim() || null,
        venue: String(body.venue ?? "").trim() || null,
        scheduledAt,
        status: "UPCOMING",
      },
    });
    return NextResponse.json({ competition });
  } catch {
    return NextResponse.json({ error: "Could not create competition" }, { status: 500 });
  }
}

/** Update status (schedule flow) or reschedule. */
export async function PATCH(req: Request) {
  const session = await requireAnyRole(["INSTITUTION_ADMIN", "TEACHER"]);
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  try {
    const body = await req.json();
    const id = Number(body.id);
    if (!id) return NextResponse.json({ error: "Missing id" }, { status: 400 });

    const data: { status?: string; scheduledAt?: Date; venue?: string | null } = {};
    if (body.status !== undefined) {
      if (!STATUSES.includes(String(body.status))) {
        return NextResponse.json({ error: "Invalid status" }, { status: 400 });
      }
      data.status = String(body.status);
    }
    if (body.scheduledAt !== undefined) {
      const d = new Date(String(body.scheduledAt));
      if (Number.isNaN(d.getTime())) {
        return NextResponse.json({ error: "Invalid date" }, { status: 400 });
      }
      data.scheduledAt = d;
    }
    if (body.venue !== undefined) data.venue = String(body.venue).trim() || null;

    await prisma.competition.updateMany({
      where: { id, institutionId: session.institutionId },
      data,
    });
    return NextResponse.json({ ok: true });
  } catch {
    return NextResponse.json({ error: "Could not update competition" }, { status: 500 });
  }
}

export async function DELETE(req: Request) {
  const session = await requireAnyRole(["INSTITUTION_ADMIN"]);
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }
  const id = Number(new URL(req.url).searchParams.get("id"));
  if (!id) return NextResponse.json({ error: "Missing id" }, { status: 400 });
  await prisma.competition.deleteMany({ where: { id, institutionId: session.institutionId } });
  return NextResponse.json({ ok: true });
}
