import { NextResponse } from "next/server";
import { ApprovalState, DepartmentKey, ProductionPlanState } from "@prisma/client";
import { getServerSession } from "next-auth";
import { authOptions } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import { canAccessOperations, canManageOperations, resolveOwnerUserId, varianceUnits } from "@/lib/operations";
import { getWeekBounds } from "@/lib/kpis/date";

type CreatePlanBody = {
  weekStart?: string;
  lineName?: string;
  plannedUnits?: number;
  capacityUnits?: number;
  forecastUnits?: number;
  state?: ProductionPlanState;
};

const VALID_STATES = new Set<ProductionPlanState>([
  ProductionPlanState.draft,
  ProductionPlanState.simulated,
  ProductionPlanState.locked,
  ProductionPlanState.approved,
  ProductionPlanState.released,
  ProductionPlanState.replanned,
]);
const OWNER_ONLY_STATES = new Set<ProductionPlanState>([ProductionPlanState.approved, ProductionPlanState.released]);

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

  if (!canAccessOperations(session.user.role, session.user.department)) {
    return NextResponse.json({ error: "Forbidden" }, { status: 403 });
  }

  const { searchParams } = new URL(request.url);
  const weekStart = searchParams.get("weekStart");
  const plans = await prisma.productionPlan.findMany({
    where: weekStart
      ? {
          department: DepartmentKey.operaciones,
          weekStart: new Date(`${weekStart}T00:00:00.000Z`),
        }
      : {
          department: DepartmentKey.operaciones,
        },
    orderBy: [{ weekStart: "desc" }, { updatedAt: "desc" }],
    take: 200,
  });

  return NextResponse.json({ ok: true, plans });
}

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

  if (!canManageOperations(session.user.role, session.user.department)) {
    return NextResponse.json({ error: "Only owner/operations leader can create production plans." }, { status: 403 });
  }

  const body = (await request.json()) as CreatePlanBody;
  const { weekStart, weekEnd } = getWeekBounds(body.weekStart);
  const lineName = body.lineName?.trim() || "Línea principal";
  const plannedUnits = Math.max(0, body.plannedUnits ?? 0);
  const capacityUnits = Math.max(0, body.capacityUnits ?? plannedUnits);

  let forecastUnits = Math.max(0, body.forecastUnits ?? 0);
  if (forecastUnits === 0) {
    const forecasts = await prisma.salesForecast.findMany({
      where: {
        department: DepartmentKey.operaciones,
        weekStart: new Date(`${weekStart}T00:00:00.000Z`),
      },
    });
    forecastUnits = forecasts.reduce((acc, forecast) => acc + forecast.forecastUnits, 0);
  }

  const state = body.state && VALID_STATES.has(body.state) ? body.state : ProductionPlanState.draft;
  if (OWNER_ONLY_STATES.has(state) && session.user.role !== "owner") {
    return NextResponse.json({ error: "Only owner can create plans as approved/released." }, { status: 403 });
  }
  const plan = await prisma.productionPlan.create({
    data: {
      department: DepartmentKey.operaciones,
      weekStart: new Date(`${weekStart}T00:00:00.000Z`),
      weekEnd: new Date(`${weekEnd}T00:00:00.000Z`),
      lineName,
      plannedUnits,
      forecastUnits,
      capacityUnits,
      varianceUnits: varianceUnits(forecastUnits, plannedUnits),
      state,
      createdById: session.user.id,
      approvedById: state === ProductionPlanState.approved || state === ProductionPlanState.released ? session.user.id : null,
      approvedAt: state === ProductionPlanState.approved || state === ProductionPlanState.released ? new Date() : null,
    },
  });

  if (state === ProductionPlanState.locked) {
    const ownerUserId = await resolveOwnerUserId();
    await prisma.approvalRequest.create({
      data: {
        department: DepartmentKey.operaciones,
        requestType: "production_plan_lock",
        productionPlanId: plan.id,
        submittedById: session.user.id,
        approverId: ownerUserId,
        state: ApprovalState.pending_owner,
        reason: "Plan locked and awaiting owner approval.",
      },
    });
  }

  return NextResponse.json({ ok: true, plan });
}
