"use client";

import { useEffect, useState, useCallback, useRef } from "react";
import { Plus, Send, Search, RefreshCcw, X, Download, Image as ImageIcon } from "lucide-react";
import Swal from "sweetalert2";
import { captureAndShare } from "@/lib/capture-share";
import { SearchableSelect } from "@/components/ui/searchable-select";

interface ProcRow {
  OBJID: string; PROC_NO: string; PROC_DATE: string;
  VENDOR_OBJID: string | null; VENDOR_NAME: string | null;
  STATUS: string; TOTAL_AMOUNT: number; LINE_CNT: number; MEMO?: string;
}
interface ProcDetail {
  OBJID: string; PROC_NO: string; PROC_DATE: string; STATUS: string;
  TOTAL_AMOUNT: number; MEMO?: string;
  VENDOR_OBJID: string | null; VENDOR_NAME: string | null;
  DELIVERY_PLACE?: string;
  DELIVERY_PERIOD?: string;
  PAYMENT_TERMS?: string;
  FREIGHT_TERMS?: string;
}
interface ProcLine {
  OBJID: string; ITEM_OBJID: string; ITEM_CODE: string; ITEM_NAME: string;
  UNIT: string; QTY: number; COST_PRICE: number; TOTAL_AMOUNT: number;
  RECEIVED_QTY: number;
}
interface Vendor { OBJID: string; VENDOR_NAME: string }
interface Item {
  OBJID: string; ITEM_CODE: string; ITEM_NAME: string; UNIT: string;
  COST_PRICE: number; UNIT_PRICE: number;
  VENDOR_OBJID?: string; VENDOR_NAME?: string;
}

const fmt = (n: number | string | undefined | null) => Number(n || 0).toLocaleString("ko-KR");
const STATUS_LABEL: Record<string, string> = {
  OPEN: "작성중", REQUESTED: "발주요청", RECEIVED: "입고완료", CANCELLED: "취소",
};
const STATUS_COLOR: Record<string, string> = {
  OPEN:      "bg-slate-100 text-slate-600 border-slate-200",
  REQUESTED: "bg-amber-100 text-amber-700 border-amber-200",
  RECEIVED:  "bg-emerald-100 text-emerald-700 border-emerald-200",
  CANCELLED: "bg-rose-100 text-rose-600 border-rose-200",
};

// 기본 한 달 전 ~ 오늘
function defaultRange() {
  const e = new Date(), s = new Date();
  s.setDate(s.getDate() - 30);
  const fmt = (d: Date) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
  return [fmt(s), fmt(e)];
}

