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

type UpsertForecastBody = {
  weekStart?: string;
  weekEnd?: string;
  locationId?: string | null;
  sku?: string | null;
  lastWeekSales?: number;
  forecastUnits?: number;
  multiplier?: number;
  state?: SalesForecastState;
};

const VALID_STATES = new Set<SalesForecastState>([
  SalesForecastState.draft,
  SalesForecastState.published,
  SalesForecastState.superseded,
]);

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 where = weekStart
    ? {
        department: DepartmentKey.operaciones,
        weekStart: new Date(`${weekStart}T00:00:00.000Z`),
      }
    : { department: DepartmentKey.operaciones };

  const forecasts = await prisma.salesForecast.findMany({
    where,
    orderBy: [{ weekStart: "desc" }, { createdAt: "desc" }],
    take: 120,
  });

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

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 update forecast." }, { status: 403 });
  }

  const body = (await request.json()) as UpsertForecastBody;
  const multiplier = Math.max(0.1, body.multiplier ?? 1.2);
  const lastWeekSales = Math.max(0, body.lastWeekSales ?? 0);
  const forecastUnits = Math.max(
    0,
    body.forecastUnits !== undefined ? body.forecastUnits : forecastUnitsWithMultiplier(lastWeekSales, multiplier)
  );
  const { weekStart, weekEnd } = getWeekBounds(body.weekStart);
  const parsedWeekEnd =
    body.weekEnd && /^\\d{4}-\\d{2}-\\d{2}$/.test(body.weekEnd) ? body.weekEnd : weekEnd;
  const state = body.state && VALID_STATES.has(body.state) ? body.state : SalesForecastState.published;

  const forecast = await prisma.salesForecast.create({
    data: {
      department: DepartmentKey.operaciones,
      weekStart: new Date(`${weekStart}T00:00:00.000Z`),
      weekEnd: new Date(`${parsedWeekEnd}T00:00:00.000Z`),
      locationId: body.locationId?.trim() || null,
      sku: body.sku?.trim() || null,
      forecastUnits,
      multiplier,
      state,
      createdById: session.user.id,
    },
  });

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