"use client";

// ============================================================
// 영업관리 > 견적관리 > 견적작성(일반)
// wace estimateTemplate1.jsp 1:1 이식 (template_type='1')
// 진입: 견적관리 그리드 행 선택 → "견적작성" → "일반 견적서"
// ============================================================

import React, { useEffect, useMemo, useRef, useState } from "react";
import { useParams, useSearchParams, useRouter } from "next/navigation";
import { salesEstimateApi, EstimateTemplateItemRow } from "@/lib/api/salesEstimate";
import { CustomerSelect, fetchCustomers } from "@/components/common/CustomerSelect";
import { useAuth } from "@/hooks/useAuth";

// ─── 포맷 헬퍼 (wace addComma / getCurrencySymbol 1:1) ────────
function addComma(num: number | string): string {
  if (num === "" || num == null) return "";
  const n = Number(String(num).replace(/,/g, ""));
  if (Number.isNaN(n)) return "";
  return n.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
}

function getCurrencySymbol(currencyName: string): string {
  const c = currencyName ?? "";
  if (c.indexOf("달러") >= 0 || c === "USD") return "$";
  if (c.indexOf("유로") >= 0 || c === "EUR") return "€";
  if (c.indexOf("엔") >= 0 || c === "JPY") return "¥";
  if (c.indexOf("위안") >= 0 || c === "CNY") return "¥";
  return "₩";
}

// 단가 입력 시 실시간 콤마 처리 (wace input 이벤트 1:1)
function formatPriceInput(raw: string): string {
  const cleaned = raw.replace(/,/g, "").replace(/[^0-9.]/g, "");
  if (cleaned === "") return "";
  return addComma(cleaned);
}

// 라인 1행 상태
interface ItemRow {
  rowId: string;        // React key 용 클라이언트 ID
  partObjid: string;
  description: string;  // 품명 (readonly)
  specification: string;
  quantity: string;     // 숫자만 (콤마 없음)
  unit: string;
  unitPrice: string;    // 표시용 (콤마 포함)
  amount: string;       // 표시용 (통화기호 + 콤마)
  note: string;
}

