import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { requireRole } from "@/lib/auth";
import { INVENTORY_CATEGORIES, INVENTORY_UNITS } from "@/lib/constants";

/** Inventory items + dashboard stats + recent movements. */
export async function GET() {
  const session = await requireRole("INSTITUTION_ADMIN");
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const [items, movements, monthMovements] = await Promise.all([
    prisma.inventoryItem.findMany({
      where: { institutionId: session.institutionId },
      orderBy: [{ isActive: "asc" }, { name: "asc" }],
    }),
    prisma.stockMovement.findMany({
      where: { institutionId: session.institutionId },
      orderBy: { createdAt: "desc" },
      take: 10,
      include: {
        item: { select: { name: true, unit: true } },
        createdBy: { select: { name: true } },
      },
    }),
    prisma.stockMovement.findMany({
      where: {
        institutionId: session.institutionId,
        createdAt: { gte: new Date(new Date().toISOString().slice(0, 7) + "-01") },
      },
      select: { id: true },
    }),
  ]);

  const stockValue = items
    .filter((i) => i.isActive)
    .reduce((sum, i) => sum + i.quantity * Number(i.unitPrice), 0);

  return NextResponse.json({
    stats: {
      totalItems: items.filter((i) => i.isActive).length,
      stockValue,
      lowStock: items.filter((i) => i.isActive && i.quantity <= i.minQuantity).length,
      movementsThisMonth: monthMovements.length,
    },
    items: items.map((i) => ({
      id: i.id,
      name: i.name,
      nameBn: i.nameBn,
      category: i.category,
      unit: i.unit,
      quantity: i.quantity,
      minQuantity: i.minQuantity,
      unitPrice: Number(i.unitPrice),
      value: i.quantity * Number(i.unitPrice),
      location: i.location,
      isActive: i.isActive,
      low: i.isActive && i.quantity <= i.minQuantity,
    })),
    recentMovements: movements.map((m) => ({
      id: m.id,
      itemName: m.item.name,
      unit: m.item.unit,
      type: m.type,
      quantity: m.quantity,
      party: m.party,
      note: m.note,
      by: m.createdBy?.name ?? null,
      createdAt: m.createdAt,
    })),
  });
}

/** Create an inventory item (initial quantity logs an IN movement). */
export async function POST(req: Request) {
  const session = await requireRole("INSTITUTION_ADMIN");
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  try {
    const body = await req.json();
    const name = String(body.name ?? "").trim();
    const quantity = Math.max(0, Number(body.quantity) || 0);
    if (!name) return NextResponse.json({ error: "Missing fields" }, { status: 400 });

    const item = await prisma.$transaction(async (tx) => {
      const created = await tx.inventoryItem.create({
        data: {
          institutionId: session.institutionId!,
          name,
          nameBn: String(body.nameBn ?? "").trim() || null,
          category: INVENTORY_CATEGORIES.includes(body.category as never) ? body.category : "OTHER",
          unit: INVENTORY_UNITS.includes(body.unit as never) ? body.unit : "PCS",
          quantity,
          minQuantity: Math.max(0, Number(body.minQuantity) || 0),
          unitPrice: body.unitPrice !== undefined ? Number(body.unitPrice) : 0,
          location: String(body.location ?? "").trim() || null,
          note: String(body.note ?? "").trim() || null,
        },
      });
      if (quantity > 0) {
        await tx.stockMovement.create({
          data: {
            institutionId: session.institutionId!,
            itemId: created.id,
            type: "IN",
            quantity,
            note: "Initial stock",
            createdById: session.userId,
          },
        });
      }
      return created;
    });

    return NextResponse.json({ item });
  } catch {
    return NextResponse.json({ error: "Could not create item" }, { status: 500 });
  }
}
