import { NextResponse } from "next/server";
import { getServerSession } from "next-auth";
import { authOptions } from "@/lib/auth";
import prisma from "@/lib/prisma";

export async function GET(req: Request) {
  try {
    const session = await getServerSession(authOptions);
    if (!session) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

    const { searchParams } = new URL(req.url);
    const status = searchParams.get("status");
    const userId = searchParams.get("userId");
    const forApproval = searchParams.get("forApproval") === "true";

    let where: any = {};

    if (forApproval && (session.user.role === "MANAGER" || session.user.role === "ADMIN")) {
      if (session.user.role === "MANAGER") {
        // Get IDs of employees who report to this manager
        const employees = await prisma.user.findMany({
          where: { managerId: session.user.id },
          select: { id: true },
        });
        where.userId = { in: employees.map((e) => e.id) };
      }
      where.status = "PENDING";
    } else if (userId) {
      where.userId = userId;
    } else {
      where.userId = session.user.id;
    }

    if (status && !forApproval) {
      where.status = status;
    }

    const requests = await prisma.leaveRequest.findMany({
      where,
      include: {
        user: { select: { id: true, name: true, email: true, department: true } },
        leaveType: true,
        approver: { select: { id: true, name: true } },
      },
      orderBy: { createdAt: "desc" },
    });

    return NextResponse.json(requests);
  } catch (error) {
    return NextResponse.json({ error: "Failed to fetch leave requests" }, { status: 500 });
  }
}

export async function POST(req: Request) {
  try {
    const session = await getServerSession(authOptions);
    if (!session) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

    const body = await req.json();
    const { leaveTypeId, startDate, endDate, totalDays, reason } = body;

    // Check for overlapping leave requests
    const overlapping = await prisma.leaveRequest.findFirst({
      where: {
        userId: session.user.id,
        status: { in: ["PENDING", "APPROVED"] },
        OR: [
          {
            startDate: { lte: new Date(endDate) },
            endDate: { gte: new Date(startDate) },
          },
        ],
      },
    });

    if (overlapping) {
      return NextResponse.json(
        { error: "You already have a leave request overlapping with these dates" },
        { status: 400 }
      );
    }

    // Check balance
    const year = new Date(startDate).getFullYear();
    const balance = await prisma.leaveBalance.findFirst({
      where: { userId: session.user.id, leaveTypeId, year },
    });

    if (balance) {
      const available = balance.allocated + balance.carriedOver - balance.used - balance.pending;
      if (totalDays > available) {
        return NextResponse.json(
          { error: `Insufficient balance. Available: ${available} days` },
          { status: 400 }
        );
      }
    }

    // Create the request
    const leaveRequest = await prisma.leaveRequest.create({
      data: {
        userId: session.user.id,
        leaveTypeId,
        startDate: new Date(startDate),
        endDate: new Date(endDate),
        totalDays,
        reason,
        status: "PENDING",
      },
      include: { leaveType: true, user: true },
    });

    // Update pending balance
    if (balance) {
      await prisma.leaveBalance.update({
        where: { id: balance.id },
        data: { pending: balance.pending + totalDays },
      });
    }

    // Notify manager
    const user = await prisma.user.findUnique({
      where: { id: session.user.id },
      select: { managerId: true, name: true },
    });

    if (user?.managerId) {
      await prisma.notification.create({
        data: {
          userId: user.managerId,
          title: "New Leave Request",
          message: `${user.name} has requested ${leaveRequest.leaveType.name} from ${new Date(startDate).toLocaleDateString()} to ${new Date(endDate).toLocaleDateString()}.`,
          type: "INFO",
          link: "/dashboard/approvals",
        },
      });
    }

    // Also notify admins
    const admins = await prisma.user.findMany({
      where: { role: "ADMIN", id: { not: session.user.id } },
      select: { id: true },
    });

    for (const admin of admins) {
      await prisma.notification.create({
        data: {
          userId: admin.id,
          title: "New Leave Request",
          message: `${session.user.name} has requested ${leaveRequest.leaveType.name}.`,
          type: "INFO",
          link: "/dashboard/approvals",
        },
      });
    }

    return NextResponse.json(leaveRequest, { status: 201 });
  } catch (error) {
    console.error("Create leave request error:", error);
    return NextResponse.json({ error: "Failed to create leave request" }, { status: 500 });
  }
}
