// act-template.jsx — друковані «Акт приймання-передачі наданих послуг» + «Накладна
// приймання-передавання технічної документації» (2× A4). Виконавець = COMPANY (ТОВ,
// платник ПДВ); дані тягнуться з акта/договору/об'єкта. ПДВ 20% нараховується ЗВЕРХУ.
// Потребує window.moneyInWords (invoice-template.jsx) — завантажувати ПІСЛЯ нього.

function actFmt(n) {
  return Number(n).toLocaleString("uk-UA", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
}
const ACT_MONTHS = ["січня", "лютого", "березня", "квітня", "травня", "червня",
  "липня", "серпня", "вересня", "жовтня", "листопада", "грудня"];
function actDateUA(iso) {
  if (!iso) return null;
  const d = new Date(iso);
  if (isNaN(d)) return null;
  return `«${String(d.getDate()).padStart(2, "0")}» ${ACT_MONTHS[d.getMonth()]} ${d.getFullYear()} р.`;
}
function ActPh({ children }) { return <span className="act-ph">{children}</span>; }

// Нижній блок: реквізити + підписи сторін
// rc — конфіг ролей (Наш бік / контрагент)
function ActFooter({ co, client, rc }) {
  const cust = client && client.contact;
  const ourLabel = rc ? rc.our.label : "ВИКОНАВЕЦЬ";
  const counterLabel = rc ? rc.counter.label : "ЗАМОВНИК";
  return (
    <div className="act-footer">
      <div className="act-footer-h">Реквізити та підписи сторін</div>
      <div className="act-foot-grid">
        <div className="act-foot-col">
          <div className="act-party-role">{ourLabel}</div>
          <div className="act-party-name">{co.fullName || co.shortName}</div>
          <div className="act-party-line">Адреса: {co.address}</div>
          <div className="act-party-line">Код ЄДРПОУ {co.edrpou} · ІПН {co.vatId || <ActPh>уточнити</ActPh>}</div>
          <div className="act-party-line mono">р/р {co.iban}</div>
          <div className="act-party-line">{co.bank}</div>
          <div className="act-party-line">E-mail: {co.email || "office@ukrbudproiekt.ua"}</div>
          <div className="act-sign-role2">Директор {co.shortName}</div>
          <div className="act-sign-row">
            <span className="act-sign-slot"></span>
            <span className="act-sign-name">{co.director || <ActPh>П.І.Б.</ActPh>}</span>
          </div>
          <div className="act-stamp">М.П.</div>
        </div>
        <div className="act-foot-col">
          <div className="act-party-role">{counterLabel}</div>
          <div className="act-party-name">{client ? client.name : <ActPh>Назва замовника</ActPh>}</div>
          <div className="act-party-line">Адреса: {client?.address || <ActPh>адреса</ActPh>}</div>
          <div className="act-party-line">Код ЄДРПОУ {client?.edrpou || <ActPh>________</ActPh>}</div>
          <div className="act-party-line mono">р/р <ActPh>UA__ ____ ____ ____</ActPh></div>
          <div className="act-party-line"><ActPh>банк, МФО</ActPh></div>
          <div className="act-sign-role2">{cust ? cust.role : <ActPh>посада</ActPh>}</div>
          <div className="act-sign-row">
            <span className="act-sign-slot"></span>
            <span className="act-sign-name">{cust ? cust.name : <ActPh>П.І.Б.</ActPh>}</span>
          </div>
          <div className="act-stamp">М.П.</div>
        </div>
      </div>
    </div>
  );
}

function ActPrintDoc({ act, onClose }) {
  React.useEffect(() => {
    const onKey = (e) => e.key === "Escape" && onClose();
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [onClose]);

  const isFop = !!(act && act.execEntity === "fop");
  const co = isFop ? (window.COMPANY_FOP || window.COMPANY || {}) : (window.COMPANY || {});
  const obj = act ? window.getObject(act.obj) : null;
  const contract = obj ? (window.DATA.CONTRACTS || []).find(c => c.obj === obj.id) : null;
  let client = contract ? window.getClient(contract.client) : null;
  // Проєкт ГО: контрагент — партнер-ГО
  if (!client && act && act.partnerId && window.getNgoPartner) {
    const ng = window.getNgoPartner(act.partnerId);
    if (ng) client = { name: ng.name, edrpou: ng.edrpou, address: ng.city ? `м. ${ng.city}` : null, contact: ng.contact };
  }
  const noVat = !!(act && act.noVat);
  // Ролі сторін (Виконавець / Підрядник) — з договору
  const rc = (window.actRoleConfig && contract) ? window.actRoleConfig(contract)
    : { our: { labelGen: "Виконавця", short: "Виконавець", label: "ВИКОНАВЕЦЬ" },
        counter: { labelGen: "Замовника", short: "Замовник", label: "ЗАМОВНИК" },
        subj: window.ACT_SUBJECTS ? window.ACT_SUBJECTS.services : { titleSuffix: "наданих послуг", verb: "надав", verbPl: "надано", noun: "послуги", genPl: "послуг", unit: "послуга", noteDone: "Послуги надані в повному обсязі" } };

  // ПДВ 20% ЗВЕРХУ: сума акта трактується як база (без ПДВ)
  const base = act && typeof act.amount === "number" ? act.amount : 0;
  const vat = noVat ? 0 : Math.round(base * 0.20 * 100) / 100;
  const total = noVat ? base : Math.round((base + vat) * 100) / 100;
  const hasAmount = base > 0;

  const num = act ? act.num : null;
  const dateUA = actDateUA(act && act.date);
  const contractNo = contract ? contract.number : ((act && act.contractNumber) || null);
  const contractDate = contract ? (actDateUA(contract.date) || contract.date) : ((act && act.contractDate) ? (actDateUA(act.contractDate) || act.contractDate) : null);
  const custRep = client && client.contact
    ? `${client.contact.role} ${client.contact.name}`
    : null;

  const venue = obj
    ? `по об'єкту: «${obj.name}»${obj.code ? ` (${obj.code})` : ""}`
    : (act && act.projectName ? `за проєктом: «${act.projectName}»${act.projectCode ? ` (${act.projectCode})` : ""}` : "");
  const serviceLine = act
    ? `${rc.subj.noun === "роботи" ? "Роботи" : "Послуги"} з розроблення проєктно-кошторисної документації${act.stage ? ` (${act.stage})` : ""} ${venue}`
    : null;

  // Перелік томів технічної документації (типовий комплект; редагується)
  const docRows = [
    { code: "ПЗ", name: "Том 1. Пояснювальна записка", qty: "4 прим." },
    { code: "АР", name: "Том 2. Архітектурні рішення", qty: "4 прим." },
    { code: "КР", name: "Том 3. Конструктивні рішення", qty: "4 прим." },
    { code: "ІМ", name: "Том 4. Інженерні мережі (ОВ, ВК, ЕО)", qty: "4 прим." },
    { code: "К",  name: "Том 5. Кошторисна документація", qty: "4 прим." },
    { code: "ВД", name: "Том 6. Вихідні дані", qty: "4 прим." },
    { code: null, name: "Електронний носій (PDF + DWG)", qty: "1 прим.", note: "CD/USB" },
  ];
  const desig = (c) => c ? `${obj ? obj.code + "." : ""}${c}` : "—";

  const doPrint = () => window.print();

  return (
    <>
      <ActStyles />
      <div className="act-print-root">
        <div className="act-backdrop" onClick={onClose}></div>

        <div className="act-toolbar">
          <div className="act-toolbar-title">Акт + накладна{num ? ` · ${num}` : ""}</div>
          <div className="act-toolbar-actions">
            <button className="btn" onClick={onClose}>Закрити</button>
            <button className="btn btn-primary" onClick={doPrint}>
              <window.Icon.Check /> Друк / Зберегти PDF
            </button>
          </div>
        </div>

        <div className="act-scroll">

          {/* ===================== СТОРІНКА 1: АКТ ===================== */}
          <div className="act-sheet">
            <div className="act-logo-row">
              <img src="logo-horizontal-black.svg" alt={co.shortName} className="act-logo" />
            </div>

            <h1 className="act-title">АКТ № {num || <ActPh>__</ActPh>}<br /><span>приймання-передачі {rc.subj.titleSuffix}</span></h1>

            <div className="act-place">
              <span>м. {co.city || "Київ"}</span>
              <span>{dateUA || <ActPh>«__» ________ 2026 року</ActPh>}</span>
            </div>

            <p className="act-text">
              Ми, що нижче підписалися, представник {rc.our.labelGen} — {co.fullName || co.shortName} в особі
              директора {co.director || <ActPh>П.І.Б.</ActPh>}, що діє на підставі Статуту, і представник
              {" "}{rc.counter.labelGen} — {custRep || <ActPh>посада, П.І.Б.</ActPh>}, уклали цей акт про те, що {rc.our.short}{" "}
              у повному обсязі {rc.subj.verb} {rc.subj.noun} відповідно до Договору № {contractNo || <ActPh>____</ActPh>}
              {" "}від {contractDate || <ActPh>«__» ________ 20__ р.</ActPh>}:
            </p>

            <table className="act-table">
              <thead>
                <tr>
                  <th className="c-no">№</th>
                  <th className="c-name">Найменування</th>
                  <th className="c-unit">Од. виміру</th>
                  <th className="c-qty">К-сть</th>
                  <th className="c-price">Ціна за од., грн без ПДВ</th>
                  <th className="c-sum">Сума, грн без ПДВ</th>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <td className="c-no">1</td>
                  <td className="c-name">{serviceLine || <ActPh>Найменування послуг</ActPh>}</td>
                  <td className="c-unit">{rc.subj.unit}</td>
                  <td className="c-qty">1</td>
                  <td className="c-price mono">{hasAmount ? actFmt(base) : <ActPh>0,00</ActPh>}</td>
                  <td className="c-sum mono">{hasAmount ? actFmt(base) : <ActPh>0,00</ActPh>}</td>
                </tr>
              </tbody>
            </table>

            <div className="act-totals">
              <div className="act-total-row"><span>Всього без ПДВ:</span><span className="mono">{hasAmount ? actFmt(base) : <ActPh>0,00</ActPh>} грн</span></div>
              <div className="act-total-row"><span>ПДВ:</span><span className="mono">{noVat ? "без ПДВ" : <React.Fragment>{hasAmount ? actFmt(vat) : <ActPh>0,00</ActPh>} грн</React.Fragment>}</span></div>
              <div className="act-total-row act-total-grand"><span>Всього{noVat ? "" : " з ПДВ"}:</span><span className="mono">{hasAmount ? actFmt(total) : <ActPh>0,00</ActPh>} грн</span></div>
            </div>

            <p className="act-words">
              Всього {rc.subj.verbPl} {rc.subj.genPl} на суму (прописом): <b>{hasAmount ? actFmt(total) : "0,00"} грн</b>
              {" — "}
              {hasAmount
                ? `${window.moneyInWords(total)}${noVat ? " (без ПДВ)." : `, у тому числі ПДВ 20% — ${actFmt(vat)} грн.`}`
                : <ActPh>сума прописом</ActPh>}
            </p>

            <p className="act-note">{rc.subj.noteDone}, сторони претензій одна до одної не мають.</p>
            <p className="act-note">Акт складено у 2-х екземплярах, по одному для кожної із сторін.</p>

            <ActFooter co={co} client={client} rc={rc} />
          </div>

          {/* ===================== СТОРІНКА 2: НАКЛАДНА ===================== */}
          <div className="act-sheet act-sheet-2">
            <div className="act-logo-row">
              <img src="logo-horizontal-black.svg" alt={co.shortName} className="act-logo" />
            </div>

            <h1 className="act-title">НАКЛАДНА № {num || <ActPh>__</ActPh>}<br />
              <span>приймання-передавання технічної документації</span><br />
              <span className="act-title-sub">по Договору № {contractNo || <ActPh>____</ActPh>} від {contractDate || <ActPh>«__» ________ 20__ р.</ActPh>}</span>
            </h1>

            <div className="act-place">
              <span>м. {co.city || "Київ"}</span>
              <span>{dateUA || <ActPh>«__» ________ 2026 року</ActPh>}</span>
            </div>

            <p className="act-text">
              {co.fullName || co.shortName} передало, а {client ? client.name : <ActPh>Замовник</ActPh>} в особі
              {" "}{custRep || <ActPh>посада, П.І.Б.</ActPh>} прийняло технічну документацію по
              Договору № {contractNo || <ActPh>____</ActPh>} від {contractDate || <ActPh>«__» ________ 20__ р.</ActPh>}:
            </p>

            <table className="act-table act-table-doc">
              <thead>
                <tr>
                  <th className="c-no">№</th>
                  <th className="c-desig">Позначення</th>
                  <th className="c-dname">Найменування документів</th>
                  <th className="c-dqty">К-сть</th>
                  <th className="c-note">Примітка</th>
                </tr>
              </thead>
              <tbody>
                {docRows.map((r, i) => (
                  <tr key={i}>
                    <td className="c-no">{i + 1}</td>
                    <td className="c-desig mono">{desig(r.code)}</td>
                    <td className="c-dname">{r.name}</td>
                    <td className="c-dqty">{r.qty}</td>
                    <td className="c-note">{r.note || ""}</td>
                  </tr>
                ))}
              </tbody>
            </table>

            <p className="act-note">Документацію передано в повному обсязі. Сторони претензій одна до одної не мають.</p>

            <ActFooter co={co} client={client} rc={rc} />
          </div>

        </div>
      </div>
    </>
  );
}

function ActStyles() {
  return (
    <style>{`
      .act-print-root { position: fixed; inset: 0; z-index: 1200; display: flex; flex-direction: column; }
      .act-backdrop { position: absolute; inset: 0; background: rgba(4, 18, 26, 0.55); backdrop-filter: blur(2px); }
      .act-toolbar { position: relative; z-index: 2; display: flex; align-items: center; justify-content: space-between;
        gap: 16px; padding: 12px 20px; background: var(--bg-elev); border-bottom: 1px solid var(--line); }
      .act-toolbar-title { font-size: 13.5px; font-weight: 650; color: var(--ink); }
      .act-toolbar-actions { display: flex; gap: 10px; }
      .act-scroll { position: relative; z-index: 1; flex: 1 1 auto; overflow-y: auto; padding: 28px 20px 60px;
        display: flex; flex-direction: column; align-items: center; gap: 26px; }

      .act-sheet { width: 210mm; max-width: 100%; min-height: 297mm; background: #fff; color: #14181c;
        padding: 15mm 16mm 16mm; box-shadow: 0 18px 50px rgba(0,0,0,0.32); box-sizing: border-box;
        font-family: var(--font, "Inter", system-ui, sans-serif); line-height: 1.42; font-size: 12px; }
      .act-sheet .mono { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-variant-numeric: tabular-nums; }
      .act-ph { color: #9aa6ad; font-style: italic; border-bottom: 1px dashed #c4ced3; }

      .act-logo-row { display: flex; justify-content: flex-end; margin-bottom: 12px; }
      .act-logo { height: 30px; width: auto; max-width: 55%; }

      .act-party-role { font-size: 10px; font-weight: 800; letter-spacing: 0.04em; color: #14181c; margin-bottom: 3px; }
      .act-party-name { font-size: 12px; font-weight: 700; color: #14181c; margin-bottom: 2px; text-wrap: pretty; }
      .act-party-line { font-size: 10.5px; color: #2c343a; line-height: 1.5; }

      .act-title { font-size: 17px; font-weight: 750; text-align: center; margin: 8px 0 4px; line-height: 1.3; }
      .act-title span { font-size: 13px; font-weight: 600; }
      .act-title .act-title-sub { font-size: 11px; font-weight: 500; color: #4a555c; }

      .act-place { display: flex; justify-content: space-between; font-size: 11.5px; color: #14181c; margin: 14px 0 12px; }

      .act-text { font-size: 12px; color: #14181c; line-height: 1.5; margin: 0 0 14px; text-align: justify; text-wrap: pretty; }

      /* Таблиці */
      .act-table { width: 100%; border-collapse: collapse; margin-bottom: 14px; }
      .act-table th { background: #eef3f4; border: 1px solid #b9c4ca; padding: 6px 8px; font-size: 9.5px;
        text-transform: uppercase; letter-spacing: 0.02em; color: #2c343a; font-weight: 700; text-align: center; line-height: 1.3; }
      .act-table td { border: 1px solid #c8d1d6; padding: 8px; font-size: 11.5px; color: #14181c; vertical-align: top; }
      .act-table .c-no { width: 30px; text-align: center; }
      .act-table .c-unit, .act-table .c-qty { width: 64px; text-align: center; }
      .act-table .c-price, .act-table .c-sum { width: 110px; text-align: right; white-space: nowrap; }
      .act-table-doc .c-desig { width: 110px; }
      .act-table-doc .c-dqty { width: 70px; text-align: center; }
      .act-table-doc .c-note { width: 90px; }

      .act-totals { margin-left: auto; width: 290px; margin-bottom: 12px; }
      .act-total-row { display: flex; justify-content: space-between; padding: 4px 2px; font-size: 12px; }
      .act-total-row span:first-child { color: #4a555c; }
      .act-total-grand { border-top: 2px solid #14181c; margin-top: 3px; padding-top: 7px; font-size: 13.5px; font-weight: 750; }
      .act-total-grand span:first-child { color: #14181c; }

      .act-words { font-size: 11.5px; color: #14181c; line-height: 1.5; margin: 0 0 14px; text-wrap: pretty; }
      .act-note { font-size: 11.5px; color: #2c343a; margin: 0 0 8px; }

      /* Реквізити + підписи (низ) */
      .act-footer { margin-top: 30px; border-top: 1.5px solid #14181c; padding-top: 12px; break-inside: avoid; }
      .act-footer-h { font-size: 11px; font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase;
        color: #14181c; text-align: center; margin-bottom: 14px; }
      .act-foot-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 40px; }
      .act-foot-col .act-party-role { margin-bottom: 4px; }
      .act-sign-role2 { font-size: 10.5px; color: #4a555c; margin-top: 18px; margin-bottom: 24px; }
      .act-sign-row { display: flex; align-items: flex-end; gap: 10px; }
      .act-sign-slot { flex: 1 1 auto; border-bottom: 1px solid #14181c; height: 1px; }
      .act-sign-name { font-size: 11px; font-weight: 600; color: #14181c; white-space: nowrap; }
      .act-stamp { width: 78px; height: 78px; border: 1.5px dashed #b9c4ca; border-radius: 50%; display: flex;
        align-items: center; justify-content: center; font-size: 11px; color: #9aa6ad; margin-top: 14px; }

      @media (max-width: 760px) {
        .act-foot-grid { grid-template-columns: 1fr; gap: 22px; }
        .act-sheet { padding: 10mm; }
      }

      @media print {
        body * { visibility: hidden !important; }
        .act-print-root, .act-print-root * { visibility: visible !important; }
        .act-print-root { position: absolute !important; inset: 0 !important; z-index: 9999; }
        .act-backdrop, .act-toolbar { display: none !important; }
        .act-scroll { overflow: visible !important; padding: 0 !important; display: block !important; }
        .act-sheet { box-shadow: none !important; width: auto !important; min-height: 0 !important; padding: 0 !important; margin: 0 !important; }
        .act-sheet-2 { break-before: page; page-break-before: always; }
        @page { size: A4; margin: 14mm; }
      }
    `}</style>
  );
}

window.ActPrintDoc = ActPrintDoc;

// Синтез чернетки акта з договору (наступна несплачена/поточна віха графіку).
window.draftActForContract = function (contract, stageIdx) {
  if (!contract) return null;
  const today = window.TODAY_ISO || "2026-05-26";
  const sched = contract.schedule || [];
  let idx = (typeof stageIdx === "number" && stageIdx >= 0) ? stageIdx : sched.findIndex(s => !s.paidDate);
  if (idx < 0) idx = sched.length ? sched.length - 1 : -1;
  const m = idx >= 0 ? sched[idx] : {};
  const obj = window.getObject(contract.obj);
  const codeNum = obj && obj.code ? (obj.code.match(/(\d+)\s*$/) || [])[1] : null;
  const base = codeNum || (contract.number || "").split("/")[0] || "";
  const proj = contract.__project || null;
  const execEntity = proj ? proj.execEntity : (contract.execEntity || null);
  return {
    num: base ? `${base}-АКТ-${String(idx >= 0 ? idx + 1 : 1).padStart(2, "0")}` : null,
    date: today,
    obj: contract.obj,
    stage: m.stage || "",
    amount: m.amount || 0,
    status: "draft",
    execEntity,
    noVat: execEntity === "fop",
    projectName: proj ? proj.name : (contract.projectName || null),
    projectCode: proj ? proj.code : (contract.projectCode || null),
    partnerId: proj ? proj.partner : (contract.partnerId || null),
    contractNumber: contract.number || null,
    contractDate: contract.date || null,
  };
};

// ─────────────────────────────────────────────────────────────
// Пікер «Сформувати акт»: обрати договір (або проєкт ГО) і віху,
// далі відкриває друковану форму акта. Аналог InvoiceContractPicker.
// ─────────────────────────────────────────────────────────────
function ActContractPicker({ onClose, onPick }) {
  const { useState, useEffect } = React;
  const today = window.TODAY_ISO || "2026-05-26";
  const designList = (window.DATA.CONTRACTS || []).filter(c => c.status !== "draft");
  const projList = (window.DATA.PROJECTS || []).map(p => ({ ...p.contract, kind: "project", __project: p }));
  const list = [...designList, ...projList];

  const dispCode = (c) => c.__project ? c.__project.code : (window.getObject(c.obj)?.code || "—");
  const dispName = (c) => c.__project ? c.__project.name : (window.getObject(c.obj)?.name || "Без об'єкта");
  const dispClient = (c) => c.__project ? (window.getNgoPartner(c.__project.partner)?.short || "ГО") : (window.getClient(c.client)?.short || "—");
  const dispNum = (c) => c.number;

  const firstActive = list.find(c => c.status === "active") || list[0];
  const keyOf = (c) => c.__project ? "prj-" + c.__project.id : c.id;
  const [selKey, setSelKey] = useState(firstActive ? keyOf(firstActive) : null);

  const nextUnpaidIdx = (c) => {
    const i = (c.schedule || []).findIndex(s => !s.paidDate);
    return i < 0 ? Math.max(0, (c.schedule || []).length - 1) : i;
  };
  const [milestoneIdx, setMilestoneIdx] = useState(firstActive ? nextUnpaidIdx(firstActive) : 0);

  useEffect(() => {
    const onKey = (e) => e.key === "Escape" && onClose();
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [onClose]);

  const pick = (c) => { setSelKey(keyOf(c)); setMilestoneIdx(nextUnpaidIdx(c)); };
  const selected = list.find(c => keyOf(c) === selKey) || null;
  const sched = selected ? (selected.schedule || []) : [];
  const fmt = (n) => (window.formatMoney ? window.formatMoney(n) : n);

  const submit = () => { if (selected) onPick(window.draftActForContract(selected, milestoneIdx)); };

  return (
    <React.Fragment>
      <div className="drawer-overlay" onClick={onClose}></div>
      <div className="report-modal ip-modal">
        <div className="report-toolbar">
          <button className="drawer-close" onClick={onClose}><window.Icon.X /></button>
          <div className="ip-head-ic"><window.Ico name="clipboard" size={20} /></div>
          <div>
            <div className="ip-head-title">Сформувати акт</div>
            <div className="ip-head-sub">Оберіть договір / проєкт і етап графіку</div>
          </div>
        </div>

        <div className="ip-body">
          <div className="ip-col ip-col-contracts">
            <div className="ip-col-label">Договір / проєкт</div>
            <div className="ip-contract-list">
              {list.map(c => {
                const st = window.CONTRACT_STATUS[c.status] || window.PROJECT_STATUS?.[c.__project?.status] || {};
                const ni = nextUnpaidIdx(c);
                const next = c.schedule ? c.schedule[ni] : null;
                const allPaid = (c.schedule || []).every(s => s.paidDate);
                const k = keyOf(c);
                return (
                  <button key={k} type="button" className={`ip-contract ${selKey === k ? "is-active" : ""}`} onClick={() => pick(c)}>
                    <div className="ip-contract-top">
                      <span className="ip-obj-code td-mono">{dispCode(c)}</span>
                      <span className={`status-tag ${"tone-" + (st.tone || "neutral")} ip-c-status`}>{c.__project ? "Проєкт ГО" : st.label}</span>
                    </div>
                    <div className="ip-obj-name">{dispName(c)}</div>
                    <div className="ip-contract-meta">
                      <span className="ip-client">{dispClient(c)}</span>
                      <span className="ip-c-num td-mono">№ {dispNum(c)}</span>
                    </div>
                    <div className="ip-next">
                      {allPaid
                        ? <span className="ip-next-paid">усі етапи графіку закриті</span>
                        : <React.Fragment><span className="ip-next-stage">{next?.stage}</span><span className="ip-next-sum">{fmt(next?.amount || 0)} ₴</span></React.Fragment>}
                    </div>
                  </button>
                );
              })}
            </div>
          </div>

          <div className="ip-col ip-col-detail">
            {selected ? (
              <React.Fragment>
                <div className="ip-col-label">Етап для акта</div>
                <div className="ip-milestones">
                  {sched.map((s, i) => {
                    const disabled = !!s.paidDate;
                    return (
                      <label key={i} className={`ip-ms ${milestoneIdx === i ? "is-on" : ""} ${disabled ? "is-disabled" : ""}`}>
                        <input type="radio" name="act-ms" checked={milestoneIdx === i} disabled={disabled} onChange={() => setMilestoneIdx(i)} />
                        <span className="ip-ms-radio"></span>
                        <span className="ip-ms-main">
                          <span className="ip-ms-stage">{s.stage}</span>
                          <span className="ip-ms-sub"><span className="td-mono">{s.pct}%</span></span>
                        </span>
                        <span className="ip-ms-right">
                          <span className="ip-ms-amount">{fmt(s.amount)} ₴</span>
                          {disabled && <span className="status-tag tone-neutral ip-ms-tag">сплачено</span>}
                        </span>
                      </label>
                    );
                  })}
                </div>
                <div className="ip-summary">
                  <div className="ip-summary-row ip-summary-total">
                    <span>Сума акта</span>
                    <span className="td-mono">{fmt(sched[milestoneIdx]?.amount || 0)} ₴</span>
                  </div>
                </div>
                <div className="hint-box" style={{ marginTop: 12 }}>
                  Сформується чернетка акта {selected.__project ? "наданих послуг (проєкт ГО)" : "наданих послуг / виконаних робіт"} за обраний етап. Друкована форма відкриється у наступному кроці.
                </div>
              </React.Fragment>
            ) : (
              <div className="ip-empty">Немає договорів чи проєктів для акта.</div>
            )}
          </div>
        </div>

        <div className="ip-foot">
          <button className="btn" onClick={onClose}>Скасувати</button>
          <button className="btn btn-primary" onClick={submit} disabled={!selected} style={!selected ? { opacity: 0.5, pointerEvents: "none" } : {}}>
            Сформувати акт
          </button>
        </div>
      </div>
    </React.Fragment>
  );
}
window.ActContractPicker = ActContractPicker;