export default function ProcurementsPage() {
  const [list, setList] = useState<ProcRow[]>([]);
  const [statusFilter, setStatusFilter] = useState("");
  const [vendorFilter, setVendorFilter] = useState("");
  const [[dateFrom, dateTo], setRange] = useState(defaultRange());
  const [activeId, setActiveId] = useState("");
  const [detail, setDetail] = useState<{ proc: ProcDetail; items: ProcLine[] } | null>(null);
  const [vendors, setVendors] = useState<Vendor[]>([]);
  const [busy, setBusy] = useState(false);
  const [pickerOpen, setPickerOpen] = useState(false);

  const load = useCallback(async () => {
    const res = await fetch("/api/m/procurements/list", {
      method: "POST", headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        status: statusFilter || undefined,
        vendorObjid: vendorFilter || undefined,
        dateFrom: dateFrom || undefined,
        dateTo: dateTo || undefined,
      }),
    });
    const j = await res.json();
    const rows: ProcRow[] = j.RESULTLIST ?? [];
    setList(rows);
    if (rows.length && !rows.some((r) => r.OBJID === activeId)) setActiveId(rows[0].OBJID);
    if (!rows.length) { setActiveId(""); setDetail(null); }
  }, [statusFilter, vendorFilter, dateFrom, dateTo, activeId]);

  const loadVendors = async () => {
    const r = await fetch("/api/m/vendors/list", { method: "POST", headers: { "Content-Type": "application/json" }, body: "{}" });
    setVendors((await r.json()).RESULTLIST ?? []);
  };

  const loadDetail = useCallback(async () => {
    if (!activeId) { setDetail(null); return; }
    const res = await fetch("/api/m/procurements/detail", {
      method: "POST", headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ objid: activeId }),
    });
    const j = await res.json();
    if (j.success) setDetail({ proc: j.proc, items: j.items });
  }, [activeId]);

  useEffect(() => { loadVendors(); }, []);
  useEffect(() => { load(); }, [load]);
  useEffect(() => { loadDetail(); }, [loadDetail]);

  const createNew = async () => {
    const res = await fetch("/api/m/procurements/create-empty", {
      method: "POST", headers: { "Content-Type": "application/json" }, body: "{}",
    });
    const j = await res.json();
    if (j.success) {
      setActiveId(j.objId);
      load();
    }
  };

  const updateHeader = async (patch: { vendorObjid?: string | null; memo?: string }) => {
    if (!detail) return;
    const res = await fetch("/api/m/procurements/update-header", {
      method: "POST", headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ objid: detail.proc.OBJID, ...patch }),
    });
    if ((await res.json()).success) loadDetail();
  };

  const updateLine = async (line: { objid?: string; itemObjid?: string; qty: number; costPrice: number; delete?: boolean }) => {
    if (!detail) return;
    const res = await fetch("/api/m/procurements/lines/save", {
      method: "POST", headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ procObjid: detail.proc.OBJID, lines: [line] }),
    });
    const j = await res.json();
    if (j.success) loadDetail();
    else Swal.fire({ icon: "error", title: "저장 실패", text: j.message });
  };

  const deleteLine = async (objid: string) => {
    const ok = await Swal.fire({ icon: "question", title: "라인을 삭제하시겠습니까?", showCancelButton: true });
    if (!ok.isConfirmed) return;
    updateLine({ objid, qty: 0, costPrice: 0, delete: true });
  };

  const sendOrder = async () => {
    if (!detail) return;
    if (!detail.proc.VENDOR_OBJID) {
      Swal.fire({ icon: "warning", title: "공급업체를 먼저 선택하세요." });
      return;
    }
    if (detail.items.length === 0) {
      Swal.fire({ icon: "warning", title: "발주 라인을 1개 이상 입력하세요." });
      return;
    }
    const ok = await Swal.fire({
      icon: "question", title: "공급업체로 발주서를 발송하시겠습니까?",
      html: `<b>${detail.proc.VENDOR_NAME ?? "-"}</b> 에게 메일 발송 + 상태 변경<br>총액: ₩${fmt(detail.proc.TOTAL_AMOUNT)}`,
      showCancelButton: true, confirmButtonText: "발주 요청", cancelButtonText: "취소",
      confirmButtonColor: "#0f766e",
    });
    if (!ok.isConfirmed) return;
    setBusy(true);
    try {
      const res = await fetch("/api/m/procurements/send", {
        method: "POST", headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ objid: detail.proc.OBJID }),
      });
      const j = await res.json();
      if (j.success) {
        Swal.fire({
          icon: j.mailSent ? "success" : "warning",
          title: "발주 요청 완료",
          html: j.mailSent ? `메일 발송 완료 → <b>${j.vendorEmail}</b>` : (j.vendorEmail ? `메일 실패: ${j.mailError ?? ""}` : "공급업체 이메일 미설정 — 별도 통보 필요"),
        });
        load();
      } else {
        Swal.fire({ icon: "error", title: "실패", text: j.message });
      }
    } finally { setBusy(false); }
  };

  // 작성중(OPEN) 발주서 삭제 — 라인 포함 hard delete
  const deleteProc = async () => {
    if (!detail) return;
    if (detail.proc.STATUS !== "OPEN") {
      Swal.fire({ icon: "warning", title: "작성중 상태만 삭제 가능합니다." });
      return;
    }
    const ok = await Swal.fire({
      icon: "warning",
      title: `발주서 ${detail.proc.PROC_NO} 를 삭제하시겠습니까?`,
      text: "작성중인 라인까지 모두 삭제됩니다.",
      showCancelButton: true,
      confirmButtonColor: "#dc2626",
      confirmButtonText: "삭제",
    });
    if (!ok.isConfirmed) return;
    setBusy(true);
    try {
      const res = await fetch("/api/m/procurements/delete", {
        method: "POST", headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ objid: detail.proc.OBJID }),
      });
      const j = await res.json();
      if (j.success) {
        Swal.fire({ icon: "success", title: "삭제되었습니다", timer: 1200, showConfirmButton: false });
        setActiveId(null);
        load();
      } else {
        Swal.fire({ icon: "error", title: "삭제 실패", text: j.message });
      }
    } finally { setBusy(false); }
  };

  return (
    <div className="space-y-3">
      <div className="flex items-end justify-between flex-wrap gap-2">
        <div>
          <h1 className="text-xl font-bold">매입 발주서 관리</h1>
          <p className="text-xs text-slate-500 mt-0.5">왼쪽에서 발주서를 선택하면 오른쪽에 양식이 보여요. [+ 새 발주]로 작성, [발주 요청]으로 공급업체에 메일 발송.</p>
        </div>
        <div className="flex gap-1.5 items-center flex-nowrap overflow-x-auto pb-1 max-w-full">
          <input type="date" value={dateFrom} onChange={(e) => setRange([e.target.value, dateTo])}
            className="h-8 px-2 rounded border border-slate-300 text-xs shrink-0 w-[130px]" />
          <span className="text-slate-400 text-xs shrink-0">~</span>
          <input type="date" value={dateTo} onChange={(e) => setRange([dateFrom, e.target.value])}
            className="h-8 px-2 rounded border border-slate-300 text-xs shrink-0 w-[130px]" />
          <div className="shrink-0 w-[150px]">
            <SearchableSelect
              options={[{ value: "", label: "전체 공급업체" }, ...vendors.map((v) => ({ value: v.OBJID, label: v.VENDOR_NAME }))]}
              value={vendorFilter}
              onChange={setVendorFilter}
              placeholder="공급업체"
            />
          </div>
          <select value={statusFilter} onChange={(e) => setStatusFilter(e.target.value)}
            className="h-8 px-2 rounded border border-slate-300 bg-white text-xs shrink-0">
            <option value="">전체 상태</option>
            {Object.entries(STATUS_LABEL).map(([k, v]) => <option key={k} value={k}>{v}</option>)}
          </select>
          <button onClick={createNew} className="h-8 px-2 rounded bg-emerald-700 text-white text-xs font-bold inline-flex items-center gap-1 hover:bg-emerald-800 shrink-0">
            <Plus size={12} /> 새 발주
          </button>
        </div>
      </div>

      <div className="grid grid-cols-1 lg:grid-cols-[360px_1fr] gap-3">
        <div className="bg-white border border-slate-200 rounded-xl overflow-hidden">
          <div className="px-3 py-2 bg-slate-50 border-b border-slate-200 text-xs font-semibold text-slate-600">
            발주서 목록 ({list.length}건)
          </div>
          <div className="overflow-x-auto max-h-[60vh] lg:max-h-[calc(100vh-220px)]">
            <table className="w-full text-xs">
              <thead className="bg-slate-50 text-slate-500">
                <tr>
                  <th className="text-left px-2 py-2">발주번호</th>
                  <th className="text-left px-2 py-2">일자</th>
                  <th className="text-left px-2 py-2">공급업체</th>
                  <th className="text-right px-2 py-2">금액</th>
                  <th className="text-center px-2 py-2">상태</th>
                </tr>
              </thead>
              <tbody>
                {list.length === 0 ? (
                  <tr><td colSpan={5} className="text-center py-12 text-slate-400">발주서가 없습니다.</td></tr>
                ) : list.map((p) => (
                  <tr key={p.OBJID}
                      onClick={() => setActiveId(p.OBJID)}
                      className={`cursor-pointer border-t border-slate-100 ${activeId === p.OBJID ? "bg-emerald-50" : "hover:bg-slate-50"}`}>
                    <td className="px-2 py-2 font-semibold">{p.PROC_NO}</td>
                    <td className="px-2 py-2 text-slate-500">{p.PROC_DATE}</td>
                    <td className="px-2 py-2 truncate max-w-[120px]">{p.VENDOR_NAME ?? <span className="text-slate-300">미선택</span>}</td>
                    <td className="px-2 py-2 text-right tabular-nums">₩{fmt(p.TOTAL_AMOUNT)}</td>
                    <td className="px-2 py-2 text-center">
                      <span className={`inline-block px-1.5 py-0.5 rounded text-[10px] font-semibold border ${STATUS_COLOR[p.STATUS] ?? "bg-slate-100 text-slate-500 border-slate-200"}`}>
                        {STATUS_LABEL[p.STATUS] ?? p.STATUS}
                      </span>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>

        <div className="bg-white border border-slate-200 rounded-xl overflow-hidden flex flex-col">
          <div className="px-3 py-2 bg-slate-50 border-b border-slate-200 text-xs font-semibold text-slate-600 flex items-center justify-between">
            <span>발주서</span>
            {detail && detail.proc.STATUS === "OPEN" && (
              <div className="flex items-center gap-2">
                <button onClick={deleteProc} disabled={busy}
                  className="inline-flex items-center gap-1 h-8 px-3 rounded border border-rose-300 bg-white text-rose-700 text-xs font-bold hover:bg-rose-50 disabled:opacity-50">
                  삭제
                </button>
                <button onClick={sendOrder} disabled={busy}
                  className="inline-flex items-center gap-1 h-8 px-3 rounded bg-emerald-700 text-white text-xs font-bold hover:bg-emerald-800 disabled:opacity-50">
                  <Send size={12} /> 발주 요청
                </button>
              </div>
            )}
            {detail && detail.proc.STATUS === "REQUESTED" && (
              <span className="text-[11px] text-amber-700">발주 요청 완료 — 공급업체 응답 대기</span>
            )}
          </div>
          <div className="flex-1 lg:overflow-auto p-4">
            {!detail ? (
              <div className="h-full flex items-center justify-center text-slate-400">왼쪽에서 발주서를 선택하거나 [+ 새 발주]를 누르세요.</div>
            ) : (
              <ProcurementForm
                detail={detail}
                vendors={vendors}
                onSetVendor={(v) => updateHeader({ vendorObjid: v || null })}
                onSetMemo={(m) => updateHeader({ memo: m })}
                onSetTerm={(field, val) => updateHeader({ [field]: val })}
                onAddPicker={() => setPickerOpen(true)}
                onUpdateLine={updateLine}
                onDeleteLine={deleteLine}
              />
            )}
          </div>
        </div>
      </div>

      {pickerOpen && detail && (
        <ItemPicker
          vendorObjid={detail.proc.VENDOR_OBJID}
          existingItemIds={new Set(detail.items.map((i) => i.ITEM_OBJID))}
          onClose={() => setPickerOpen(false)}
          onAddItems={async (selected) => {
            if (selected.length === 0) { setPickerOpen(false); return; }
            const res = await fetch("/api/m/procurements/lines/save", {
              method: "POST", headers: { "Content-Type": "application/json" },
              body: JSON.stringify({
                procObjid: detail.proc.OBJID,
                lines: selected.map((it) => ({
                  itemObjid: it.OBJID,
                  qty: 1,
                  costPrice: Number(it.COST_PRICE) || 0,
                })),
              }),
            });
            const j = await res.json();
            if (j.success) { setPickerOpen(false); loadDetail(); }
            else Swal.fire({ icon: "error", title: "추가 실패", text: j.message });
          }}
        />
      )}
    </div>
  );
}

function ProcurementForm({ detail, vendors, onSetVendor, onSetMemo, onSetTerm, onAddPicker, onUpdateLine, onDeleteLine }: {
  detail: { proc: ProcDetail; items: ProcLine[] };
  vendors: Vendor[];
  onSetVendor: (id: string) => void;
  onSetMemo: (m: string) => void;
  onSetTerm: (field: "deliveryPlace" | "deliveryPeriod" | "paymentTerms" | "freightTerms", val: string) => void;
  onAddPicker: () => void;
  onUpdateLine: (line: { objid?: string; itemObjid?: string; qty: number; costPrice: number }) => void;
  onDeleteLine: (objid: string) => void;
}) {
  // 입금완료(PAID)/취소(CANCELLED) 전까지 수정 허용 — 발주요청/입고완료/부분입고 도 수량 수정 가능
  const editable = !["PAID", "CANCELLED"].includes(detail.proc.STATUS);
  const formRef = useRef<HTMLDivElement>(null);

  const handleCapture = async () => {
    if (!formRef.current) return;
    await captureAndShare({
      node: formRef.current,
      filename: `${detail.proc.PROC_NO}_발주서`,
      shareTitle: `${detail.proc.PROC_NO} 발주서`,
      shareText: detail.proc.VENDOR_NAME ?? "",
      forceWidth: 1100, // 엑셀 가로 출력처럼 펼쳐서 캡처
    });
  };

  return (
    <div className="text-[12px]">
      {/* 공유/인쇄/엑셀 버튼 — 캡처 영역 밖 */}
      <div className="flex justify-end gap-2 mb-2 print:hidden flex-wrap">
        <button
          type="button"
          onClick={handleCapture}
          className="inline-flex items-center gap-1 h-8 px-3 rounded-lg bg-amber-100 text-amber-800 text-xs font-bold hover:bg-amber-200"
          title="이미지로 캡처해 카톡 등에 공유"
        >
          <ImageIcon size={14} /> 이미지 공유
        </button>
        <button
          type="button"
          onClick={() => window.print()}
          className="inline-flex items-center gap-1 h-8 px-3 rounded-lg bg-slate-100 text-slate-700 text-xs font-bold hover:bg-slate-200"
          title="인쇄"
        >
          🖨 인쇄
        </button>
        <a
          href={`/api/m/procurements/excel/${detail.proc.OBJID}`}
          className="inline-flex items-center gap-1 h-8 px-3 rounded-lg bg-emerald-100 text-emerald-800 text-xs font-bold hover:bg-emerald-200"
          title="발주서 엑셀 다운로드"
        >
          <Download size={14} /> 엑셀 다운로드
        </a>
      </div>

      <div ref={formRef} className="bg-white p-3">
      <div className="text-center">
        <h2 className="text-2xl font-bold tracking-[0.4em] text-slate-900">발 주 서</h2>
      </div>

      <table className="text-[11px] mt-3 border border-slate-400" style={{borderCollapse:'collapse',width:'auto'}}>
        <tbody>
          <tr>
            <th className="border border-slate-400 bg-slate-100 px-2 py-1 w-[100px] text-center">분류번호</th>
            <td className="border border-slate-400 px-3 py-1 font-semibold w-[200px]">매입발주</td>
          </tr>
          <tr>
            <th className="border border-slate-400 bg-slate-100 px-2 py-1 text-center">발주서번호</th>
            <td className="border border-slate-400 px-3 py-1 font-mono">{detail.proc.PROC_NO}</td>
          </tr>
          <tr>
            <th className="border border-slate-400 bg-slate-100 px-2 py-1 text-center">발주일</th>
            <td className="border border-slate-400 px-3 py-1">{detail.proc.PROC_DATE}</td>
          </tr>
          <tr>
            <th className="border border-slate-400 bg-slate-100 px-2 py-1 text-center">공급업체</th>
            <td className="border border-slate-400 px-3 py-1">
              {editable ? (
                <select value={detail.proc.VENDOR_OBJID ?? ""}
                  onChange={(e) => onSetVendor(e.target.value)}
                  className="h-7 px-2 rounded border border-slate-300 text-[11px] bg-white">
                  <option value="">-- 공급업체 선택 --</option>
                  {vendors.map((v) => <option key={v.OBJID} value={v.OBJID}>{v.VENDOR_NAME}</option>)}
                </select>
              ) : (
                <span className="font-semibold">{detail.proc.VENDOR_NAME ?? "-"}</span>
              )}
            </td>
          </tr>
        </tbody>
      </table>

      <p className="mt-3 font-semibold text-[12px]">1. 물품의 표시</p>
      {editable && (
        <div className="flex gap-2 mb-2 text-[11px] flex-wrap">
          <button onClick={onAddPicker}
            className="inline-flex items-center gap-1 h-7 px-3 rounded bg-emerald-100 text-emerald-800 font-bold hover:bg-emerald-200">
            <Plus size={12} /> 품목 추가
          </button>
          <span className="self-center text-slate-400">— 모달에서 공급업체 필터, 결과내 검색, 다중 선택 가능</span>
        </div>
      )}
      <table className="w-full text-[11px] border border-slate-400" style={{borderCollapse:'collapse'}}>
        <thead className="bg-slate-100">
          <tr>
            <th className="border border-slate-400 px-1 py-1 w-8">#</th>
            <th className="border border-slate-400 px-2 py-1 text-left">품명</th>
            <th className="border border-slate-400 px-1 py-1 w-12">단위</th>
            <th className="border border-slate-400 px-1 py-1 w-16">수량</th>
            <th className="border border-slate-400 px-1 py-1 w-20">단가</th>
            <th className="border border-slate-400 px-1 py-1 w-24">금액</th>
            {editable && <th className="border border-slate-400 px-1 py-1 w-10"></th>}
          </tr>
        </thead>
        <tbody className="tabular-nums">
          {detail.items.length === 0 ? (
            <tr><td colSpan={editable ? 7 : 6} className="border border-slate-400 px-2 py-6 text-center text-slate-400">품목이 없습니다. {editable && "[품목 추가] 버튼으로 등록."}</td></tr>
          ) : detail.items.map((it, idx) => (
            <ProcLineRow key={it.OBJID} line={it} idx={idx + 1} editable={editable}
              onSave={(qty, cost) => onUpdateLine({ objid: it.OBJID, qty, costPrice: cost })}
              onDelete={() => onDeleteLine(it.OBJID)} />
          ))}
        </tbody>
      </table>
      <div className="text-right text-[11px] mt-1 text-slate-500">(V.A.T 별도, 단위: 원)</div>

      <table className="ml-auto text-[12px] tabular-nums mt-3">
        <tbody>
          <tr className="border-t-2 border-slate-900 font-bold">
            <td className="px-3 py-1.5">총액</td>
            <td className="px-3 py-1.5 text-right text-emerald-700 min-w-[140px]">₩ {fmt(detail.proc.TOTAL_AMOUNT)}</td>
          </tr>
        </tbody>
      </table>

      <p className="mt-4 font-semibold text-[12px]">2. 납품조건</p>
      <ol className="text-[11px] mt-1 space-y-1 leading-relaxed list-decimal pl-5">
        <li>상기 품목의 납기 지연 시, 지연일수 매 1일에 대하여 미납 금액의 3/1000을 납품대금 지불 시 우선 공제한다.</li>
        <li>납품된 물품은 당사의 지정인에게 검수를 받아야 하며, 부적합품은 즉시 납품자의 비용으로 반출하여야 한다.</li>
        <li>상기 수량 및 규격은 당사의 사정에 의하여 변경될 수 있으며, 납품자는 이에 대하여 이의를 제기할 수 없다.</li>
      </ol>

      <table className="text-[11px] mt-2 border border-slate-400 w-full" style={{borderCollapse:'collapse'}}>
        <tbody>
          <tr>
            <th className="border border-slate-400 bg-slate-100 px-2 py-1 text-center font-semibold w-[80px]">4) 납품장소</th>
            <td className="border border-slate-400 px-2 py-0.5">
              {editable ? (
                <input defaultValue={detail.proc.DELIVERY_PLACE ?? ""}
                  onBlur={(e) => onSetTerm("deliveryPlace", e.target.value)}
                  className="w-full h-7 px-2 text-[11px] outline-none border-0 bg-transparent" />
              ) : (
                <span>{detail.proc.DELIVERY_PLACE || "-"}</span>
              )}
            </td>
            <th className="border border-slate-400 bg-slate-100 px-2 py-1 text-center font-semibold w-[80px]">6) 대금지불</th>
            <td className="border border-slate-400 px-2 py-0.5">
              {editable ? (
                <input defaultValue={detail.proc.PAYMENT_TERMS ?? ""}
                  onBlur={(e) => onSetTerm("paymentTerms", e.target.value)}
                  className="w-full h-7 px-2 text-[11px] outline-none border-0 bg-transparent" />
              ) : (
                <span>{detail.proc.PAYMENT_TERMS || "-"}</span>
              )}
            </td>
          </tr>
          <tr>
            <th className="border border-slate-400 bg-slate-100 px-2 py-1 text-center font-semibold">5) 납품기간</th>
            <td className="border border-slate-400 px-2 py-0.5">
              {editable ? (
                <input defaultValue={detail.proc.DELIVERY_PERIOD ?? ""}
                  onBlur={(e) => onSetTerm("deliveryPeriod", e.target.value)}
                  className="w-full h-7 px-2 text-[11px] outline-none border-0 bg-transparent" />
              ) : (
                <span>{detail.proc.DELIVERY_PERIOD || "-"}</span>
              )}
            </td>
            <th className="border border-slate-400 bg-slate-100 px-2 py-1 text-center font-semibold">7) 운임부담</th>
            <td className="border border-slate-400 px-2 py-0.5">
              {editable ? (
                <input defaultValue={detail.proc.FREIGHT_TERMS ?? ""}
                  onBlur={(e) => onSetTerm("freightTerms", e.target.value)}
                  className="w-full h-7 px-2 text-[11px] outline-none border-0 bg-transparent" />
              ) : (
                <span>{detail.proc.FREIGHT_TERMS || "-"}</span>
              )}
            </td>
          </tr>
        </tbody>
      </table>

      <ol className="text-[11px] mt-2 space-y-1 leading-relaxed list-decimal pl-5" start={8}>
        <li>본 발주서는 납품자가 FAX 또는 기타 방법으로 접수 후 3일 이내에 이의를 제기치 않으면 제반 법적 효력을 발휘한다.</li>
        <li>상기 조항에 명시되지 아니한 사항은 상호 협의하고, 협의가 불가능할 경우에는 당사의 해석에 따른다.</li>
      </ol>

      <p className="mt-4 font-semibold text-[12px]">3. 비고</p>
      {editable ? (
        <textarea
          defaultValue={detail.proc.MEMO ?? ""}
          onBlur={(e) => onSetMemo(e.target.value)}
          rows={2}
          placeholder="추가로 전달할 사항이 있으면 입력"
          className="w-full mt-1 px-3 py-2 rounded border border-slate-300 text-[11px] resize-y"
        />
      ) : (
        <div className="mt-1 px-3 py-2 rounded border border-slate-200 bg-slate-50 text-[11px] whitespace-pre-wrap min-h-[40px]">
          {detail.proc.MEMO || <span className="text-slate-400">없음</span>}
        </div>
      )}

      <div className="mt-6 text-center text-[11px] text-slate-600">
        <p>상기와 같이 발주함.</p>
        <p className="mt-2">{detail.proc.PROC_DATE.replace(/-/g, ".") + "."}</p>
        <p className="mt-3 font-semibold">발주자 : {process.env.NEXT_PUBLIC_MOMO_NAME ?? "(주)모모유통"}</p>
      </div>
      </div>{/* /formRef capture area */}
    </div>
  );
}

