import { NextRequest, NextResponse } from "next/server";
import { pool } from "@/lib/db";
import { getSession } from "@/lib/session";
import { createObjectId } from "@/lib/utils";

// 원본: /purchaseOrder/purchaseOrderFormPopup_PriceSave.do — 단가만 저장
// 품목의 PARTNER_PRICE, PRICE1~4, SUPPLY_UNIT_PRICE, VAT 관련 값만 업데이트.
// 마스터의 수량/거래처/납품일 등은 건드리지 않음.
// 동시발주 마스터인 경우 슬레이브 품목/합계도 동기화 (마스터 품목을 DELETE+INSERT로 복제).
interface PriceRow {
  OBJID?: string;
  PARTNER_PRICE?: string | number;
  PRICE1?: string | number;
  PRICE2?: string | number;
  PRICE3?: string | number;
  PRICE4?: string | number;
  ORDER_QTY?: string | number;
}

const toNum = (v: unknown) => {
  const s = String(v ?? "").replace(/,/g, "");
  const n = Number(s);
  return Number.isFinite(n) ? n : 0;
};
const toStr = (v: unknown) => (v === undefined || v === null ? "" : String(v));

export async function POST(request: NextRequest) {
  const user = await getSession();
  if (!user) return NextResponse.json({ success: false }, { status: 401 });

  const body = await request.json();
  const masterObjId = toStr(body.objId || body.MASTER_OBJID);
  const vatMethod = toStr(body.vat_method);
  const rows: PriceRow[] = Array.isArray(body.parts) ? body.parts : [];
  if (!masterObjId) {
    return NextResponse.json({ success: false, message: "objId가 필요합니다." });
  }
  const vatRate = vatMethod === "0000270" ? 0 : 0.1;

  const client = await pool.connect();
  try {
    await client.query("BEGIN");

    // 결재중/결재완료/취소 상태는 단가저장 불가. 슬레이브도 차단 (마스터에서만).
    const check = await client.query(
      `SELECT COALESCE(status,'') AS status,
              COALESCE(multi_yn,'') AS multi_yn,
              COALESCE(multi_master_yn,'') AS multi_master_yn
         FROM purchase_order_master WHERE objid::text = $1`,
      [masterObjId],
    );
    const cur = check.rows[0];
    if (cur?.multi_yn === "Y" && cur?.multi_master_yn !== "Y") {
      await client.query("ROLLBACK");
      return NextResponse.json({
        success: false,
        message: "동시발주 슬레이브건은 마스터 발주서에서 수정해주세요.",
      });
    }
    if (
      cur?.status === "approvalRequest" ||
      cur?.status === "approvalComplete" ||
      cur?.status === "cancel"
    ) {
      await client.query("ROLLBACK");
      const label =
        cur.status === "approvalRequest"
          ? "결재중"
          : cur.status === "approvalComplete"
            ? "결재완료"
            : "취소";
      return NextResponse.json({
        success: false,
        message: `${label} 상태의 발주서는 단가저장할 수 없습니다.`,
      });
    }

    let totalSupplyUnitPrice = 0;
    let totalSupplyPrice = 0;
    for (const r of rows) {
      if (!toStr(r.OBJID)) continue;
      const qty = toNum(r.ORDER_QTY);
      const unit = toNum(r.PARTNER_PRICE);
      const sum = qty * (unit + toNum(r.PRICE1) + toNum(r.PRICE2) + toNum(r.PRICE3) + toNum(r.PRICE4));
      totalSupplyUnitPrice += sum;
      totalSupplyPrice += qty * unit;
      await client.query(
        `UPDATE purchase_order_part SET
           partner_price = $2, price1 = $3, price2 = $4, price3 = $5, price4 = $6,
           supply_unit_price = $7,
           supply_unit_vat_price = $8,
           supply_unit_vat_sum_price = $9,
           real_supply_price = $9,
           update_date = now(), modifier = $10
         WHERE objid = $1`,
        [
          toStr(r.OBJID),
          String(unit),
          String(toNum(r.PRICE1)),
          String(toNum(r.PRICE2)),
          String(toNum(r.PRICE3)),
          String(toNum(r.PRICE4)),
          String(sum),
          String(Math.round(sum * vatRate)),
          String(Math.round(sum * (1 + vatRate))),
          user.userId,
        ],
      );
    }
    // 동시발주 슬레이브 품목 동기화: 마스터 현재 품목을 슬레이브로 DELETE+INSERT 복제.
    // save/route.ts의 슬레이브 생성 로직과 동일 패턴 — 단가가 바뀌면 슬레이브 품목도 같이.
    const slavesRes = await client.query(
      `SELECT objid::text AS objid FROM purchase_order_master
         WHERE multi_master_objid::text = $1 AND objid::text <> $1`,
      [masterObjId],
    );
    if (slavesRes.rows.length > 0) {
      const masterPartsRes = await client.query(
        `SELECT part_objid, part_no, part_name, spec, maker, unit,
                order_qty, partner_price, price1, price2, price3, price4,
                supply_unit_price, supply_unit_vat_price, supply_unit_vat_sum_price,
                real_supply_price, real_order_qty, total_order_qty, stock_qty,
                remark, ld_part_objid
           FROM purchase_order_part
          WHERE purchase_order_master_objid::text = $1
          ORDER BY regdate ASC, objid ASC`,
        [masterObjId],
      );
      for (const slave of slavesRes.rows) {
        await client.query(
          `DELETE FROM purchase_order_part WHERE purchase_order_master_objid::text = $1`,
          [slave.objid],
        );
        for (const mp of masterPartsRes.rows) {
          await client.query(
            `INSERT INTO purchase_order_part (
               objid, purchase_order_master_objid, part_objid, part_no, part_name,
               spec, maker, unit, order_qty, partner_price,
               price1, price2, price3, price4,
               supply_unit_price, supply_unit_vat_price, supply_unit_vat_sum_price,
               real_supply_price, real_order_qty, total_order_qty, stock_qty,
               remark, writer, regdate, status, ld_part_objid
             ) VALUES (
               $1, $2, $3, $4, $5, $6, $7, $8, $9, $10,
               $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21,
               $22, $23, now(), 'create', $24
             )`,
            [
              createObjectId(),
              slave.objid,
              toStr(mp.part_objid),
              toStr(mp.part_no),
              toStr(mp.part_name),
              toStr(mp.spec),
              toStr(mp.maker),
              toStr(mp.unit),
              toStr(mp.order_qty),
              toStr(mp.partner_price),
              toStr(mp.price1),
              toStr(mp.price2),
              toStr(mp.price3),
              toStr(mp.price4),
              toStr(mp.supply_unit_price),
              toStr(mp.supply_unit_vat_price),
              toStr(mp.supply_unit_vat_sum_price),
              toStr(mp.real_supply_price),
              toStr(mp.real_order_qty),
              toStr(mp.total_order_qty),
              toStr(mp.stock_qty),
              toStr(mp.remark),
              user.userId,
              toStr(mp.ld_part_objid),
            ],
          );
        }
      }
    }

    // 마스터 + 슬레이브의 단건 합계 동기화 (discount_price_all은 건드리지 않음 — 원본 동작)
    const discount = toNum(body.discount_price);
    const totalPrice = totalSupplyUnitPrice - discount;
    const realSupply = Math.round(totalPrice * (1 + vatRate));
    const negoRate =
      totalSupplyPrice > 0 ? Math.round((discount / totalSupplyPrice) * 10000) / 100 : 0;
    await client.query(
      `UPDATE purchase_order_master SET
         total_supply_unit_price = $2, total_supply_price = $3,
         total_real_supply_price = $4, total_price = $5,
         discount_price = $6, nego_rate = $7
       WHERE objid::text = $1 OR multi_master_objid::text = $1`,
      [
        masterObjId,
        String(totalSupplyUnitPrice),
        String(totalSupplyPrice),
        String(realSupply),
        String(totalPrice),
        String(discount),
        String(negoRate),
      ],
    );

    // 원본 updatePurchaseOrderMasterPriceAll + updatePurchaseOrderPriceTxt
    // 마스터+슬레이브에 total_supply_unit_price_all, total_price_all, 한글 금액 세팅
    // (save/route.ts와 동일 패턴)
    const supplyUnitAll = totalSupplyUnitPrice * (1 + slavesRes.rows.length);
    await client.query(
      `UPDATE purchase_order_master SET
          total_supply_unit_price_all = $2,
          total_price_all = CASE
            WHEN COALESCE(discount_price, '0')::numeric != 0
            THEN (COALESCE(total_real_supply_price, '0')::numeric - COALESCE(discount_price, '0')::numeric)::text
            ELSE NULL END,
          total_price_txt = NUM_TO_KOR(COALESCE(total_supply_unit_price, '0'), '일금 ', ' 원정 (￦ ')
            || TO_CHAR(COALESCE(total_supply_unit_price, '0')::numeric, '999,999,999,999') || ')',
          total_price_txt_all = NUM_TO_KOR(COALESCE(total_supply_unit_price_all, '0'), '일금 ', ' 원정 (￦ ')
            || TO_CHAR(COALESCE(total_supply_unit_price_all, '0')::numeric, '999,999,999,999') || ')'
        WHERE objid::text = $1 OR multi_master_objid::text = $1`,
      [masterObjId, String(supplyUnitAll)],
    );

    await client.query("COMMIT");
    return NextResponse.json({ success: true, message: "단가가 저장되었습니다." });
  } catch (e) {
    await client.query("ROLLBACK");
    console.error("order/price-save:", e);
    return NextResponse.json(
      { success: false, message: "단가 저장 중 오류가 발생했습니다." },
      { status: 500 },
    );
  } finally {
    client.release();
  }
}
