import { NextRequest, NextResponse } from "next/server";
import { verifyToken, getTokenFromRequest } from "@/lib/jwt";
import { prisma } from "@/lib/prisma";
import { z } from "zod";

// Schema validasi untuk ATP
const ATPSchema = z.object({
  mingguKe: z.number().int().min(1, "Minggu ke harus minimal 1"),
  alokasiWaktuJP: z.number().int().min(1, "Alokasi waktu JP harus minimal 1"),
  profilPelajarPancasila: z
    .array(
      z.enum(["BERIMAN_BERTAKWA", "BERKEBINEKAAN_GLOBAL", "BERGOTONG_ROYONG", "MANDIRI", "BERNALAR_KRITIS", "KREATIF"]),
    )
    .default([]),
  tpId: z.string().min(1, "TP ID tidak boleh kosong"),
});

// Helper function to check access via TP
async function checkTPAccess(
  tpId: string,
  payload: { role: string; userId: string },
): Promise<{ allowed: boolean; message?: string }> {
  const tp = await prisma.tujuanPembelajaran.findUnique({
    where: { id: tpId },
    include: {
      cpElement: {
        include: {
          cpFase: {
            select: { guruId: true },
          },
        },
      },
    },
  });

  if (!tp) {
    return { allowed: false, message: "Tujuan Pembelajaran tidak ditemukan" };
  }

  if (payload.role === "GURU") {
    const guru = await prisma.guru.findUnique({
      where: { userId: payload.userId },
    });

    if (!guru || tp.cpElement.cpFase.guruId !== guru.id) {
      return { allowed: false, message: "Anda tidak memiliki akses" };
    }
  }

  return { allowed: true };
}

// GET - Ambil semua ATP berdasarkan TP
export async function GET(request: NextRequest) {
  try {
    const token = getTokenFromRequest(request);

    if (!token) {
      return NextResponse.json({ success: false, message: "Token tidak ditemukan" }, { status: 401 });
    }

    const payload = verifyToken(token);
    if (!payload) {
      return NextResponse.json({ success: false, message: "Token tidak valid" }, { status: 401 });
    }

    const { searchParams } = new URL(request.url);
    const tpId = searchParams.get("tpId");

    if (!tpId) {
      return NextResponse.json({ success: false, message: "TP ID wajib diisi" }, { status: 400 });
    }

    const access = await checkTPAccess(tpId, payload);
    if (!access.allowed) {
      const status = access.message === "Tujuan Pembelajaran tidak ditemukan" ? 404 : 403;
      return NextResponse.json({ success: false, message: access.message }, { status });
    }

    const alurTP = await prisma.alurTP.findMany({
      where: { tpId },
      orderBy: { mingguKe: "asc" },
    });

    return NextResponse.json({
      success: true,
      data: alurTP,
    });
  } catch (error) {
    console.error("Error fetching ATP:", error);
    return NextResponse.json({ success: false, message: "Terjadi kesalahan" }, { status: 500 });
  }
}

// POST - Buat ATP baru
export async function POST(request: NextRequest) {
  try {
    const token = getTokenFromRequest(request);

    if (!token) {
      return NextResponse.json({ success: false, message: "Token tidak ditemukan" }, { status: 401 });
    }

    const payload = verifyToken(token);
    if (!payload) {
      return NextResponse.json({ success: false, message: "Token tidak valid" }, { status: 401 });
    }

    if (payload.role !== "ADMIN" && payload.role !== "GURU") {
      return NextResponse.json({ success: false, message: "Tidak memiliki akses" }, { status: 403 });
    }

    const body = await request.json();
    const validatedData = ATPSchema.parse(body);

    const access = await checkTPAccess(validatedData.tpId, payload);
    if (!access.allowed) {
      const status = access.message === "Tujuan Pembelajaran tidak ditemukan" ? 404 : 403;
      return NextResponse.json({ success: false, message: access.message }, { status });
    }

    const newATP = await prisma.alurTP.create({
      data: {
        mingguKe: validatedData.mingguKe,
        alokasiWaktuJP: validatedData.alokasiWaktuJP,
        profilPelajarPancasila: validatedData.profilPelajarPancasila,
        tpId: validatedData.tpId,
      },
    });

    return NextResponse.json({
      success: true,
      data: newATP,
      message: "Alur TP berhasil dibuat",
    });
  } catch (error) {
    if (error instanceof z.ZodError) {
      return NextResponse.json(
        { success: false, message: error.errors.map((e) => e.message).join(", ") },
        { status: 400 },
      );
    }

    console.error("Error creating ATP:", error);
    return NextResponse.json({ success: false, message: "Terjadi kesalahan" }, { status: 500 });
  }
}
