import { NextResponse } from "next/server";
import { and, eq, isNull } from "drizzle-orm";
import { revalidatePath } from "next/cache";
import { db } from "@/db";
import { menuItemSbisLinks, menuItems, sbisCatalogItems } from "@/db/schema";
import { adminAuthorized } from "@/lib/admin-auth";
import { recordAudit } from "@/lib/audit";

function fail(error: string, status = 400) { return NextResponse.json({ error }, { status }); }

export async function POST(request: Request) {
  if (!(await adminAuthorized(request, true))) return fail("Unauthorized", 401);
  if (!db) return fail("Database is not configured", 503);
  const body = await request.json() as { menuItemId?: unknown; sbisId?: unknown };
  const menuItemId = Number(body.menuItemId);
  // Bot catalog ids are numeric (contract §3); accept both shapes.
  const sbisId = typeof body.sbisId === "number" ? String(Math.trunc(body.sbisId)) : typeof body.sbisId === "string" ? body.sbisId.trim() : "";
  if (!Number.isInteger(menuItemId) || !sbisId) return fail("Укажите карточку сайта и sbis_id");
  try {
    const [[item], [catalog], [itemLink], [sbisLink]] = await Promise.all([
      db.select({ id: menuItems.id }).from(menuItems).where(eq(menuItems.id, menuItemId)).limit(1),
      db.select({ sbisId: sbisCatalogItems.sbisId }).from(sbisCatalogItems).where(eq(sbisCatalogItems.sbisId, sbisId)).limit(1),
      db.select({ id: menuItemSbisLinks.id }).from(menuItemSbisLinks).where(and(eq(menuItemSbisLinks.menuItemId, menuItemId), isNull(menuItemSbisLinks.unlinkedAt))).limit(1),
      db.select({ id: menuItemSbisLinks.id }).from(menuItemSbisLinks).where(and(eq(menuItemSbisLinks.sbisId, sbisId), isNull(menuItemSbisLinks.unlinkedAt))).limit(1)
    ]);
    if (!item) return fail("Карточка сайта не найдена", 404);
    if (!catalog) return fail("Позиция отсутствует в актуальном каталоге СБИС", 409);
    if (itemLink) return fail("Карточка уже привязана; сначала отвяжите её", 409);
    if (sbisLink) return fail("Эта позиция СБИС уже привязана к другой карточке", 409);
    await db.insert(menuItemSbisLinks).values({ menuItemId, sbisId, linkedBy: "admin" });
    await recordAudit("sbis_link", { entityType: "menu_item", entityId: menuItemId, details: { sbis_id: sbisId } });
    revalidatePath("/menu");
    return NextResponse.json({ ok: true });
  } catch (error) { return fail(error instanceof Error ? error.message : "Не удалось привязать позицию", 503); }
}

export async function DELETE(request: Request) {
  if (!(await adminAuthorized(request, true))) return fail("Unauthorized", 401);
  if (!db) return fail("Database is not configured", 503);
  const body = await request.json() as { menuItemId?: unknown; reason?: unknown };
  const menuItemId = Number(body.menuItemId);
  if (!Number.isInteger(menuItemId)) return fail("Укажите карточку сайта");
  const reason = typeof body.reason === "string" ? body.reason.slice(0, 200) : "admin";
  await db.update(menuItemSbisLinks).set({ unlinkedAt: new Date(), unlinkReason: reason }).where(and(eq(menuItemSbisLinks.menuItemId, menuItemId), isNull(menuItemSbisLinks.unlinkedAt)));
  await recordAudit("sbis_unlink", { entityType: "menu_item", entityId: menuItemId, details: { reason } });
  revalidatePath("/menu");
  return NextResponse.json({ ok: true });
}
