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

// Schema validasi untuk Update CP Element
const UpdateCPElementSchema = z.object({
  elemen: z.string().min(1, "Nama elemen tidak boleh kosong").optional(),
  capaianPembelajaran: z.string().min(1, "Capaian pembelajaran tidak boleh kosong").optional(),
});

// Helper function to check access
async function checkAccess(
  cpElementId: string,
  payload: { role: string; userId: string },
): Promise<{ allowed: boolean; message?: string; cpElement?: unknown }> {
  const cpElement = await prisma.cPElement.findUnique({
    where: { id: cpElementId },
    include: {
      cpFase: {
        select: { guruId: true },
      },
    },
  });

  if (!cpElement) {
    return { allowed: false, message: "CP Element tidak ditemukan" };
  }

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

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

  return { allowed: true, cpElement };
}

// GET - Ambil detail CP Element
export async function GET(request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
  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 { id } = await params;

    const cpElement = await prisma.cPElement.findUnique({
      where: { id },
      include: {
        cpFase: {
          select: {
            id: true,
            tahunPelajaran: true,
            semester: true,
            guruId: true,
            rombel: {
              select: {
                id: true,
                namaRombel: true,
              },
            },
            mapel: {
              select: {
                id: true,
                namaMapel: true,
              },
            },
          },
        },
        tujuanPembelajaran: {
          include: {
            alurTP: {
              orderBy: { mingguKe: "asc" },
            },
          },
          orderBy: { kode: "asc" },
        },
      },
    });

    if (!cpElement) {
      return NextResponse.json({ success: false, message: "CP Element tidak ditemukan" }, { status: 404 });
    }

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

      if (!guru || cpElement.cpFase.guruId !== guru.id) {
        return NextResponse.json({ success: false, message: "Anda tidak memiliki akses" }, { status: 403 });
      }
    }

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

// PUT - Update CP Element
export async function PUT(request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
  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 { id } = await params;

    const access = await checkAccess(id, payload);
    if (!access.allowed) {
      return NextResponse.json(
        { success: false, message: access.message },
        { status: access.message === "CP Element tidak ditemukan" ? 404 : 403 },
      );
    }

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

    const updatedCPElement = await prisma.cPElement.update({
      where: { id },
      data: {
        ...(validatedData.elemen && { elemen: validatedData.elemen }),
        ...(validatedData.capaianPembelajaran && { capaianPembelajaran: validatedData.capaianPembelajaran }),
      },
    });

    return NextResponse.json({
      success: true,
      data: updatedCPElement,
      message: "CP Element berhasil diupdate",
    });
  } 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 updating CP Element:", error);
    return NextResponse.json({ success: false, message: "Terjadi kesalahan" }, { status: 500 });
  }
}

// DELETE - Hapus CP Element
export async function DELETE(request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
  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 { id } = await params;

    const access = await checkAccess(id, payload);
    if (!access.allowed) {
      return NextResponse.json(
        { success: false, message: access.message },
        { status: access.message === "CP Element tidak ditemukan" ? 404 : 403 },
      );
    }

    // Delete CP Element (cascade akan menghapus TP dan ATP)
    await prisma.cPElement.delete({
      where: { id },
    });

    return NextResponse.json({
      success: true,
      message: "CP Element berhasil dihapus beserta TP dan ATP terkait",
    });
  } catch (error) {
    console.error("Error deleting CP Element:", error);
    return NextResponse.json({ success: false, message: "Terjadi kesalahan" }, { status: 500 });
  }
}