function emptyRow(): ItemRow {
  return {
    rowId: `r_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
    partObjid: "",
    description: "",
    specification: "",
    quantity: "",
    unit: "EA",
    unitPrice: "",
    amount: "",
    note: "",
  };
}

// ─── 페이지 ──────────────────────────────────────────────────
export default function EstimateTemplate1Page() {
  const params = useParams<{ contractObjid: string }>();
  const searchParams = useSearchParams();
  const router = useRouter();
  const { user } = useAuth();

  const contractObjidParam = params?.contractObjid ?? "";
  const templateObjidParam = searchParams?.get("templateObjid") ?? "";

  // 환율/통화 (영업 정보에서 로드)
  const [exchangeRate, setExchangeRate] = useState<number>(1);
  const [currencyName, setCurrencyName] = useState<string>("KRW");
  const currencySymbol = getCurrencySymbol(currencyName);

  // 헤더 필드
  const [executor, setExecutor] = useState<string>("");           // 시행일자 (YYYY-MM-DD)
  const executorDateRef = useRef<HTMLInputElement>(null);
  const [recipient, setRecipient] = useState<string>("");         // 수신처 (customer_objid)
  const [estimateNo, setEstimateNo] = useState<string>("");
  const [contactPerson, setContactPerson] = useState<string>("");
  const [greetingText, setGreetingText] = useState<string>(
    "견적을 요청해 주셔서 대단히 감사합니다.\n하기와 같이 견적서를 제출합니다.",
  );
  const [managerName, setManagerName] = useState<string>("");
  const [managerContact, setManagerContact] = useState<string>("");
  const [noteRemarks, setNoteRemarks] = useState<string>("");
  const [note1, setNote1] = useState<string>("1. 견적유효기간: 일");
  const [note2, setNote2] = useState<string>("2. 납품기간: 발주 후 1주 이내");
  const [note3, setNote3] = useState<string>("3. VAT 별도");
  const [note4, setNote4] = useState<string>("4. 결제 조건 : 기존 결제조건에 따름.");
  const [showTotalRow, setShowTotalRow] = useState<boolean>(true);

  // 결재상태 (운영 amaranth_approval 없으면 '작성중'으로 폴백)
  const [apprStatus, setApprStatus] = useState<string>("작성중");
  const readOnly = apprStatus === "결재완료" || apprStatus === "결재중";

  // 라인
  const [items, setItems] = useState<ItemRow[]>([emptyRow(), emptyRow()]);

  // 수정 모드용 templateObjid (저장 후 갱신)
  const [templateObjid, setTemplateObjid] = useState<string>(templateObjidParam);

  // 데이터 로드 완료 플래그
  const [loading, setLoading] = useState<boolean>(true);
  const [contractObjid, setContractObjid] = useState<string>(contractObjidParam);

  // ─── 합계 계산 (items 또는 환율 변경 시) ──────────────────────
  const { totalAmountNum, totalAmountKrwNum } = useMemo(() => {
    const total = items.reduce((sum, r) => {
      const a = parseFloat((r.amount ?? "").replace(/[^0-9.]/g, "")) || 0;
      return sum + a;
    }, 0);
    return { totalAmountNum: total, totalAmountKrwNum: total * (exchangeRate || 1) };
  }, [items, exchangeRate]);
  const totalAmountStr = `${currencySymbol}${addComma(totalAmountNum)}`;
  const totalAmountKrwStr = `₩${addComma(totalAmountKrwNum)}`;

  // ─── 라인 수정 핸들러 ─────────────────────────────────────────
  function updateItem(idx: number, patch: Partial<ItemRow>) {
    setItems(prev => {
      const next = [...prev];
      const cur = { ...next[idx], ...patch };
      // 수량/단가 변경 시 금액 자동 계산 (wace fn_calculateAmount)
      if (patch.quantity != null || patch.unitPrice != null) {
        const qty = parseFloat((cur.quantity ?? "").replace(/,/g, "")) || 0;
        const price = parseFloat((cur.unitPrice ?? "").replace(/,/g, "")) || 0;
        const amt = qty * price;
        cur.amount = Number.isFinite(amt) && amt !== 0 ? `${currencySymbol}${addComma(amt)}` : "";
      }
      next[idx] = cur;
      return next;
    });
  }

  function addItemRow() {
    setItems(prev => [...prev, emptyRow()]);
  }

  function removeItemRow(idx: number) {
    setItems(prev => prev.filter((_, i) => i !== idx));
  }

  // ─── 데이터 로드 ────────────────────────────────────────────
  useEffect(() => {
    let cancel = false;

    (async () => {
      try {
        // 1) 영업 정보 로드 (헤더의 customer_objid, 통화, 환율, contract_item 라인)
        let contractInfo: any = null;
        if (contractObjidParam) {
          try {
            contractInfo = await salesEstimateApi.detail(contractObjidParam);
          } catch (e) {
            console.warn("영업정보 로드 실패", e);
          }
        }

        // getById 응답: { ...contract_mgmt 헤더 필드들, items: [...] } (평면 구조)
        if (contractInfo && !cancel) {
          setExchangeRate(parseFloat(contractInfo.exchange_rate || "1") || 1);
          setCurrencyName(contractInfo.contract_currency_name || contractInfo.contract_currency || "KRW");
          // 수신처는 customer_objid (예: 'C_RPS001') — 견적요청의 고객사를 견적서에 자동 채움
          if (contractInfo.customer_objid) setRecipient(contractInfo.customer_objid);
        }

        // 2) 기존 견적 차수 수정 (templateObjid 지정) — 우선
        if (templateObjidParam) {
          const tpl = await salesEstimateApi.getTemplate(templateObjidParam);
          if (tpl && !cancel) {
            if (tpl.contract_objid) setContractObjid(tpl.contract_objid);
            setExchangeRate(parseFloat(tpl.exchange_rate || "1") || 1);
            setCurrencyName(tpl.contract_currency_name || tpl.contract_currency || "KRW");
            setExecutor(tpl.executor ?? "");
            if (tpl.recipient) setRecipient(tpl.recipient);
            setEstimateNo(tpl.estimate_no ?? "");
            setContactPerson(tpl.contact_person ?? "");
            if (tpl.greeting_text) setGreetingText(tpl.greeting_text);
            if (tpl.manager_name) setManagerName(tpl.manager_name);
            if (tpl.manager_contact) setManagerContact(tpl.manager_contact);
            setNoteRemarks(tpl.note_remarks ?? "");
            if (tpl.note1) setNote1(tpl.note1);
            if (tpl.note2) setNote2(tpl.note2);
            if (tpl.note3) setNote3(tpl.note3);
            if (tpl.note4) setNote4(tpl.note4);
            setShowTotalRow((tpl.show_total_row ?? "Y") !== "N");

            const loaded: ItemRow[] = (tpl.items ?? []).map(it => ({
              rowId: `t_${(it as any).objid ?? Math.random().toString(36).slice(2, 8)}`,
              partObjid: it.part_objid ?? "",
              description: it.description ?? "",
              specification: it.specification ?? "",
              quantity: (it.quantity ?? "").toString(),
              unit: it.unit ?? "EA",
              unitPrice: it.unit_price ? addComma(it.unit_price) : "",
              amount: it.amount
                ? `${getCurrencySymbol(tpl.contract_currency_name || tpl.contract_currency || "KRW")}${addComma(it.amount)}`
                : "",
              note: it.note ?? "",
            }));
            if (loaded.length > 0) setItems(loaded);
          }
        } else if (contractInfo?.items?.length) {
          // 3) 신규 작성: 영업정보의 contract_item 품목을 기본 라인으로 깔아줌 (wace fn_loadContractItems)
          const loaded: ItemRow[] = contractInfo.items.map((it: any) => ({
            rowId: `c_${it.objid ?? Math.random().toString(36).slice(2, 8)}`,
            partObjid: it.part_objid ?? "",
            description: it.master_part_name ?? it.part_name ?? "",
            specification: "",
            quantity: (it.quantity ?? "").toString(),
            unit: "EA",
            unitPrice: "",
            amount: "",
            note: "",
          }));
          if (!cancel && loaded.length > 0) setItems(loaded);
        }

        // 4) 로그인 사용자 정보 — 담당자 이름/연락처 자동 채움 (기존 값 없을 때만)
        // (백엔드에 별도 user 조회 API가 있으면 사용; 일단 비워두고 수동 입력 허용)

        // 5) 수신처 CustomerSelect 옵션 미리 로드 — PDF 캡처 시 selectedLabel이 비어있는 현상 방지
        // (hidden iframe 메일 발송 흐름에서 dataLoaded 트리거 시점에 옵션 fetch가 안 끝나면 빈 셀렉트로 잡힘)
        try { await fetchCustomers(); } catch {}
      } finally {
        if (!cancel) setLoading(false);
      }
    })();

    return () => { cancel = true; };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [contractObjidParam, templateObjidParam]);

  // 로그인 사용자 정보로 담당자/연락처 자동 채움 (wace estimateTemplate1.jsp:321-322)
  // — 신규 작성 시에만, 그리고 사용자가 아직 직접 입력하지 않은 경우(빈값)에만 채움
  useEffect(() => {
    if (!user) return;
    if (templateObjidParam) return;  // 기존 견적서 수정 모드는 건드리지 않음
    setManagerName(prev => prev || `${user.deptName ?? ""} ${user.userName ?? ""}`.trim());
    // wace MailUtil 패턴: cell_phone 우선, 없으면 tel
    setManagerContact(prev => prev || user.cellPhone || user.tel || "");
  }, [user, templateObjidParam]);

  // ─── 저장 (wace fn_save 1:1) ─────────────────────────────────
  async function handleSave() {
    if (!contractObjid) {
      alert("견적서를 저장할 수 없습니다. 영업정보가 없습니다.");
      return;
    }
    if (!confirm("견적서를 저장하시겠습니까?")) return;

    // 라인 → 페이로드 (콤마/통화기호 제거)
    const itemsBody: EstimateTemplateItemRow[] = items.map((r, idx) => ({
      seq: idx + 1,
      part_objid: r.partObjid || null,
      description: r.description || "",
      specification: r.specification || "",
      quantity: (r.quantity || "").replace(/[^0-9]/g, ""),
      unit: r.unit || "",
      unit_price: (r.unitPrice || "").replace(/[^0-9.]/g, ""),
      amount: (r.amount || "").replace(/[^0-9.]/g, ""),
      note: r.note || "",
    }));

    try {
      const data = await salesEstimateApi.saveTemplate1({
        contract_objid: contractObjid,
        template_objid: templateObjid || undefined,
        executor,
        recipient,
        estimate_no: estimateNo,
        contact_person: contactPerson,
        greeting_text: greetingText,
        manager_name: managerName,
        manager_contact: managerContact,
        note_remarks: noteRemarks,
        note1, note2, note3, note4,
        show_total_row: showTotalRow ? "Y" : "N",
        total_amount: String(totalAmountNum),
        total_amount_krw: String(totalAmountKrwNum),
        items: itemsBody,
      });
      // 저장 성공 → templateObjid 동기화 (수정 모드 유지)
      if (data?.templateObjid) setTemplateObjid(data.templateObjid);
      alert("저장되었습니다.");
      // opener 새로고침 — wace는 window.opener.fn_search() 호출. RPS는 새 탭/창이라 별도 처리 없음.
    } catch (e: any) {
      console.error("저장 오류", e);
      alert("저장에 실패했습니다.\n" + (e?.response?.data?.message ?? e?.message ?? ""));
    }
  }

  function handlePrint() {
    window.print();
  }

  // ─── 견적서 PDF 생성 (공용) — wace fn_generatePdf 1:1 ─────────────
  // 다운로드/메일발송 모두 같은 캡처 로직 사용. 반환값은 jsPDF 인스턴스.
  async function generatePdfDocument(): Promise<any> {
    const html2canvas = (await import("html2canvas-pro")).default;
    const { jsPDF } = await import("jspdf");

    const container = document.querySelector(".estimate-container") as HTMLElement | null;
    if (!container) throw new Error("견적서 컨테이너(.estimate-container)를 찾을 수 없습니다.");

    const canvas = await html2canvas(container, {
      scale: 2,
      useCORS: true,
      logging: false,
      backgroundColor: "#ffffff",
      // 클론된 DOM에서 input/textarea/select → 텍스트 노드로 교체 (글자 잘림 방지)
      onclone: (doc) => {
        const replaceWithText = (el: HTMLElement, text: string) => {
          const span = doc.createElement("span");
          span.textContent = text;
          const style = el.getAttribute("style") || "";
          span.setAttribute("style", style + ";display:inline-block;white-space:pre-wrap;");
          el.parentNode?.replaceChild(span, el);
        };
        doc.querySelectorAll<HTMLInputElement>('input[type="text"],input[type="date"]').forEach(el => replaceWithText(el, el.value || ""));
        doc.querySelectorAll<HTMLTextAreaElement>("textarea").forEach(el => replaceWithText(el, el.value || ""));
        doc.querySelectorAll<HTMLSelectElement>("select").forEach(el => {
          const opt = el.options[el.selectedIndex];
          replaceWithText(el as unknown as HTMLElement, opt?.text || "");
        });
        // SmartSelect/CustomerSelect (role="combobox") → 선택된 라벨만 텍스트로
        // (button 안 span.truncate가 selectedLabel — 옵션 fetch 미완 등 엣지케이스에서 텍스트가 비어 캡처 누락되는 현상 방지)
        doc.querySelectorAll<HTMLElement>('[role="combobox"]').forEach((el) => {
          const labelSpan = el.querySelector(".truncate");
          // 실제 렌더 텍스트는 라이브 DOM에서 가져오기 (clone된 doc에서는 빈 경우 있음)
          const liveBtn = document.querySelectorAll<HTMLElement>('[role="combobox"]');
          let text = (labelSpan?.textContent ?? "").trim();
          if (text === "" || /^거래처\s*선택$|^고객사\s*선택$|^선택$/i.test(text)) {
            // placeholder만 잡혔으면 빈 문자열로
            const idx = Array.from(doc.querySelectorAll('[role="combobox"]')).indexOf(el);
            const live = liveBtn[idx];
            const liveLabel = live?.querySelector(".truncate")?.textContent?.trim() ?? "";
            text = /^거래처\s*선택$|^고객사\s*선택$|^선택$/i.test(liveLabel) ? "" : liveLabel;
          }
          replaceWithText(el, text);
        });
        // 인쇄 비대상 요소 숨김
        doc.querySelectorAll<HTMLElement>(".no-print, .btn-area, .delete-btn-cell button").forEach(el => { el.style.display = "none"; });
      },
    });

    const imgData = canvas.toDataURL("image/jpeg", 0.85);
    const pdf = new jsPDF("p", "mm", "a4");
    const imgWidth = 210, pageHeight = 297;
    const imgHeight = canvas.height * imgWidth / canvas.width;
    let heightLeft = imgHeight;
    let position = 0;

    pdf.addImage(imgData, "JPEG", 0, position, imgWidth, imgHeight, undefined, "FAST");
    heightLeft -= pageHeight;
    while (heightLeft > 1) {
      position = heightLeft - imgHeight;
      pdf.addPage();
      pdf.addImage(imgData, "JPEG", 0, position, imgWidth, imgHeight, undefined, "FAST");
      heightLeft -= pageHeight;
    }
    return pdf;
  }

  // PDF 다운로드 — wace fn_generatePdf 1:1
  async function handleDownloadPdf() {
    if (!confirm("PDF로 다운로드 하시겠습니까?")) return;
    try {
      const pdf = await generatePdfDocument();
      const fileName = (estimateNo || "견적서") + ".pdf";
      pdf.save(fileName);
    } catch (e: any) {
      console.error("PDF 생성 오류", e);
      alert("PDF 생성 중 오류가 발생했습니다.\n" + (e?.message ?? ""));
    }
  }

  // ─── 부모 창의 메일 다이얼로그용 글로벌 노출 ──────────────────────────
  // wace estimateMailFormPopup.jsp가 hidden iframe으로 이 페이지를 열고
  // iframe.contentWindow.fn_generateAndUploadPdf(cb)를 호출한다.
  // 데이터 로딩 완료 후 dataLoaded=true 세팅 → 부모가 폴링으로 감지.
  useEffect(() => {
    if (loading) return;
    if (typeof window === "undefined") return;
    const w = window as any;
    w.dataLoaded = true;
    w.fn_generateAndUploadPdf = async (callback: (pdfBase64: string) => void) => {
      try {
        const pdf = await generatePdfDocument();
        // jsPDF.output('datauristring') → data:application/pdf;base64,...
        const dataUri: string = pdf.output("datauristring");
        callback(dataUri);
      } catch (e) {
        console.error("fn_generateAndUploadPdf error", e);
        callback("");
      }
    };
    return () => {
      try {
        w.dataLoaded = false;
        delete w.fn_generateAndUploadPdf;
      } catch {}
    };
  }, [loading]);

  function handleClose() {
    // 새 탭으로 열린 경우 닫기 시도 + 안되면 router back
    if (window.opener) {
      window.close();
    } else {
      router.back();
    }
  }

  if (loading) return <div style={{ padding: 40 }}>견적서를 불러오는 중...</div>;

  // ─── 렌더링 (wace 마크업 1:1) ────────────────────────────────
  return (
    <div className="estimate-page">
      <style jsx global>{`
        @media print {
          @page { size: A4; margin: 10mm; }
          body { margin: 0; padding: 0; }
          .no-print { display: none !important; }
          .delete-btn-cell button { display: none !important; }
        }
        body {
          font-family: "Malgun Gothic", "맑은 고딕", Arial, sans-serif;
          font-size: 12pt;
          background-color: #f5f5f5;
        }
        /* 견적서는 인쇄용 양식 — 다크모드와 무관하게 항상 흰 배경/검정 텍스트 */
        html.dark .estimate-page, html[data-theme="dark"] .estimate-page,
        .estimate-page { color: #000; background-color: #f5f5f5; min-height: 100vh; }
        .estimate-page .estimate-container,
        .estimate-page .estimate-container * { color: #000; }
        .estimate-container {
          width: 210mm;
          min-height: 297mm;
          background: white;
          margin: 0 auto;
          padding: 20mm;
          box-shadow: 0 0 10px rgba(0,0,0,0.1);
          box-sizing: border-box;
        }
        .estimate-title {
          text-align: center;
          font-size: 28pt;
          font-weight: bold;
          letter-spacing: 20px;
          margin-bottom: 40px;
          padding: 10px 0;
        }
        .info-table {
          width: 100%;
          border-collapse: collapse;
          margin-bottom: 30px;
        }
        .info-table td { padding: 5px 8px; border: 1px solid #000; font-size: 9pt; }
        .info-table .label { background-color: #f0f0f0; font-weight: bold; width: 80px; text-align: center; }
        .items-table {
          width: 100%;
          border-collapse: collapse;
          margin-bottom: 30px;
          table-layout: fixed;
        }
        .items-table th, .items-table td {
          border: 1px solid #000;
          padding: 8px 2px;
          text-align: center;
          vertical-align: middle;
          font-size: 9pt;
          line-height: 1.3;
        }
        .items-table th { background-color: #f0f0f0; font-weight: bold; }
        .items-table .col-no { width: 4%; }
        .items-table .col-desc { width: 12%; }
        .items-table .col-spec { width: 22%; }
        .items-table .col-qty { width: 4%; }
        .items-table .col-unit { width: 5%; }
        .items-table .col-price { width: 14%; }
        .items-table .col-amount { width: 15%; }
        .items-table .col-note { width: 9%; white-space: normal; word-break: break-all; }
        .items-table td { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
        .items-table .text-left { text-align: left; }
        .items-table .text-right { text-align: right; overflow: hidden; }
        .estimate-page input[type="text"],
        .estimate-page input[type="date"],
        .estimate-page textarea,
        .estimate-page select {
          border: none;
          outline: none;
          background: transparent;
          width: 100%;
          font-family: inherit;
          font-size: inherit;
          box-sizing: border-box;
          color: #000;
        }
        .estimate-page input[readonly], .estimate-page textarea[readonly] { color: #000; }
        .estimate-page textarea {
          resize: none;
          height: 1.3em;
          min-height: auto;
          padding: 0 2px;
          white-space: nowrap;
          overflow: hidden;
        }
        .estimate-page .item-price, .estimate-page .item-amount { text-align: right; }
        .estimate-page .item-amount { pointer-events: none; }
        .btn-area {
          position: fixed; bottom: 0; left: 0; right: 0;
          text-align: right;
          padding: 15px 30px;
          background-color: #ffffff;
          border-top: 3px solid #007bff;
          box-shadow: 0 -2px 10px rgba(0,0,0,0.1);
          z-index: 1000;
        }
        .estimate-btn {
          display: inline-block;
          padding: 5px 15px;
          margin: 0 2px;
          font-size: 12px;
          cursor: pointer;
          border: 1px solid #60a5fa;
          background-color: #60a5fa;
          color: white;
          border-radius: 3px;
          line-height: 1;
          white-space: nowrap;
        }
        .estimate-btn:hover { background-color: #1e3a8a; border-color: #1e3a8a; }
        .estimate-btn[disabled] { background-color: #cbd5e1; border-color: #cbd5e1; cursor: not-allowed; }
        .company-stamp-placeholder {
          width: 100%; min-height: 200px;
          display: flex; align-items: center; justify-content: center;
          border: 1px dashed #ccc; color: #666; font-size: 9pt;
        }
        .editable-input { background-color: transparent; }
        .readonly-input { background-color: #f5f5f5; }
      `}</style>

      <div className="estimate-container" style={{ paddingBottom: 100 }}>
        {/* 제목 */}
        <div className="estimate-title">견&nbsp;&nbsp;적&nbsp;&nbsp;서</div>

        {/* 상단 정보 테이블 */}
        <table className="info-table">
          <colgroup>
            <col width="80px" />
            <col width="*" />
            <col width="50px" />
            <col width="300px" />
          </colgroup>
          <tbody>
            <tr>
              <td className="label">시행일자</td>
              <td>
                {/* 표시는 YYYY-MM-DD (text), 클릭 시 숨겨진 type=date의 showPicker 트리거 */}
                <div style={{ position: "relative", display: "inline-block", width: 150 }}>
                  <input
                    type="text"
                    value={executor}
                    readOnly
                    placeholder="YYYY-MM-DD"
                    onClick={() => { if (!readOnly) executorDateRef.current?.showPicker?.(); }}
                    style={{ width: "100%", cursor: readOnly ? "default" : "pointer" }}
                  />
                  <input
                    ref={executorDateRef}
                    type="date"
                    value={executor}
                    onChange={e => setExecutor(e.target.value)}
                    tabIndex={-1}
                    aria-hidden="true"
                    style={{ position: "absolute", left: 0, top: 0, width: 1, height: 1, opacity: 0, pointerEvents: "none" }}
                  />
                </div>
              </td>
              <td rowSpan={4} style={{ border: "none" }}></td>
              <td rowSpan={4} style={{ textAlign: "center", border: "none", verticalAlign: "middle", padding: 0 }}>
                <div style={{ width: "100%", textAlign: "center", marginBottom: 5 }}>
                  <img
                    src="/images/company_stamp.png"
                    alt="회사 도장"
                    style={{ width: "100%", height: "auto" }}
                    onError={(e) => {
                      const img = e.currentTarget;
                      img.style.display = "none";
                      const fb = img.nextElementSibling as HTMLElement | null;
                      if (fb) fb.style.display = "flex";
                    }}
                  />
                  <div className="company-stamp-placeholder" style={{ display: "none" }}>
                    ㈜알피에스<br />RPS CO., LTD<br />대표이사 이동준
                  </div>
                </div>
              </td>
            </tr>
            <tr>
              <td className="label">수신처</td>
              <td>
                <CustomerSelect
                  value={recipient}
                  onValueChange={setRecipient}
                  placeholder="고객사 선택"
                  disabled={readOnly}
                />
              </td>
            </tr>
            <tr>
              <td className="label">수신인</td>
              <td>
                <input
                  type="text"
                  value={contactPerson}
                  onChange={e => setContactPerson(e.target.value)}
                  readOnly={readOnly}
                  placeholder="OO 귀하"
                />
              </td>
            </tr>
            <tr>
              <td className="label">견적번호</td>
              <td>
                <input
                  type="text"
                  value={estimateNo}
                  onChange={e => setEstimateNo(e.target.value)}
                  readOnly={readOnly}
                />
              </td>
            </tr>
          </tbody>
        </table>

        {/* 인사말 + 담당자 + 부가세 별도 */}
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 10, padding: "0 5px" }}>
          <div style={{ lineHeight: 1.6, fontSize: "10pt", whiteSpace: "pre-line" }}>
            {greetingText}
          </div>
          <div style={{ textAlign: "right", fontSize: "9pt", lineHeight: 1.8 }}>
            담당자 :{" "}
            <input
              type="text"
              value={managerName}
              onChange={e => setManagerName(e.target.value)}
              readOnly={readOnly}
              style={{ width: 120, borderBottom: "1px solid #ddd", fontSize: "9pt", padding: 2, backgroundColor: "#f5f5f5" }}
            /><br/>
            연락처 :{" "}
            <input
              type="text"
              value={managerContact}
              onChange={e => setManagerContact(e.target.value)}
              readOnly={readOnly}
              style={{ width: 120, borderBottom: "1px solid #ddd", fontSize: "9pt", padding: 2, backgroundColor: "#f5f5f5" }}
            /><br/><br/>
            <span style={{ fontSize: "10pt", marginTop: 5, display: "inline-block" }}>부가세 별도</span>
          </div>
        </div>

        {/* 품목 테이블 */}
        <table className="items-table">
          <thead>
            <tr>
              <th className="col-no">번호<br/>NO.</th>
              <th className="col-desc">품　명<br/>DESCRIPTION</th>
              <th className="col-spec">규　격<br/>SPECIFICATION</th>
              <th className="col-qty">수량<br/>Q'TY</th>
              <th className="col-unit">단위<br/>UNIT</th>
              <th className="col-price">단　가<br/>UNIT PRICE</th>
              <th className="col-amount">금　액<br/>AMOUNT</th>
              <th className="col-note">비고</th>
            </tr>
          </thead>
          <tbody>
            {items.map((r, idx) => (
              <tr key={r.rowId}>
                <td>{idx + 1}</td>
                <td className="text-left">
                  <input type="text" value={r.description} readOnly className="readonly-input" />
                </td>
                <td className="text-left">
                  <textarea
                    value={r.specification}
                    onChange={e => updateItem(idx, { specification: e.target.value })}
                    readOnly={readOnly}
                  />
                </td>
                <td>
                  <input
                    type="text"
                    value={r.quantity}
                    onChange={e => updateItem(idx, { quantity: e.target.value.replace(/[^0-9]/g, "") })}
                    readOnly={readOnly}
                  />
                </td>
                <td>
                  <input
                    type="text"
                    value={r.unit}
                    onChange={e => updateItem(idx, { unit: e.target.value })}
                    readOnly={readOnly}
                  />
                </td>
                <td className="text-right">
                  <input
                    type="text"
                    value={r.unitPrice}
                    onChange={e => updateItem(idx, { unitPrice: formatPriceInput(e.target.value) })}
                    readOnly={readOnly}
                  />
                </td>
                <td className="text-right">
                  <input type="text" value={r.amount} readOnly />
                </td>
                <td>
                  <input
                    type="text"
                    value={r.note}
                    onChange={e => updateItem(idx, { note: e.target.value })}
                    readOnly={readOnly}
                  />
                </td>
              </tr>
            ))}

            {/* 계 행 */}
            {showTotalRow && (
              <tr className="total-row">
                <td colSpan={6} style={{ textAlign: "center", fontWeight: "bold", backgroundColor: "#f0f0f0" }}>계</td>
                <td className="text-right" style={{ fontWeight: "bold", backgroundColor: "#f0f0f0" }}>{totalAmountStr}</td>
                <td className="delete-btn-cell" style={{ backgroundColor: "#f0f0f0", textAlign: "center" }}>
                  {!readOnly && (
                    <button
                      type="button"
                      style={{ padding: "2px 8px", fontSize: "9pt", cursor: "pointer" }}
                      onClick={() => { if (confirm("계 행을 삭제하시겠습니까?")) setShowTotalRow(false); }}
                    >삭제</button>
                  )}
                </td>
              </tr>
            )}

            {/* 원화환산 (KRW 외 통화 시만 표시) */}
            {currencyName && currencyName !== "KRW" && !currencyName.includes("원") && (
              <tr className="total-krw-row">
                <td colSpan={6} style={{ textAlign: "center", fontWeight: "bold", backgroundColor: "#e8f4f8" }}>원화환산 공급가액 (KRW)</td>
                <td className="text-right" style={{ fontWeight: "bold", backgroundColor: "#e8f4f8" }}>{totalAmountKrwStr}</td>
                <td style={{ backgroundColor: "#e8f4f8" }}></td>
              </tr>
            )}

            {/* 비고 */}
            <tr className="remarks-row">
              <td colSpan={8} style={{ height: 100, verticalAlign: "top", padding: 10, textAlign: "left" }}>
                <div style={{ fontWeight: "bold", marginBottom: 10 }}>&lt;비고&gt;</div>
                <textarea
                  value={noteRemarks}
                  onChange={e => setNoteRemarks(e.target.value)}
                  readOnly={readOnly}
                  style={{ width: "100%", height: 70, border: "none", resize: "none", fontSize: "10pt", textAlign: "left", whiteSpace: "pre-line" }}
                />
              </td>
            </tr>

            {/* 참조사항 */}
            <tr className="notes-row">
              <td colSpan={8} style={{ verticalAlign: "top", padding: 10, textAlign: "left", border: "1px solid #000" }}>
                <div style={{ fontWeight: "bold", marginBottom: 10 }}>&lt;참조사항&gt;</div>
                <div style={{ marginBottom: 5 }}>
                  <input type="text" value={note1} onChange={e => setNote1(e.target.value)} readOnly={readOnly} style={{ fontSize: "10pt" }} />
                </div>
                <div style={{ marginBottom: 5 }}>
                  <input type="text" value={note2} onChange={e => setNote2(e.target.value)} readOnly={readOnly} style={{ fontSize: "10pt" }} />
                </div>
                <div style={{ marginBottom: 5 }}>
                  <input type="text" value={note3} onChange={e => setNote3(e.target.value)} readOnly={readOnly} style={{ fontSize: "10pt" }} />
                </div>
                <div style={{ marginBottom: 5 }}>
                  <input type="text" value={note4} onChange={e => setNote4(e.target.value)} readOnly={readOnly} style={{ fontSize: "10pt" }} />
                </div>
              </td>
            </tr>

            {/* 푸터 회사명 */}
            <tr className="footer-row">
              <td colSpan={8} style={{ textAlign: "right", padding: 15, fontSize: "10pt", fontWeight: "bold", border: "none" }}>
                ㈜알피에스
              </td>
            </tr>
          </tbody>
        </table>
      </div>

      {/* 버튼 영역 (고정 하단) */}
      <div className="btn-area no-print">
        <button type="button" className="estimate-btn" onClick={handlePrint}>인쇄</button>
        <button type="button" className="estimate-btn" onClick={handleDownloadPdf}>PDF 다운로드</button>
        <button type="button" className="estimate-btn" onClick={handleSave} disabled={readOnly}>저장</button>
        <button type="button" className="estimate-btn" onClick={handleClose}>닫기</button>
      </div>
    </div>
  );
}
