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

// 원본: purchaseOrder.mergePurchaseOrderMaster + purchaseOrder.initPurchaseOrderPart + mergePurchaseOrderPart
// 발주서 UPSERT (단일발주 + 동시발주)
// 동시발주: 하나의 공급처에 대해 여러 프로젝트를 묶어서 발주. 마스터 1건 +
// 추가 프로젝트 수만큼 슬레이브 PO 생성. 슬레이브는 multi_yn='Y', multi_master_yn='N',
// multi_master_objid=master, 품목은 마스터 것을 복사 (각 프로젝트별 contract_mgmt_objid만 다름).
interface MultiProjectEntry {
  contract_mgmt_objid?: string;
  unit_code?: string;
  delivery_plan_date?: string;
  delivery_plan_qty?: string | number;
  objid?: string; // 기존 슬레이브 OBJID (편집 시)
}

interface PartRow {
  OBJID?: string;
  PART_OBJID?: string;
  PART_NO?: string;
  PART_NAME?: string;
  SPEC?: string;
  MAKER?: string;
  UNIT?: string;
  ORDER_QTY?: string | number;
  PARTNER_PRICE?: string | number;
  PRICE1?: string | number;
  PRICE2?: string | number;
  PRICE3?: string | number;
  PRICE4?: string | number;
  SUPPLY_UNIT_PRICE?: string | number;
  SUPPLY_UNIT_VAT_PRICE?: string | number;
  SUPPLY_UNIT_VAT_SUM_PRICE?: string | number;
  REMARK?: string;
  LD_PART_OBJID?: string;
  TOTAL_ORDER_QTY?: string | number;
  STOCK_QTY?: string | number;
  REAL_ORDER_QTY?: string | number;
}

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

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 inputObjId = toStr(body.objId || body.MASTER_OBJID);
  const isNew = !inputObjId;
  const masterObjId = isNew ? createObjectId() : inputObjId;
  const parts: PartRow[] = Array.isArray(body.parts) ? body.parts : [];
  const rawMultiProjects: MultiProjectEntry[] = Array.isArray(body.multi_projects)
    ? body.multi_projects.filter((m: MultiProjectEntry) => toStr(m?.contract_mgmt_objid))
    : [];
  // 동시적용 중복 방어:
  //   1) 마스터와 같은 프로젝트는 거부 (프론트 우회 방어)
  //   2) 슬레이브끼리 같은 프로젝트 중복은 첫 건만 남기고 제거
  const masterProject = toStr(body.contract_mgmt_objid);
  if (rawMultiProjects.some((m) => toStr(m.contract_mgmt_objid) === masterProject)) {
    return NextResponse.json({
      success: false,
      message: "동시적용 프로젝트에 마스터 프로젝트를 포함할 수 없습니다.",
    });
  }
  const seenProjects = new Set<string>();
  const multiProjects: MultiProjectEntry[] = [];
  for (const m of rawMultiProjects) {
    const key = toStr(m.contract_mgmt_objid);
    if (seenProjects.has(key)) {
      return NextResponse.json({
        success: false,
        message: "동시적용 프로젝트가 중복되었습니다. 같은 프로젝트는 1회만 선택할 수 있습니다.",
      });
    }
    seenProjects.add(key);
    multiProjects.push(m);
  }
  const isMulti = multiProjects.length > 0;
  // 발주처는 FITO 고정 — 클라이언트 입력 무시
  const poClientId = COMPANY_INFO.PO_CLIENT_ID;

  // 필수 검증
  if (!toStr(body.partner_objid)) {
    return NextResponse.json({ success: false, message: "공급처(PARTNER)를 선택하세요." });
  }
  if (!toStr(body.contract_mgmt_objid)) {
    return NextResponse.json({ success: false, message: "프로젝트를 선택하세요." });
  }
  if (!toStr(body.type)) {
    return NextResponse.json({ success: false, message: "발주부품을 선택하세요." });
  }

  // 합계 계산 (서버사이드에서 재계산: 품목 공급가 = qty * (partner_price + price1..4))
  let totalSupplyUnitPrice = 0; // 공급단가 합계 (POP.supply_unit_price 합)
  let totalSupplyPrice = 0; // 공급가 합계 (price1..4 포함하지 않은 단가*수량 합)
  for (const p of parts) {
    const qty = toNum(p.ORDER_QTY);
    const unit = toNum(p.PARTNER_PRICE);
    const sum = qty * (unit + toNum(p.PRICE1) + toNum(p.PRICE2) + toNum(p.PRICE3) + toNum(p.PRICE4));
    totalSupplyUnitPrice += sum;
    totalSupplyPrice += qty * unit;
  }
  const discountPrice = toNum(body.discount_price);
  const totalPrice = totalSupplyUnitPrice - discountPrice;
  // VAT 10% 기본
  const vatRate = toStr(body.vat_method) === "0000270" ? 0 : 0.1; // 0000270 = 부가세 없음 (표준코드 추정)
  const totalRealSupplyPrice = Math.round(totalPrice * (1 + vatRate));
  const negoRate =
    totalSupplyPrice > 0 ? Math.round((discountPrice / totalSupplyPrice) * 10000) / 100 : 0;

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

    // PO 번호 자동생성 (신규 때만). 형식: PO-YYMM-SEQ
    let poNo = toStr(body.purchase_order_no);
    if (isNew || !poNo) {
      const now = new Date();
      const yymm =
        String(now.getFullYear()).slice(2) + String(now.getMonth() + 1).padStart(2, "0");
      const r = await client.query(
        `SELECT COALESCE(MAX(
            CASE WHEN SPLIT_PART(purchase_order_no, '-', 3) ~ '^[0-9]+$'
                 THEN SPLIT_PART(purchase_order_no, '-', 3)::int ELSE 0 END), 0) + 1 AS next_seq
           FROM purchase_order_master`,
      );
      const nextSeq = Number(r.rows[0]?.next_seq ?? 1);
      poNo = `PO-${yymm}-${nextSeq}`;
    }

    // 공급처 정보 자동 채우기 (admin_supply_mng 조회)
    let supplyInfo: Record<string, string> = {};
    if (toStr(body.partner_objid)) {
      const r = await client.query(
        `SELECT bus_reg_no, supply_address, supply_tel_no, supply_fax_no, office_no, email, charge_user_name
           FROM admin_supply_mng WHERE objid::text = $1`,
        [toStr(body.partner_objid)],
      );
      if (r.rows[0]) {
        supplyInfo = {
          SUPPLY_BUS_NO: toStr(r.rows[0].bus_reg_no),
          SUPPLY_USER_NAME: toStr(r.rows[0].charge_user_name),
          SUPPLY_USER_HP: toStr(r.rows[0].office_no),
          SUPPLY_USER_TEL: toStr(r.rows[0].supply_tel_no),
          SUPPLY_USER_FAX: toStr(r.rows[0].supply_fax_no),
          SUPPLY_USER_EMAIL: toStr(r.rows[0].email),
          SUPPLY_ADDR: toStr(r.rows[0].supply_address),
        };
      }
    }

    if (isNew) {
      await client.query(
        `INSERT INTO purchase_order_master (
           objid, purchase_order_no, po_client_id, partner_objid, my_company_objid,
           contract_mgmt_objid, unit_code, bom_report_objid, sales_request_objid,
           type, order_type_cd, delivery_date, delivery_place, effective_date,
           payment_terms, inspect_method, vat_method, sales_mng_user_id,
           title, remark, status, writer, regdate, purchase_date,
           supply_bus_no, supply_user_name, supply_user_hp, supply_user_tel,
           supply_user_fax, supply_user_email, supply_addr,
           total_supply_unit_price, total_supply_price, total_real_supply_price,
           total_price, total_price_all, discount_price, discount_price_all,
           nego_rate, multi_yn, multi_master_yn, multi_master_objid, purchase_order_no_org
         ) VALUES (
           $1, $2, $3, $4, $5, $6::numeric, $7, $8, $9,
           $10, $11, $12, $13, $14, $15, $16, $17, $18,
           $19, $20, 'create', $21, now(), TO_CHAR(NOW(), 'YYYY-MM-DD'),
           $22, $23, $24, $25, $26, $27, $28,
           $29, $30, $31, $32, $33, $34, $35, $36, $37, $38, $39, $40
         )`,
        [
          masterObjId,
          poNo,
          poClientId,
          toStr(body.partner_objid),
          toStr(body.my_company_objid) || poClientId,
          toStr(body.contract_mgmt_objid),
          toStr(body.unit_code),
          toStr(body.bom_report_objid),
          toStr(body.sales_request_objid),
          toStr(body.type),
          toStr(body.order_type_cd),
          toStr(body.delivery_date),
          toStr(body.delivery_place),
          toStr(body.effective_date),
          toStr(body.payment_terms),
          toStr(body.inspect_method),
          toStr(body.vat_method),
          toStr(body.sales_mng_user_id) || user.userId,
          toStr(body.title),
          toStr(body.remark),
          user.userId,
          supplyInfo.SUPPLY_BUS_NO || "",
          supplyInfo.SUPPLY_USER_NAME || "",
          supplyInfo.SUPPLY_USER_HP || "",
          supplyInfo.SUPPLY_USER_TEL || "",
          supplyInfo.SUPPLY_USER_FAX || "",
          supplyInfo.SUPPLY_USER_EMAIL || "",
          supplyInfo.SUPPLY_ADDR || "",
          String(totalSupplyUnitPrice),
          String(totalSupplyPrice),
          String(totalRealSupplyPrice),
          String(totalPrice),
          String(totalRealSupplyPrice), // 단일발주는 전체=자신
          String(discountPrice),
          String(discountPrice),
          String(negoRate),
          isMulti ? "Y" : "",
          isMulti ? "Y" : "",
          "", // multi_master_objid (master 자기 자신이므로 비움)
          toStr(body.purchase_order_no_org),
        ],
      );
    } else {
      // 결재중/결재완료/취소 상태는 수정 불가. 슬레이브도 차단 (마스터를 통해서만).
      const check = await client.query(
        `SELECT COALESCE(multi_yn,'') AS multi_yn,
                COALESCE(multi_master_yn,'') AS multi_master_yn,
                COALESCE(status,'') AS status
           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} 상태의 발주서는 수정할 수 없습니다.`,
        });
      }
      await client.query(
        `UPDATE purchase_order_master SET
           po_client_id = $2, partner_objid = $3,
           contract_mgmt_objid = $4::numeric, unit_code = $5,
           type = $6, order_type_cd = $7, delivery_date = $8, delivery_place = $9,
           effective_date = $10, payment_terms = $11, inspect_method = $12,
           vat_method = $13, sales_mng_user_id = $14, title = $15, remark = $16,
           supply_bus_no = $17, supply_user_name = $18, supply_user_hp = $19,
           supply_user_tel = $20, supply_user_fax = $21, supply_user_email = $22,
           supply_addr = $23,
           total_supply_unit_price = $24, total_supply_price = $25,
           total_real_supply_price = $26, total_price = $27, total_price_all = $28,
           discount_price = $29, discount_price_all = $30, nego_rate = $31,
           multi_yn = $32, multi_master_yn = $33
         WHERE objid::text = $1`,
        [
          masterObjId,
          poClientId,
          toStr(body.partner_objid),
          toStr(body.contract_mgmt_objid),
          toStr(body.unit_code),
          toStr(body.type),
          toStr(body.order_type_cd),
          toStr(body.delivery_date),
          toStr(body.delivery_place),
          toStr(body.effective_date),
          toStr(body.payment_terms),
          toStr(body.inspect_method),
          toStr(body.vat_method),
          toStr(body.sales_mng_user_id) || user.userId,
          toStr(body.title),
          toStr(body.remark),
          supplyInfo.SUPPLY_BUS_NO || "",
          supplyInfo.SUPPLY_USER_NAME || "",
          supplyInfo.SUPPLY_USER_HP || "",
          supplyInfo.SUPPLY_USER_TEL || "",
          supplyInfo.SUPPLY_USER_FAX || "",
          supplyInfo.SUPPLY_USER_EMAIL || "",
          supplyInfo.SUPPLY_ADDR || "",
          String(totalSupplyUnitPrice),
          String(totalSupplyPrice),
          String(totalRealSupplyPrice),
          String(totalPrice),
          String(totalRealSupplyPrice),
          String(discountPrice),
          String(discountPrice),
          String(negoRate),
          isMulti ? "Y" : "",
          isMulti ? "Y" : "",
        ],
      );
    }

    // 품목 재등록: 기존 delete 후 재삽입
    await client.query(
      `DELETE FROM purchase_order_part WHERE purchase_order_master_objid = $1`,
      [masterObjId],
    );
    for (const p of parts) {
      if (!toStr(p.PART_OBJID) && !toStr(p.PART_NO)) continue;
      const qty = toNum(p.ORDER_QTY);
      const unit = toNum(p.PARTNER_PRICE);
      const sum = qty * (unit + toNum(p.PRICE1) + toNum(p.PRICE2) + toNum(p.PRICE3) + toNum(p.PRICE4));
      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(),
          masterObjId,
          toStr(p.PART_OBJID),
          toStr(p.PART_NO),
          toStr(p.PART_NAME),
          toStr(p.SPEC),
          toStr(p.MAKER),
          toStr(p.UNIT),
          String(qty),
          String(unit),
          String(toNum(p.PRICE1)),
          String(toNum(p.PRICE2)),
          String(toNum(p.PRICE3)),
          String(toNum(p.PRICE4)),
          String(sum),
          String(Math.round(sum * vatRate)),
          String(Math.round(sum * (1 + vatRate))),
          String(Math.round(sum * (1 + vatRate))),
          String(toNum(p.REAL_ORDER_QTY) || qty),
          String(toNum(p.TOTAL_ORDER_QTY)),
          String(toNum(p.STOCK_QTY)),
          toStr(p.REMARK),
          user.userId,
          toStr(p.LD_PART_OBJID),
        ],
      );
    }

    // === 동시발주 슬레이브 처리 ===
    // 기존 슬레이브 전부 삭제 후 새로 생성 (parts도 동일하게)
    await client.query(
      `DELETE FROM purchase_order_part
         WHERE purchase_order_master_objid IN (
           SELECT objid FROM purchase_order_master
            WHERE multi_master_objid::text = $1 AND objid::text <> $1
         )`,
      [masterObjId],
    );
    await client.query(
      `DELETE FROM purchase_order_master
         WHERE multi_master_objid::text = $1 AND objid::text <> $1`,
      [masterObjId],
    );

    // 슬레이브 unit_code 재조회용: 마스터 유닛의 task_name 한 번만 조회
    // 원본 common.getUnitCodeList — 동시 BOM으로 올라온 프로젝트는 같은 task_name의 유닛을 공유.
    let masterTaskName = "";
    if (isMulti && toStr(body.unit_code)) {
      const r = await client.query(
        `SELECT task_name FROM pms_wbs_task WHERE objid::text = $1`,
        [toStr(body.unit_code)],
      );
      masterTaskName = toStr(r.rows[0]?.task_name);
    }

    for (const m of multiProjects) {
      const slaveObjId = createObjectId();
      const slaveContract = toStr(m.contract_mgmt_objid);
      // 슬레이브 프로젝트에서 같은 task_name의 유닛 찾아 unit_code 재조회 (원본 getUnitCodeList)
      const unitRes = await client.query(
        `SELECT objid::text AS code FROM pms_wbs_task
           WHERE contract_objid::text = $1
             AND (TRIM(UPPER(COALESCE(task_name, ''))) = TRIM(UPPER($2))
               OR TRIM(UPPER(COALESCE(unit_no, '') || '-' || COALESCE(task_name, ''))) = TRIM(UPPER($2)))
           ORDER BY unit_no ASC LIMIT 1`,
        [slaveContract, masterTaskName],
      );
      const slaveUnit = toStr(unitRes.rows[0]?.code);
      if (!slaveUnit) {
        const pr = await client.query(
          `SELECT project_no FROM project_mgmt WHERE objid::text = $1`,
          [slaveContract],
        );
        await client.query("ROLLBACK");
        return NextResponse.json({
          success: false,
          message: `${toStr(pr.rows[0]?.project_no) || slaveContract} 프로젝트에 '${masterTaskName}' 유닛이 없습니다. 동시 BOM 설정을 확인하세요.`,
        });
      }
      const slaveDelivDate = toStr(m.delivery_plan_date) || toStr(body.delivery_date);
      const slaveDelivQty = toStr(m.delivery_plan_qty);
      // 슬레이브 PO 번호 자동생성
      const seqRes = await client.query(
        `SELECT COALESCE(MAX(
            CASE WHEN SPLIT_PART(purchase_order_no, '-', 3) ~ '^[0-9]+$'
                 THEN SPLIT_PART(purchase_order_no, '-', 3)::int ELSE 0 END), 0) + 1 AS next_seq
           FROM purchase_order_master`,
      );
      const slaveSeq = Number(seqRes.rows[0]?.next_seq ?? 1);
      const now = new Date();
      const yymm =
        String(now.getFullYear()).slice(2) + String(now.getMonth() + 1).padStart(2, "0");
      const slavePoNo = `PO-${yymm}-${slaveSeq}`;

      await client.query(
        `INSERT INTO purchase_order_master (
           objid, purchase_order_no, po_client_id, partner_objid, my_company_objid,
           contract_mgmt_objid, unit_code, bom_report_objid, sales_request_objid,
           type, order_type_cd, delivery_date, delivery_place, effective_date,
           payment_terms, inspect_method, vat_method, sales_mng_user_id,
           title, remark, status, writer, regdate, purchase_date,
           supply_bus_no, supply_user_name, supply_user_hp, supply_user_tel,
           supply_user_fax, supply_user_email, supply_addr,
           total_supply_unit_price, total_supply_price, total_real_supply_price,
           total_price, total_price_all, discount_price, discount_price_all,
           nego_rate, multi_yn, multi_master_yn, multi_master_objid,
           delivery_plan_date, delivery_plan_qty, purchase_order_no_org
         ) VALUES (
           $1, $2, $3, $4, $5, $6::numeric, $7, $8, $9,
           $10, $11, $12, $13, $14, $15, $16, $17, $18,
           $19, $20, 'create', $21, now(), TO_CHAR(NOW(), 'YYYY-MM-DD'),
           $22, $23, $24, $25, $26, $27, $28,
           $29, $30, $31, $32, $33, $34, $35, $36, 'Y', 'N', $37,
           $38, $39, ''
         )`,
        [
          slaveObjId,
          slavePoNo,
          poClientId,
          toStr(body.partner_objid),
          toStr(body.my_company_objid) || poClientId,
          slaveContract,
          slaveUnit,
          "",
          "",
          toStr(body.type),
          toStr(body.order_type_cd),
          slaveDelivDate,
          toStr(body.delivery_place),
          toStr(body.effective_date),
          toStr(body.payment_terms),
          toStr(body.inspect_method),
          toStr(body.vat_method),
          toStr(body.sales_mng_user_id) || user.userId,
          toStr(body.title),
          toStr(body.remark),
          user.userId,
          supplyInfo.SUPPLY_BUS_NO || "",
          supplyInfo.SUPPLY_USER_NAME || "",
          supplyInfo.SUPPLY_USER_HP || "",
          supplyInfo.SUPPLY_USER_TEL || "",
          supplyInfo.SUPPLY_USER_FAX || "",
          supplyInfo.SUPPLY_USER_EMAIL || "",
          supplyInfo.SUPPLY_ADDR || "",
          String(totalSupplyUnitPrice),
          String(totalSupplyPrice),
          String(totalRealSupplyPrice),
          String(totalPrice),
          String(totalRealSupplyPrice),
          String(discountPrice),
          String(discountPrice),
          String(negoRate),
          masterObjId,
          slaveDelivDate,
          slaveDelivQty,
        ],
      );
      // 슬레이브 품목도 마스터 것을 그대로 복사
      for (const p of parts) {
        if (!toStr(p.PART_OBJID) && !toStr(p.PART_NO)) continue;
        const qty = toNum(p.ORDER_QTY);
        const unit = toNum(p.PARTNER_PRICE);
        const sum =
          qty *
          (unit + toNum(p.PRICE1) + toNum(p.PRICE2) + toNum(p.PRICE3) + toNum(p.PRICE4));
        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(),
            slaveObjId,
            toStr(p.PART_OBJID),
            toStr(p.PART_NO),
            toStr(p.PART_NAME),
            toStr(p.SPEC),
            toStr(p.MAKER),
            toStr(p.UNIT),
            String(qty),
            String(unit),
            String(toNum(p.PRICE1)),
            String(toNum(p.PRICE2)),
            String(toNum(p.PRICE3)),
            String(toNum(p.PRICE4)),
            String(sum),
            String(Math.round(sum * vatRate)),
            String(Math.round(sum * (1 + vatRate))),
            String(Math.round(sum * (1 + vatRate))),
            String(toNum(p.REAL_ORDER_QTY) || qty),
            String(toNum(p.TOTAL_ORDER_QTY)),
            String(toNum(p.STOCK_QTY)),
            toStr(p.REMARK),
            user.userId,
            toStr(p.LD_PART_OBJID),
          ],
        );
      }
    }

    // 원본 updatePurchaseOrderMasterPriceAll + updatePurchaseOrderPriceTxt 를 1건으로 병합.
    // 마스터와 모든 슬레이브에 동일한 집계값을 세팅:
    //   - total_supply_unit_price_all: 마스터 공급단가 × (1 + 슬레이브수)
    //   - total_price_all: real - discount (할인 없으면 NULL)
    //   - total_price_txt / _all: NUM_TO_KOR 한글 금액 (PG 함수)
    // discount_price_all은 저장 시점에 건드리지 않음 — 별도 네고 수정 화면에서 세팅하는 게 원본 동작.
    const supplyUnitAll = totalSupplyUnitPrice * (1 + multiProjects.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,
      objId: masterObjId,
      purchaseOrderNo: poNo,
      message: isNew ? "등록되었습니다." : "수정되었습니다.",
    });
  } catch (e) {
    await client.query("ROLLBACK");
    console.error("order/save:", e);
    return NextResponse.json(
      { success: false, message: "저장 중 오류가 발생했습니다." },
      { status: 500 },
    );
  } finally {
    client.release();
  }
}