function ProcLineRow({ line, idx, editable, onSave, onDelete }: {
  line: ProcLine; idx: number; editable: boolean;
  onSave: (qty: number, cost: number) => void;
  onDelete: () => void;
}) {
  const [qty, setQty] = useState(Number(line.QTY));
  const [cost, setCost] = useState(Number(line.COST_PRICE));
  useEffect(() => { setQty(Number(line.QTY)); setCost(Number(line.COST_PRICE)); }, [line.OBJID, line.QTY, line.COST_PRICE]);
  const total = Math.round(qty * cost);
  const dirty = qty !== Number(line.QTY) || cost !== Number(line.COST_PRICE);
  return (
    <tr className="bg-white">
      <td className="border border-slate-400 px-1 py-1 text-center">{idx}</td>
      <td className="border border-slate-400 px-2 py-1">{line.ITEM_NAME}</td>
      <td className="border border-slate-400 px-1 py-1 text-center">{line.UNIT ?? "EA"}</td>
      <td className="border border-slate-400 px-1 py-1">
        {editable ? (
          <input type="number" min={1} value={qty}
            onChange={(e) => setQty(Number(e.target.value))}
            onBlur={() => { if (dirty) onSave(qty, cost); }}
            className="w-full h-6 px-1 border border-slate-200 rounded text-[11px] text-right tabular-nums bg-white" />
        ) : <div className="text-right">{fmt(qty)}</div>}
      </td>
      <td className="border border-slate-400 px-1 py-1">
        {editable ? (
          <input type="number" min={0} value={cost}
            onChange={(e) => setCost(Number(e.target.value))}
            onBlur={() => { if (dirty) onSave(qty, cost); }}
            className="w-full h-6 px-1 border border-slate-200 rounded text-[11px] text-right tabular-nums bg-white" />
        ) : <div className="text-right">{fmt(cost)}</div>}
      </td>
      <td className="border border-slate-400 px-1 py-1 text-right font-semibold">{fmt(total)}</td>
      {editable && (
        <td className="border border-slate-400 px-1 py-1 text-center">
          <button onClick={onDelete} className="text-rose-500 hover:text-rose-700"><X size={12} /></button>
        </td>
      )}
    </tr>
  );
}

