// fin-report.jsx — Фінансова звітність мікропідприємства (НП(С)БО 25, Дод. 2):
// Форма 1-мс «Баланс» (ДКУД 1801006) + Форма 2-мс «Звіт про фінансові результати» (1801007).
// Одиниця: тис. грн з 1 знаком. Ф2 автозаповнюється з P&L; у Ф1 — авто-рядки + ручні поля.
// Усе редаговане й зберігається (resource fin-reports, id = fin-<year>).

(function () {
  const tis = (uah) => Math.round((uah || 0) / 100) / 10;     // ₴ → тис. грн (1 знак)
  const fmt = (v) => (v == null || v === "" || isNaN(v)) ? "" :
    Number(v).toLocaleString("uk-UA", { minimumFractionDigits: 1, maximumFractionDigits: 1 });

  // ── Структура Форми 1-мс «Баланс» ──
  const F1_ROWS = [
    { sec: "Актив" },
    { h: "I. Необоротні активи" },
    { code: "1010", label: "Основні засоби:", calc: true, bold: true },
    { code: "1011", label: "первісна вартість", indent: true, auto: "ozCost" },
    { code: "1012", label: "знос", indent: true, neg: true, auto: "ozWear" },
    { code: "1090", label: "Інші необоротні активи" },
    { code: "1095", label: "Усього за розділом I", calc: true, bold: true },
    { h: "II. Оборотні активи" },
    { code: "1100", label: "Запаси" },
    { code: "1155", label: "Поточна дебіторська заборгованість", auto: "recv" },
    { code: "1165", label: "Гроші та їх еквіваленти", auto: "cash" },
    { code: "1190", label: "Інші оборотні активи" },
    { code: "1195", label: "Усього за розділом II", calc: true, bold: true },
    { code: "1300", label: "Баланс", calc: true, bold: true, total: true },
    { sec: "Пасив" },
    { h: "I. Власний капітал" },
    { code: "1400", label: "Капітал" },
    { code: "1420", label: "Нерозподілений прибуток (непокритий збиток)" },
    { code: "1425", label: "Неоплачений капітал", neg: true },
    { code: "1495", label: "Усього за розділом I", calc: true, bold: true },
    { code: "1595", label: "II. Довгострокові зобов'язання, цільове фінансування та забезпечення" },
    { h: "III. Поточні зобов'язання" },
    { code: "1600", label: "Короткострокові кредити банків" },
    { code: "1615", label: "Поточна кредиторська заборгованість за товари, роботи, послуги", auto: "payables" },
    { code: "1620", label: "розрахунки з бюджетом" },
    { code: "1625", label: "розрахунки зі страхування" },
    { code: "1630", label: "розрахунки з оплати праці" },
    { code: "1690", label: "Інші поточні зобов'язання" },
    { code: "1695", label: "Усього за розділом III", calc: true, bold: true },
    { code: "1900", label: "Баланс", calc: true, bold: true, total: true },
  ];
  // Ф1 колонки: «На початок звітного року» = prev, «На кінець звітного періоду» = cur
  const F1_CALC = {
    "1010": (g) => g("1011") - g("1012"),
    "1095": (g) => g("1010") + g("1090"),
    "1195": (g) => g("1100") + g("1155") + g("1165") + g("1190"),
    "1300": (g) => g("1095") + g("1195"),
    "1495": (g) => g("1400") + g("1420") - g("1425"),
    "1695": (g) => g("1600") + g("1615") + g("1620") + g("1625") + g("1630") + g("1690"),
    "1900": (g) => g("1495") + g("1595") + g("1695"),
  };

  // ── Структура Форми 2-мс «Звіт про фінансові результати» ──
  const F2_ROWS = [
    { code: "2000", label: "Чистий дохід від реалізації продукції (товарів, робіт, послуг)", auto: "rev" },
    { code: "2160", label: "Інші доходи" },
    { code: "2280", label: "Разом доходи (2000 + 2160)", calc: true, bold: true },
    { code: "2050", label: "Собівартість реалізованої продукції (товарів, робіт, послуг)", neg: true },
    { code: "2165", label: "Інші витрати", neg: true, auto: "exp" },
    { code: "2285", label: "Разом витрати (2050 + 2165)", calc: true, bold: true },
    { code: "2290", label: "Фінансовий результат до оподаткування (2280 − 2285)", calc: true, bold: true },
    { code: "2300", label: "Податок на прибуток", neg: true, auto: "tax" },
    { code: "2310", label: "Витрати (доходи), які зменшують (збільшують) фінрезультат після оподаткування" },
    { code: "2350", label: "Чистий прибуток (збиток) (2290 − 2300 − (+) 2310)", calc: true, bold: true, total: true },
  ];
  // Ф2 колонки: «За звітний період» = cur, «За попередній період» = prev
  const F2_CALC = {
    "2280": (g) => g("2000") + g("2160"),
    "2285": (g) => g("2050") + g("2165"),
    "2290": (g) => g("2280") - g("2285"),
    "2350": (g) => g("2290") - g("2300") - g("2310"),
  };
  const CALC = Object.assign({}, F1_CALC, F2_CALC);

  // ── Авто-значення з даних ERP (у тис. грн) ──
  function autoFor(year) {
    const out = {};
    const plOf = (y) => { try { return window.computeAnnualPL(String(y)) || {}; } catch (e) { return {}; } };
    const setF2 = (col, pl) => {
      const put = (code, v) => { out[code] = out[code] || {}; out[code][col] = v; };
      put("2000", tis(pl.revenueNet));
      // Собівартість (2050) = усі прямі витрати: ЗП + ЄСВ + субпідряд/експертиза + виробничі ЗВВ + амортизація
      put("2050", tis((pl.payroll || 0) + (pl.esv || 0) + (pl.subExp || 0) + (pl.zvvOther || 0) + (pl.amort || 0)));
      // Інші витрати (2165) = адміністративні
      put("2165", tis(pl.adm || 0));
      put("2300", tis(pl.profitTax));
    };
    setF2("cur", plOf(year));
    setF2("prev", plOf(year - 1));

    // Ф1 (на кінець = cur) — best-effort зі знімка даних
    const D = window.DATA || {};
    const assets = (D.ASSETS || []).filter(a => a.status !== "written_off");
    const ozCost = assets.reduce((s, a) => s + (a.cost || 0), 0);
    const ozWear = assets.reduce((s, a) => {
      const dep = window.computeDepreciation ? window.computeDepreciation(a) : null;
      return s + (dep ? (dep.accumulated || 0) : 0);
    }, 0);
    const recv = (D.INVOICES || []).filter(i => i.status !== "paid").reduce((s, i) => s + (i.amount || 0), 0);
    const cash = (D.CASH_ACCOUNTS || []).reduce((s, a) => s + (a.balance || 0), 0);
    const payPur = (D.PURCHASE_INVOICES || []).filter(p => p.status !== "paid").reduce((s, p) => s + (p.amount || 0), 0);
    const paySub = (D.SUB_PAYMENTS || []).filter(p => p.status !== "paid").reduce((s, p) => s + (p.amount || 0), 0);
    const put = (code, v) => { out[code] = out[code] || {}; out[code].cur = v; };
    put("1011", tis(ozCost)); put("1012", tis(ozWear));
    put("1155", tis(recv)); put("1165", tis(cash));
    put("1615", tis(payPur + paySub));
    return out;
  }

  const AUTO_KEYS = { rev: "2000", exp: "2165", tax: "2300", ozCost: "1011", ozWear: "1012", recv: "1155", cash: "1165", payables: "1615" };

  function FinReportPage({ role }) {
    const sysYear = parseInt(String(window.SYS_DATE || "2026").slice(0, 4), 10) || 2026;
    const [year, setYear] = React.useState(sysYear - 1);   // звітний рік = минулий
    const [vals, setVals] = React.useState({});            // {code:{cur,prev}}
    const [hdr, setHdr] = React.useState({});              // редаговані поля шапки
    const [recId, setRecId] = React.useState(null);
    const [saved, setSaved] = React.useState(true);
    const [busy, setBusy] = React.useState(false);
    const canEdit = role === "director" || role === "accountant";
    const co = window.COMPANY || {};

    const load = React.useCallback(() => {
      const auto = autoFor(year);
      const apply = (rec) => {
        const v = (rec && rec.values) ? rec.values : {};
        // ефективні значення: збережене перекриває авто
        const merged = {};
        const codes = new Set([...Object.keys(auto), ...Object.keys(v)]);
        codes.forEach(c => { merged[c] = { cur: pick(v[c], auto[c], "cur"), prev: pick(v[c], auto[c], "prev") }; });
        setVals(merged);
        setHdr((rec && rec.header) || {});
        setRecId(rec ? rec.id : null);
        setSaved(true);
      };
      if (window.API && window.API.list) {
        window.API.list("fin-reports", { year: String(year) })
          .then(rows => apply((rows || []).find(r => String(r.year) === String(year)) || null))
          .catch(() => apply(null));
      } else apply(null);
    }, [year]);
    React.useEffect(() => { load(); }, [load]);

    function pick(savedCell, autoCell, col) {
      if (savedCell && savedCell[col] != null && savedCell[col] !== "") return savedCell[col];
      if (autoCell && autoCell[col] != null) return autoCell[col];
      return "";
    }

    // resolve значення коду в колонці (з урахуванням розрахункових рядків)
    const resolve = (code, col) => {
      if (CALC[code]) { const g = (c) => resolve(c, col); return CALC[code](g); }
      const cell = vals[code]; const x = cell ? cell[col] : "";
      return (x === "" || x == null || isNaN(x)) ? 0 : Number(x);
    };

    const setCell = (code, col, raw) => {
      setVals(prev => ({ ...prev, [code]: { ...(prev[code] || {}), [col]: raw } }));
      setSaved(false);
    };

    const recalc = () => {
      const auto = autoFor(year);
      setVals(prev => {
        const next = { ...prev };
        Object.entries(auto).forEach(([code, cell]) => {
          next[code] = { ...(next[code] || {}) };
          if (cell.cur != null) next[code].cur = cell.cur;
          if (cell.prev != null) next[code].prev = cell.prev;
        });
        return next;
      });
      setSaved(false);
    };

    const save = async () => {
      if (!canEdit) return;
      if (!(window.API && window.API.mode === "live" && window.API.save)) { alert("Збереження доступне лише на сервері."); return; }
      setBusy(true);
      const id = recId || ("fin-" + year);
      const payload = { id, year: String(year), values: vals, header: hdr };
      try {
        await window.API.save("fin-reports", recId ? id : null, payload);
        setRecId(id); setSaved(true);
      } catch (e) { console.error("[ERP] save fin-report:", e); alert("Не вдалося зберегти звіт."); }
      setBusy(false);
    };

    const copyForm = (rows, cols) => {
      const lines = rows.filter(r => r.code).map(r => {
        const get = (col) => fmt(r.calc ? resolve(r.code, col) : (vals[r.code] ? vals[r.code][col] : ""));
        return [r.label, r.code, ...cols.map(c => get(c.key))].join("\t");
      });
      const text = lines.join("\n");
      if (navigator.clipboard) navigator.clipboard.writeText(text).then(() => {}).catch(() => {});
      try { window.prompt && false; } catch (e) {}
      alert("Скопійовано рядки у буфер (можна вставити в кабінет / Excel).");
    };

    const renderTable = (rows, cols) => (
      <table className="data-table fin-table">
        <thead>
          <tr><th style={{ width: "52%" }}>Стаття</th><th style={{ width: 64 }}>Код</th>
            {cols.map(c => <th key={c.key} className="num-col">{c.label}</th>)}</tr>
        </thead>
        <tbody>
          {rows.map((r, i) => {
            if (r.sec) return <tr key={i} className="fin-sec"><td colSpan={2 + cols.length}>{r.sec}</td></tr>;
            if (r.h) return <tr key={i} className="fin-h"><td colSpan={2 + cols.length}>{r.h}</td></tr>;
            return (
              <tr key={i} className={(r.bold ? "fin-bold " : "") + (r.total ? "fin-total" : "")}>
                <td className={r.indent ? "fin-indent" : ""}>{r.label}</td>
                <td className="td-mono fin-code">{r.code}</td>
                {cols.map(c => {
                  if (r.calc) {
                    const v = resolve(r.code, c.key);
                    return <td key={c.key} className="num-col num-bold">{fmt(v)}</td>;
                  }
                  const cur = vals[r.code] ? vals[r.code][c.key] : "";
                  const isAuto = r.auto && cur !== "" && cur != null;
                  return (
                    <td key={c.key} className="num-col">
                      {canEdit
                        ? <input className="fin-in" type="number" step="0.1" inputMode="decimal"
                                 value={cur == null ? "" : cur}
                                 title={r.auto ? "Авто з даних ERP — можна змінити" : ""}
                                 onChange={e => setCell(r.code, c.key, e.target.value)} />
                        : fmt(cur)}
                      {r.neg && (cur !== "" && cur != null) ? "" : null}
                    </td>
                  );
                })}
              </tr>
            );
          })}
        </tbody>
      </table>
    );

    const F1_COLS = [{ key: "prev", label: "На початок звітного року" }, { key: "cur", label: "На кінець звітного періоду" }];
    const F2_COLS = [{ key: "cur", label: "За звітний період" }, { key: "prev", label: "За попередній період" }];

    // контроль зведення балансу
    const b1ok = Math.abs(resolve("1300", "cur") - resolve("1900", "cur")) < 0.05;

    return (
      <div className="page">
        <div className="page-head">
          <h1 className="page-h1">Фінансова звітність</h1>
          <div className="page-sub">
            <span>Мікропідприємство · НП(С)БО 25</span>
            <span className="dot"></span>
            <span>Ф1-мс (1801006) + Ф2-мс (1801007)</span>
            <span className="dot"></span>
            <span>тис. грн</span>
          </div>
        </div>

        <div className="fin-toolbar">
          <label>Звітний рік:&nbsp;
            <select className="auth-input fin-year" value={year} onChange={e => setYear(parseInt(e.target.value, 10))}>
              {[sysYear, sysYear - 1, sysYear - 2, sysYear - 3].map(y => <option key={y} value={y}>{y}</option>)}
            </select>
          </label>
          {canEdit && <button className="btn" onClick={recalc} title="Підтягнути авто-рядки з поточних даних ERP">↻ Перерахувати з ERP</button>}
          {canEdit && <button className="btn btn-primary" onClick={save} disabled={busy || saved}>{busy ? "Збереження…" : saved ? "Збережено ✓" : "Зберегти"}</button>}
        </div>

        {/* Шапка КОДИ */}
        <div className="fin-codes">
          <div><span className="fin-k">Підприємство</span><b>{co.name || "ТОВ «УКРБУДПРОЄКТ»"}</b></div>
          <div><span className="fin-k">ЄДРПОУ</span>{co.edrpou || "44531964"}</div>
          <div><span className="fin-k">КВЕД</span>71.12</div>
          <div><span className="fin-k">Адреса</span>{co.address || co.city || "65030, м. Одеса, вул. Палубна, 9"}</div>
          <div><span className="fin-k">Серед. к-сть прац.</span>
            {canEdit
              ? <input className="fin-in fin-in-wide" value={hdr.avgEmp == null ? "" : hdr.avgEmp} placeholder="11"
                       onChange={e => { setHdr(h => ({ ...h, avgEmp: e.target.value })); setSaved(false); }} />
              : (hdr.avgEmp || "—")}
          </div>
          <div><span className="fin-k">Звіт на</span>31.12.{year} р.</div>
        </div>

        {/* ФОРМА 1 */}
        <section className="section">
          <div className="section-head">
            <h2 className="section-h2">1. Баланс · Форма № 1-мс</h2>
            <span className="section-sub">{b1ok ? "Актив = Пасив ✓" : "Актив ≠ Пасив — перевірте рядки"}</span>
            <button className="btn btn-ghost btn-sm" onClick={() => copyForm(F1_ROWS, F1_COLS)}>Копіювати</button>
          </div>
          {renderTable(F1_ROWS, F1_COLS)}
          {!b1ok && <div className="auth-hint" style={{ color: "var(--late)" }}>Актив ({fmt(resolve("1300", "cur"))}) не дорівнює Пасиву ({fmt(resolve("1900", "cur"))}). Заповніть власний капітал / зобов'язання вручну.</div>}
        </section>

        {/* ФОРМА 2 */}
        <section className="section">
          <div className="section-head">
            <h2 className="section-h2">2. Звіт про фінансові результати · Форма № 2-мс</h2>
            <span className="section-sub">за {year} рік</span>
            <button className="btn btn-ghost btn-sm" onClick={() => copyForm(F2_ROWS, F2_COLS)}>Копіювати</button>
          </div>
          {renderTable(F2_ROWS, F2_COLS)}
          <div className="auth-hint"><b>2050 Собівартість</b> = усі прямі витрати (ЗП + ЄСВ + субпідряд/експертиза + виробничі ЗВВ + амортизація); <b>2165 Інші витрати</b> = адміністративні (офіс, ПЗ, зв'язок, банк). «Перерахувати з ERP» оновлює авто-рядки.</div>
        </section>

        <FinReportStyles />
      </div>
    );
  }

  function FinReportStyles() {
    return (
      <style>{`
        .fin-toolbar { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-bottom: 14px; }
        .fin-year { width: 100px; padding: 5px 8px; }
        .fin-codes { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px 18px; padding: 12px 14px; border: 1px solid var(--line, #e6e8eb); border-radius: 10px; margin-bottom: 16px; font-size: 13px; }
        .fin-codes .fin-k { display: block; font-size: 11px; color: var(--ink-3, #6b7280); }
        .fin-table td, .fin-table th { font-size: 13px; padding: 5px 8px; vertical-align: middle; }
        .fin-table .fin-code { color: var(--ink-3, #6b7280); text-align: center; }
        .fin-sec td { background: var(--bg-elev, #eef2f6); font-weight: 700; font-size: 13px; padding: 6px 8px; }
        .fin-h td { font-weight: 600; color: var(--ink-2, #3a4150); background: var(--bg-elev, #f6f8f9); }
        .fin-indent { padding-left: 26px !important; color: var(--ink-2, #3a4150); }
        .fin-bold td { font-weight: 600; }
        .fin-total td { border-top: 2px solid var(--line, #cdd3da); font-weight: 700; }
        .fin-in { width: 110px; text-align: right; padding: 3px 6px; font-size: 13px; border: 1px solid var(--line, #d7dde2); border-radius: 6px; background: var(--bg, #fff); color: inherit; font-variant-numeric: tabular-nums; }
        .fin-in-wide { width: 80px; text-align: left; }
        .fin-table .num-col { text-align: right; font-variant-numeric: tabular-nums; }
      `}</style>
    );
  }

  window.FinReportPage = FinReportPage;
})();
