// 일자별 발주/재고 현황 — 창고 × 품목 매트릭스
// 선택한 날짜에 판매 가능한 품목(sale_start_date ~ sale_end_date) 만 추려서
// 각 창고별 발주수량과 현재고를 반환한다.
import { NextRequest, NextResponse } from "next/server";
import { queryRows } from "@/lib/db";
import { requireMomoAdmin } from "@/lib/momo-guard";

export async function POST(req: NextRequest) {
  const g = await requireMomoAdmin();
  if (g instanceof NextResponse) return g;

  const body = await req.json().catch(() => ({}));
  const targetDate = (body.targetDate as string) || ""; // YYYY-MM-DD, 비우면 오늘
  const keyword = (body.keyword as string) || "";

  const date = targetDate || new Date().toISOString().slice(0, 10);

  // 1) 활성 창고
  const warehouses = await queryRows<{ OBJID: string; WH_CODE: string; WH_NAME: string }>(
    `SELECT objid AS "OBJID", wh_code AS "WH_CODE", wh_name AS "WH_NAME"
       FROM momo_warehouses
      WHERE COALESCE(is_del,'N') != 'Y'
      ORDER BY wh_code`
  );

  // 2) 선택일에 판매가능한 품목
  const itemConds: string[] = [
    "COALESCE(I.is_del, 'N') != 'Y'",
    "COALESCE(I.is_hidden, 'N') != 'Y'",
    "UPPER(COALESCE(I.status, '')) = 'ACTIVE'",
    `(I.sale_start_date IS NULL OR $1::date >= I.sale_start_date::date)`,
    `(I.sale_end_date   IS NULL OR $1::date <= I.sale_end_date::date)`,
  ];
  const params: unknown[] = [date];
  if (keyword) {
    params.push(keyword);
    itemConds.push(`(I.item_name ILIKE '%' || $2 || '%' OR I.item_code ILIKE '%' || $2 || '%')`);
  }

  const items = await queryRows<{
    OBJID: string; ITEM_CODE: string; ITEM_NAME: string;
    UNIT: string; UNIT_PRICE: string; IS_TAX_FREE: string;
    SALE_START_DATE: string | null; SALE_END_DATE: string | null;
    VENDOR_NAME: string | null;
  }>(
    `SELECT
       I.objid       AS "OBJID",
       I.item_code   AS "ITEM_CODE",
       I.item_name   AS "ITEM_NAME",
       I.unit        AS "UNIT",
       I.unit_price  AS "UNIT_PRICE",
       I.is_tax_free AS "IS_TAX_FREE",
       TO_CHAR(I.sale_start_date, 'YYYY-MM-DD HH24:MI') AS "SALE_START_DATE",
       TO_CHAR(I.sale_end_date,   'YYYY-MM-DD HH24:MI') AS "SALE_END_DATE",
       V.supply_name AS "VENDOR_NAME"
     FROM momo_items I
     LEFT JOIN supply_mng V ON I.vendor_objid = V.objid::text
     WHERE ${itemConds.join(" AND ")}
     ORDER BY I.item_name ASC`,
    params
  );

  if (items.length === 0) {
    return NextResponse.json({ WAREHOUSES: warehouses, ITEMS: [], TOTAL_CNT: 0 });
  }

  // 3) 창고별 재고 (해당 일자 시점이 아닌 현재 보유 재고. 일자별 시계열 재고는 별도)
  const stockRows = await queryRows<{ ITEM_OBJID: string; WH_CODE: string; STOCK_QTY: string }>(
    `SELECT S.item_objid::text AS "ITEM_OBJID",
            W.wh_code           AS "WH_CODE",
            S.qty               AS "STOCK_QTY"
       FROM momo_stocks S
       JOIN momo_warehouses W ON W.objid = S.wh_objid
      WHERE COALESCE(W.is_del,'N') != 'Y'
        AND S.item_objid IN (${items.map((_, i) => `$${i + 1}`).join(",")})`,
    items.map((it) => it.OBJID)
  );

  // 4) 창고별 발주수량 — 출고된 창고 기준 (momo_stock_moves OUT 이력으로 매핑)
  //    APPROVED 이후만 stock_moves 가 기록되므로, 그 이전(REQUESTED) 발주는
  //    거래처(user_info)의 default_wh_objid 로 가상 배정 (출고 예정 창고)
  const moveRows = await queryRows<{ ITEM_OBJID: string; WH_CODE: string; ORDER_QTY: string }>(
    `SELECT SM.item_objid::text AS "ITEM_OBJID",
            W.wh_code            AS "WH_CODE",
            SUM(-SM.qty)::text   AS "ORDER_QTY"
       FROM momo_stock_moves SM
       JOIN momo_warehouses W ON W.objid = SM.wh_objid
       JOIN momo_orders O     ON O.objid::text = SM.ref_objid::text
      WHERE SM.ref_type = 'ORDER'
        AND SM.move_type = 'OUT'
        AND COALESCE(W.is_del,'N') != 'Y'
        AND O.order_date = $1::date
        AND O.status IN ('APPROVED','INVOICED','PAID')
        AND COALESCE(O.is_del,'N') != 'Y'
        AND SM.item_objid IN (${items.map((_, i) => `$${i + 2}`).join(",")})
      GROUP BY SM.item_objid, W.wh_code`,
    [date, ...items.map((it) => it.OBJID)]
  );

  // REQUESTED 상태(아직 출고 전) 발주는 거래처 default 창고로 배정 (fallback: WH001)
  const pendingRows = await queryRows<{ ITEM_OBJID: string; WH_CODE: string; ORDER_QTY: string }>(
    `SELECT OI.item_objid::text AS "ITEM_OBJID",
            COALESCE(W.wh_code, 'WH001') AS "WH_CODE",
            SUM(OI.qty)::text AS "ORDER_QTY"
       FROM momo_order_items OI
       JOIN momo_orders O ON O.objid = OI.order_objid
       LEFT JOIN user_info U ON U.user_id = O.customer_objid
       LEFT JOIN momo_warehouses W ON W.objid = U.default_wh_objid
      WHERE COALESCE(OI.kind, 'ITEM') = 'ITEM'
        AND COALESCE(O.is_del, 'N') != 'Y'
        AND O.status = 'REQUESTED'
        AND O.order_date = $1::date
        AND OI.item_objid IN (${items.map((_, i) => `$${i + 2}`).join(",")})
      GROUP BY OI.item_objid, W.wh_code`,
    [date, ...items.map((it) => it.OBJID)]
  );

  // 매트릭스 조립 — 각 품목별 STOCK / ORDER 객체 (wh_code → qty)
  type ItemMatrix = {
    OBJID: string; ITEM_CODE: string; ITEM_NAME: string;
    UNIT: string; UNIT_PRICE: string; IS_TAX_FREE: string;
    SALE_START_DATE: string | null; SALE_END_DATE: string | null;
    VENDOR_NAME: string | null;
    STOCK: Record<string, number>;   // wh_code → 현재고
    ORDER: Record<string, number>;   // wh_code → 발주수량
    TOTAL_STOCK: number;
    TOTAL_ORDER: number;
  };
  const byItem = new Map<string, ItemMatrix>();
  for (const it of items) {
    byItem.set(it.OBJID, {
      OBJID: it.OBJID,
      ITEM_CODE: it.ITEM_CODE,
      ITEM_NAME: it.ITEM_NAME,
      UNIT: it.UNIT,
      UNIT_PRICE: it.UNIT_PRICE,
      IS_TAX_FREE: it.IS_TAX_FREE,
      SALE_START_DATE: it.SALE_START_DATE,
      SALE_END_DATE: it.SALE_END_DATE,
      VENDOR_NAME: it.VENDOR_NAME,
      STOCK: {}, ORDER: {}, TOTAL_STOCK: 0, TOTAL_ORDER: 0,
    });
  }
  for (const s of stockRows) {
    const m = byItem.get(s.ITEM_OBJID);
    if (!m) continue;
    const q = Number(s.STOCK_QTY);
    m.STOCK[s.WH_CODE] = (m.STOCK[s.WH_CODE] || 0) + q;
    m.TOTAL_STOCK += q;
  }
  for (const o of [...moveRows, ...pendingRows]) {
    const m = byItem.get(o.ITEM_OBJID);
    if (!m) continue;
    const q = Number(o.ORDER_QTY);
    m.ORDER[o.WH_CODE] = (m.ORDER[o.WH_CODE] || 0) + q;
    m.TOTAL_ORDER += q;
  }

  return NextResponse.json({
    WAREHOUSES: warehouses,
    ITEMS: Array.from(byItem.values()),
    TOTAL_CNT: byItem.size,
  });
}