function ItemPicker({ vendorObjid, existingItemIds, onClose, onAddItems }: {
  vendorObjid: string | null;
  existingItemIds: Set<string>;
  onClose: () => void;
  onAddItems: (items: Item[]) => void;
}) {
  const [items, setItems] = useState<Item[]>([]);
  const [keyword, setKeyword] = useState("");
  const [innerKeyword, setInnerKeyword] = useState("");
  const [loading, setLoading] = useState(false);
  const [selected, setSelected] = useState<Set<string>>(new Set());
  const [filterVendor, setFilterVendor] = useState(vendorObjid || "");

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const body: Record<string, unknown> = { keyword: keyword || undefined };
      if (filterVendor) body.vendorObjid = filterVendor;
      const res = await fetch("/api/m/items/list", {
        method: "POST", headers: { "Content-Type": "application/json" },
        body: JSON.stringify(body),
      });
      setItems((await res.json()).RESULTLIST ?? []);
      setSelected(new Set());
    } finally { setLoading(false); }
  }, [keyword, filterVendor]);
  useEffect(() => { load(); }, [load]);

  const filtered = innerKeyword
    ? items.filter((it) => it.ITEM_NAME.includes(innerKeyword) || it.ITEM_CODE.includes(innerKeyword))
    : items;

  const toggle = (id: string) => {
    setSelected((p) => {
      const n = new Set(p);
      if (n.has(id)) n.delete(id); else n.add(id);
      return n;
    });
  };
  const toggleAll = () => {
    setSelected((p) => {
      const allOn = filtered.length > 0 && filtered.every((it) => p.has(it.OBJID));
      const n = new Set(p);
      if (allOn) filtered.forEach((it) => n.delete(it.OBJID));
      else filtered.forEach((it) => n.add(it.OBJID));
      return n;
    });
  };

  return (
    <div className="fixed inset-0 bg-slate-900/60 z-50 flex items-end sm:items-center justify-center p-0 sm:p-3" onClick={onClose}>
      <div className="bg-white rounded-t-xl sm:rounded-xl shadow-xl max-w-3xl w-full max-h-[90vh] flex flex-col" onClick={(e) => e.stopPropagation()}>
        <div className="px-4 py-3 border-b flex items-center justify-between sticky top-0 bg-white z-10">
          <h3 className="font-bold">품목 추가 ({filtered.length}개)</h3>
          <button onClick={onClose} className="text-slate-400 hover:text-slate-700"><X size={18} /></button>
        </div>
        <div className="px-4 py-3 border-b space-y-2 bg-slate-50">
          <div className="flex gap-2 flex-wrap">
            <input value={keyword} onChange={(e) => setKeyword(e.target.value)}
              onKeyDown={(e) => e.key === "Enter" && load()}
              placeholder="품목명/코드"
              className="flex-1 min-w-[160px] h-9 px-3 rounded border border-slate-300 text-sm" />
            <button onClick={load} className="h-9 px-3 rounded bg-slate-800 text-white text-sm font-semibold inline-flex items-center gap-1">
              <Search size={14} /> 검색
            </button>
          </div>
          <div className="flex gap-2 items-center text-xs flex-wrap">
            <span className="text-slate-500">공급업체 필터</span>
            <button onClick={() => setFilterVendor("")}
              className={`px-2 py-1 rounded ${!filterVendor ? "bg-emerald-700 text-white" : "bg-white border border-slate-300"}`}>전체</button>
            {vendorObjid && (
              <button onClick={() => setFilterVendor(vendorObjid)}
                className={`px-2 py-1 rounded ${filterVendor === vendorObjid ? "bg-emerald-700 text-white" : "bg-white border border-slate-300"}`}>
                현재 발주서 공급업체만
              </button>
            )}
          </div>
          <div className="flex gap-2 items-center text-xs">
            <span className="text-slate-500">결과 내 검색</span>
            <input value={innerKeyword} onChange={(e) => setInnerKeyword(e.target.value)}
              placeholder="결과를 더 좁힐 글자 입력"
              className="flex-1 h-8 px-2 rounded border border-slate-300 text-xs" />
            {innerKeyword && (
              <button onClick={() => setInnerKeyword("")} className="text-slate-400 hover:text-slate-700">
                <X size={12} />
              </button>
            )}
          </div>
        </div>
        <div className="flex-1 overflow-auto">
          <table className="w-full text-xs">
            <thead className="bg-slate-50 sticky top-0">
              <tr>
                <th className="px-2 py-2 w-10">
                  <input
                    type="checkbox"
                    onChange={toggleAll}
                    checked={filtered.length > 0 && filtered.every((it) => selected.has(it.OBJID))}
                    style={{ cursor: "pointer", width: 18, height: 18 }}
                    className="accent-emerald-600"
                  />
                </th>
                <th className="text-left px-2 py-2">품목명</th>
                <th className="text-left px-2 py-2">공급업체</th>
                <th className="text-right px-2 py-2">원가</th>
                <th className="text-center px-2 py-2 w-14">담김?</th>
              </tr>
            </thead>
            <tbody>
              {loading ? (
                <tr><td colSpan={5} className="text-center py-8 text-slate-400">불러오는 중...</td></tr>
              ) : filtered.length === 0 ? (
                <tr><td colSpan={5} className="text-center py-8 text-slate-400">결과가 없습니다.</td></tr>
              ) : filtered.map((it) => (
                <tr key={it.OBJID}
                    onClick={() => toggle(it.OBJID)}
                    style={{ cursor: "pointer" }}
                    className={`border-t border-slate-100 select-none ${selected.has(it.OBJID) ? "bg-emerald-50" : "hover:bg-slate-50"}`}>
                  <td className="px-2 py-1.5 text-center" onClick={(e) => e.stopPropagation()}>
                    <input
                      type="checkbox"
                      checked={selected.has(it.OBJID)}
                      onChange={() => toggle(it.OBJID)}
                      style={{ cursor: "pointer", width: 18, height: 18 }}
                      className="accent-emerald-600"
                    />
                  </td>
                  <td className="px-2 py-1.5">
                    <div className="font-semibold">{it.ITEM_NAME}</div>
                    <div className="text-slate-400 text-[10px]">{it.ITEM_CODE}</div>
                  </td>
                  <td className="px-2 py-1.5 text-slate-600">{it.VENDOR_NAME ?? "-"}</td>
                  <td className="px-2 py-1.5 text-right tabular-nums">{fmt(it.COST_PRICE)}</td>
                  <td className="px-2 py-1.5 text-center">
                    {existingItemIds.has(it.OBJID) ? <span className="text-[10px] text-amber-600">이미</span> : <span className="text-slate-300">-</span>}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
        <div className="px-4 py-3 border-t flex justify-between items-center">
          <span className="text-xs text-slate-500">선택 {selected.size}개</span>
          <div className="flex gap-2">
            <button onClick={onClose} className="px-3 h-9 rounded border border-slate-300 text-sm">닫기</button>
            <button
              disabled={selected.size === 0}
              onClick={() => onAddItems(filtered.filter((it) => selected.has(it.OBJID)))}
              className="px-4 h-9 rounded bg-emerald-700 text-white text-sm font-bold disabled:opacity-50 hover:bg-emerald-800">
              선택한 {selected.size}개 추가
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}
