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

/** Academic catalog (central + this institution's own) and its selections. */
export async function GET() {
  const session = await requireRole("INSTITUTION_ADMIN");
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  // Branches also see classes owned by their parent (brand HQ)
  const me = await prisma.institution.findUnique({
    where: { id: session.institutionId },
    select: { parentId: true, type: true, academicItemLabels: true },
  });
  const itemLabels = (me?.academicItemLabels ?? {}) as Record<
    string,
    { name?: string; nameBn?: string }
  >;

  // this institution's education levels — board subjects tagged for them
  // list first (school types span primary + high school)
  const myLevels = ["PRIMARY", "HIGH_SCHOOL"];

  const [items, selections] = await Promise.all([
    prisma.academicItem.findMany({
      where: {
        isActive: true,
        OR: [
          { institutionId: null },
          { institutionId: session.institutionId },
          ...(me?.parentId ? [{ institutionId: me.parentId }] : []),
        ],
      },
      include: { institution: { select: { name: true } } },
      orderBy: [{ category: "asc" }, { id: "asc" }],
    }),
    prisma.academicSelection.findMany({
      where: { institutionId: session.institutionId },
      select: { academicItemId: true, isOptional: true },
    }),
  ]);

  const levelOf = (i: { category: string; levels: unknown }): number => {
    if (i.category !== "SUBJECT" || !Array.isArray(i.levels)) return 0;
    return myLevels.some((l) => (i.levels as string[]).includes(l)) ? 0 : 1;
  };
  items.sort((a, b) => levelOf(a) - levelOf(b));

  return NextResponse.json({
    items: items.map((i) => {
      const override = itemLabels[String(i.id)];
      return {
        id: i.id,
        category: i.category,
        name: i.name,
        nameBn: i.nameBn,
        // per-institution display rename (Section-A → Section-Ko Shakha)
        customName: override?.name?.trim() || null,
        customNameBn: override?.nameBn?.trim() || null,
        code: i.code,
        levels: Array.isArray(i.levels) ? (i.levels as string[]) : null,
        owned: i.institutionId === session.institutionId,
        ownerName: i.institutionId ? i.institution?.name ?? null : null,
      };
    }),
    selectedIds: selections.map((s) => s.academicItemId),
    optionalIds: selections.filter((s) => s.isOptional).map((s) => s.academicItemId),
  });
}

/** Toggle a catalog item — or create an institution-owned item (auto-selected). */
export async function POST(req: Request) {
  const session = await requireRole("INSTITUTION_ADMIN");
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  try {
    const body = await req.json();

    // ---- Create own item: DISABLED — the catalog is centrally managed.
    //      Institutions request additions via the central controller (Support). ----
    if (body.category && body.name) {
      return NextResponse.json(
        { error: "CREATE_DISABLED", detail: "Request new academic items from the Central Controller" },
        { status: 403 }
      );
    }
    // ---- Rename a selected item for this institution only:
    //      { academicItemId, rename: { name, nameBn } } / { academicItemId, resetName: true } ----
    if (body.rename !== undefined || body.resetName) {
      const academicItemId = Number(body.academicItemId);
      const selection = await prisma.academicSelection.findUnique({
        where: {
          institutionId_academicItemId: { institutionId: session.institutionId, academicItemId },
        },
      });
      if (!selection) {
        return NextResponse.json({ error: "Select the item first" }, { status: 400 });
      }
      const me = await prisma.institution.findUnique({
        where: { id: session.institutionId },
        select: { academicItemLabels: true },
      });
      const labels = { ...((me?.academicItemLabels ?? {}) as Record<string, { name?: string; nameBn?: string }>) };

      if (body.resetName) {
        delete labels[String(academicItemId)];
      } else {
        const name = String(body.rename?.name ?? "").trim();
        const nameBn = String(body.rename?.nameBn ?? "").trim();
        if (!name && !nameBn) {
          return NextResponse.json({ error: "EMPTY_NAME" }, { status: 400 });
        }
        labels[String(academicItemId)] = { name, nameBn };
      }
      await prisma.institution.update({
        where: { id: session.institutionId },
        data: { academicItemLabels: labels },
      });
      return NextResponse.json({ ok: true });
    }

    // ---- Mark a selected subject optional/compulsory: { academicItemId, setOptional } ----
    if (body.setOptional !== undefined) {
      const academicItemId = Number(body.academicItemId);
      const item = await prisma.academicItem.findUnique({ where: { id: academicItemId } });
      if (!item || item.category !== "SUBJECT") {
        return NextResponse.json({ error: "Only subjects can be optional" }, { status: 400 });
      }
      const existing = await prisma.academicSelection.findUnique({
        where: {
          institutionId_academicItemId: {
            institutionId: session.institutionId,
            academicItemId,
          },
        },
      });
      if (!existing) {
        return NextResponse.json({ error: "Select the subject first" }, { status: 400 });
      }
      await prisma.academicSelection.update({
        where: { id: existing.id },
        data: { isOptional: !!body.setOptional },
      });
      return NextResponse.json({ optional: !!body.setOptional });
    }

    // ---- Toggle selection: { academicItemId } ----
    const academicItemId = Number(body.academicItemId);
    const item = await prisma.academicItem.findUnique({ where: { id: academicItemId } });
    if (!item || !item.isActive) {
      return NextResponse.json({ error: "Item not available" }, { status: 404 });
    }
    if (
      item.institutionId !== null &&
      item.institutionId !== session.institutionId
    ) {
      return NextResponse.json({ error: "Item not available" }, { status: 404 });
    }

    const existing = await prisma.academicSelection.findUnique({
      where: {
        institutionId_academicItemId: {
          institutionId: session.institutionId,
          academicItemId,
        },
      },
    });

    // Institution-owned items cannot be deselected from the owner's portal
    if (existing && item.institutionId === session.institutionId) {
      return NextResponse.json(
        { error: "Own items are always selected — delete the item instead" },
        { status: 400 }
      );
    }

    if (existing) {
      await prisma.academicSelection.delete({ where: { id: existing.id } });
      return NextResponse.json({ selected: false });
    }

    await prisma.academicSelection.create({
      data: {
        institutionId: session.institutionId,
        academicItemId,
        isOptional: item.category === "SUBJECT" && !!body.isOptional,
      },
    });
    return NextResponse.json({ selected: true });
  } catch {
    return NextResponse.json({ error: "Could not update selection" }, { status: 500 });
  }
}
