/* volume-calcs-panel.jsx — UI калькуляторов объёмов в смете (KSH-552 / 556–560) */
(function () {
  const { useState, useMemo, useEffect } = React;
  const { Ic } = window;
  const { Button } = window.DesignSystem_9e0a09 || {};
  const VC = () => window.VolumeCalcs;

  const TABS = [
    { id: 'screed', label: 'Стяжка', issue: 'KSH-556' },
    { id: 'plaster', label: 'Штукатурка', issue: 'KSH-557' },
    { id: 'tile', label: 'Плитка', issue: 'KSH-558' },
    { id: 'flooring', label: 'Покрытия', issue: 'KSH-559' },
    { id: 'layout', label: 'Раскладка', issue: 'KSH-560' },
  ];

  function num(v, d) {
    const n = +v;
    return isFinite(n) ? n : d;
  }

  function Field({ label, children }) {
    return <div className="cc-vol-field"><label>{label}</label>{children}</div>;
  }

  function ResultBlock({ result, canApply, onApply, applied }) {
    if (!result) return null;
    return (
      <div className="cc-vol-result">
        <div className="cc-vol-kpi">
          <div><i>Объём работы</i><b>{String(result.workQty).replace('.', ',')} {result.unit}</b></div>
          {result.volumeM3 != null && <div><i>Объём смеси</i><b>{String(result.volumeM3).replace('.', ',')} м³</b></div>}
          {result.bags != null && <div><i>Мешков</i><b>{result.bags}</b></div>}
          {result.tiles != null && <div><i>Плиток</i><b>{result.tiles} шт</b></div>}
          {result.piecesWithWaste != null && <div><i>С запасом</i><b>{result.piecesWithWaste} шт</b></div>}
          {result.areaWithWaste != null && result.kind !== 'layout' && <div><i>С отходами</i><b>{String(result.areaWithWaste).replace('.', ',')} м²</b></div>}
          {result.underlayM2 > 0 && <div><i>Подложка</i><b>{String(result.underlayM2).replace('.', ',')} м²</b></div>}
        </div>
        <ul className="cc-vol-lines">
          {(result.lines || []).map((ln, i) => (
            <li key={i}>
              <span>{ln.name}{ln.detail ? <span className="meta"> · {ln.detail}</span> : null}</span>
              <b>{String(ln.qty).replace('.', ',')} {ln.unit}</b>
            </li>
          ))}
        </ul>
        <details className="cc-vol-assumptions">
          <summary>Допущения и единицы</summary>
          <ul>
            {(result.assumptions || []).map((a, i) => <li key={i}>{a}</li>)}
          </ul>
        </details>
        <div className="cc-vol-actions">
          {Button ? (
            <Button variant="primary" size="sm" disabled={!canApply} onClick={onApply}>
              Вставить в смету
            </Button>
          ) : (
            <button type="button" className="cc-vol-tab on" disabled={!canApply} onClick={onApply}>Вставить в смету</button>
          )}
          {applied && <span className="cc-vol-ok">Сохранено в смете · объём на работе каталога</span>}
        </div>
      </div>
    );
  }

  function ScreedForm({ areaDefault, onResult }) {
    const types = VC().SCREED_TYPES;
    const [areaM2, setArea] = useState(areaDefault);
    const [typeId, setType] = useState(types[0].id);
    const [thicknessMm, setTh] = useState(types[0].defaultMm);
    const [wastePct, setWaste] = useState(types[0].wastePct);
    const result = useMemo(() => VC().calcScreed({ areaM2, typeId, thicknessMm, wastePct }), [areaM2, typeId, thicknessMm, wastePct]);
    React.useEffect(() => { onResult(result, { areaM2, typeId, thicknessMm, wastePct }); }, [result]);
    const onType = (id) => {
      const t = VC().screedType(id);
      setType(id);
      setTh(t.defaultMm);
      setWaste(t.wastePct);
    };
    return (
      <div className="cc-vol-grid">
        <Field label="Площадь, м²"><input type="number" min={0} step={0.1} value={areaM2} onChange={(e) => setArea(num(e.target.value, 0))} /></Field>
        <Field label="Тип стяжки">
          <select value={typeId} onChange={(e) => onType(e.target.value)}>
            {types.map((t) => <option key={t.id} value={t.id}>{t.name}</option>)}
          </select>
        </Field>
        <Field label="Толщина, мм"><input type="number" min={1} step={1} value={thicknessMm} onChange={(e) => setTh(num(e.target.value, 1))} /></Field>
        <Field label="Отходы, %"><input type="number" min={0} max={50} step={1} value={wastePct} onChange={(e) => setWaste(num(e.target.value, 0))} /></Field>
      </div>
    );
  }

  function PlasterForm({ areaDefault, onResult }) {
    const types = VC().PLASTER_TYPES;
    const [areaM2, setArea] = useState(areaDefault);
    const [mixId, setMix] = useState(types[0].id);
    const [thicknessMm, setTh] = useState(types[0].defaultMm);
    const [wastePct, setWaste] = useState(types[0].wastePct);
    const result = useMemo(() => VC().calcPlaster({ areaM2, mixId, thicknessMm, wastePct }), [areaM2, mixId, thicknessMm, wastePct]);
    React.useEffect(() => { onResult(result, { areaM2, mixId, thicknessMm, wastePct }); }, [result]);
    const onMix = (id) => {
      const t = VC().plasterType(id);
      setMix(id);
      setTh(t.defaultMm);
      setWaste(t.wastePct);
    };
    return (
      <div className="cc-vol-grid">
        <Field label="Площадь стен/потолка, м²"><input type="number" min={0} step={0.1} value={areaM2} onChange={(e) => setArea(num(e.target.value, 0))} /></Field>
        <Field label="Тип смеси">
          <select value={mixId} onChange={(e) => onMix(e.target.value)}>
            {types.map((t) => <option key={t.id} value={t.id}>{t.name}</option>)}
          </select>
        </Field>
        <Field label="Толщина слоя, мм"><input type="number" min={1} step={1} value={thicknessMm} onChange={(e) => setTh(num(e.target.value, 1))} /></Field>
        <Field label="Отходы, %"><input type="number" min={0} max={50} step={1} value={wastePct} onChange={(e) => setWaste(num(e.target.value, 0))} /></Field>
      </div>
    );
  }

  function TileForm({ areaDefault, onResult }) {
    const [areaM2, setArea] = useState(areaDefault);
    const [surface, setSurface] = useState('floor');
    const [tileWmm, setW] = useState(600);
    const [tileHmm, setH] = useState(600);
    const [jointMm, setJ] = useState(3);
    const [wastePct, setWaste] = useState(7);
    const [packM2, setPack] = useState(1.44);
    React.useEffect(() => { setWaste(surface === 'walls' ? 10 : 7); }, [surface]);
    const result = useMemo(() => VC().calcTile({ areaM2, surface, tileWmm, tileHmm, jointMm, wastePct, packM2 }), [areaM2, surface, tileWmm, tileHmm, jointMm, wastePct, packM2]);
    React.useEffect(() => { onResult(result, { areaM2, surface, tileWmm, tileHmm, jointMm, wastePct, packM2 }); }, [result]);
    return (
      <div className="cc-vol-grid">
        <Field label="Площадь покрытия, м²"><input type="number" min={0} step={0.1} value={areaM2} onChange={(e) => setArea(num(e.target.value, 0))} /></Field>
        <Field label="Поверхность">
          <select value={surface} onChange={(e) => setSurface(e.target.value)}>
            <option value="floor">Пол</option>
            <option value="walls">Стены</option>
          </select>
        </Field>
        <Field label="Формат, ширина мм"><input type="number" min={50} step={1} value={tileWmm} onChange={(e) => setW(num(e.target.value, 50))} /></Field>
        <Field label="Формат, высота мм"><input type="number" min={50} step={1} value={tileHmm} onChange={(e) => setH(num(e.target.value, 50))} /></Field>
        <Field label="Шов, мм"><input type="number" min={0} step={0.5} value={jointMm} onChange={(e) => setJ(num(e.target.value, 0))} /></Field>
        <Field label="Отходы, %"><input type="number" min={0} max={50} step={1} value={wastePct} onChange={(e) => setWaste(num(e.target.value, 0))} /></Field>
        <Field label="М² в упаковке"><input type="number" min={0} step={0.01} value={packM2} onChange={(e) => setPack(num(e.target.value, 0))} /></Field>
      </div>
    );
  }

  function FlooringForm({ areaDefault, onResult }) {
    const types = VC().FLOORING_TYPES;
    const [areaM2, setArea] = useState(areaDefault);
    const [typeId, setType] = useState(types[0].id);
    const [wastePct, setWaste] = useState(types[0].wastePct);
    const [underlay, setUnderlay] = useState(true);
    const result = useMemo(() => VC().calcFlooring({ areaM2, typeId, wastePct, underlay }), [areaM2, typeId, wastePct, underlay]);
    React.useEffect(() => { onResult(result, { areaM2, typeId, wastePct, underlay }); }, [result]);
    const onType = (id) => {
      const t = VC().flooringType(id);
      setType(id);
      setWaste(t.wastePct);
      setUnderlay(!!t.underlay);
    };
    return (
      <div className="cc-vol-grid">
        <Field label="Площадь пола, м²"><input type="number" min={0} step={0.1} value={areaM2} onChange={(e) => setArea(num(e.target.value, 0))} /></Field>
        <Field label="Тип покрытия">
          <select value={typeId} onChange={(e) => onType(e.target.value)}>
            {types.map((t) => <option key={t.id} value={t.id}>{t.name}</option>)}
          </select>
        </Field>
        <Field label="Отходы, %"><input type="number" min={0} max={50} step={1} value={wastePct} onChange={(e) => setWaste(num(e.target.value, 0))} /></Field>
        <Field label="Подложка">
          <select value={underlay ? '1' : '0'} onChange={(e) => setUnderlay(e.target.value === '1')}>
            <option value="1">Да (+5 % нахлёст)</option>
            <option value="0">Нет</option>
          </select>
        </Field>
      </div>
    );
  }

  function LayoutPreview({ result }) {
    if (!result || !result.cells) return null;
    const pad = 8;
    const scale = 120; // px per meter in viewBox units
    const W = result.roomWm * scale + pad * 2;
    const H = result.roomHm * scale + pad * 2;
    return (
      <div className="cc-vol-preview" aria-label="Превью раскладки плитки">
        <svg viewBox={`0 0 ${W} ${H}`} role="img">
          <rect className="room" x={pad} y={pad} width={result.roomWm * scale} height={result.roomHm * scale} />
          {result.cells.map((c, i) => (
            <rect
              key={i}
              className={c.full ? 'full' : 'cut'}
              x={pad + c.x * scale}
              y={pad + c.y * scale}
              width={Math.max(0.5, c.w * scale)}
              height={Math.max(0.5, c.h * scale)}
              strokeWidth={1}
            />
          ))}
        </svg>
      </div>
    );
  }

  function LayoutForm({ areaDefault, onResult }) {
    const side = Math.max(1, Math.sqrt(areaDefault || 12));
    const patterns = VC().LAYOUT_PATTERNS;
    const [roomWm, setW] = useState(r2side(side));
    const [roomHm, setH] = useState(r2side(side * 1.2));
    const [tileWmm, setTw] = useState(600);
    const [tileHmm, setTh] = useState(600);
    const [jointMm, setJ] = useState(3);
    const [patternId, setPat] = useState(patterns[0].id);
    const [wastePct, setWaste] = useState(7);
    const result = useMemo(
      () => VC().calcTileLayout({ roomWm, roomHm, tileWmm, tileHmm, jointMm, patternId, wastePct }),
      [roomWm, roomHm, tileWmm, tileHmm, jointMm, patternId, wastePct],
    );
    React.useEffect(() => { onResult(result, { roomWm, roomHm, tileWmm, tileHmm, jointMm, patternId, wastePct }); }, [result]);
    return (
      <React.Fragment>
        <div className="cc-vol-grid">
          <Field label="Длина комнаты, м"><input type="number" min={0.3} step={0.01} value={roomWm} onChange={(e) => setW(num(e.target.value, 0.3))} /></Field>
          <Field label="Ширина комнаты, м"><input type="number" min={0.3} step={0.01} value={roomHm} onChange={(e) => setH(num(e.target.value, 0.3))} /></Field>
          <Field label="Плитка, ширина мм"><input type="number" min={50} step={1} value={tileWmm} onChange={(e) => setTw(num(e.target.value, 50))} /></Field>
          <Field label="Плитка, высота мм"><input type="number" min={50} step={1} value={tileHmm} onChange={(e) => setTh(num(e.target.value, 50))} /></Field>
          <Field label="Шов, мм"><input type="number" min={0} step={0.5} value={jointMm} onChange={(e) => setJ(num(e.target.value, 0))} /></Field>
          <Field label="Схема укладки">
            <select value={patternId} onChange={(e) => setPat(e.target.value)}>
              {patterns.map((p) => <option key={p.id} value={p.id}>{p.name}</option>)}
            </select>
          </Field>
          <Field label="Запас отходов, %"><input type="number" min={0} max={50} step={1} value={wastePct} onChange={(e) => setWaste(num(e.target.value, 0))} /></Field>
        </div>
        <LayoutPreview result={result} />
      </React.Fragment>
    );
  }

  function r2side(n) {
    return Math.round((+n || 1) * 100) / 100;
  }

  function VolumeCalcsPanel({ est, setEst, role, catalog, forceOpen, initialTab, canApplyOverride, applyHint }) {
    const api = VC();
    if (!api) return null;
    const C = window.Calc2;
    const canEdit = canApplyOverride != null
      ? !!canApplyOverride
      : !!(C && C.can && est && (C.can(role, 'qty', est.status) || C.can(role, 'manual', est.status) || role === 'super'));
    const areaDefault = Math.max(1, +(est && est.project && est.project.area) || 52);
    const wallDefault = Math.max(1, Math.round(areaDefault * 2.6));
    const [open, setOpen] = useState(!!forceOpen);
    const [tab, setTab] = useState(initialTab && TABS.some((t) => t.id === initialTab) ? initialTab : 'screed');
    const [bundle, setBundle] = useState({ result: null, inputs: null });
    const [flash, setFlash] = useState('');

    useEffect(() => { if (forceOpen) setOpen(true); }, [forceOpen]);
    useEffect(() => {
      if (initialTab && TABS.some((t) => t.id === initialTab)) setTab(initialTab);
    }, [initialTab]);

    const onResult = (result, inputs) => setBundle({ result, inputs });

    const apply = () => {
      if (!canEdit || !bundle.result || !est || !setEst) return;
      const next = api.applyToEstimate(est, catalog, bundle.result, { inputs: bundle.inputs, author: (C && C.ROLE_META && C.ROLE_META[role] || {}).name || role });
      setEst(next);
      setFlash(bundle.result.kind);
      try { window.setTimeout(() => setFlash((f) => (f === bundle.result.kind ? '' : f)), 2500); } catch (e) {}
    };

    const tabMeta = TABS.find((t) => t.id === tab) || TABS[0];
    const canApply = canEdit && !!(bundle.result && bundle.result.workQty > 0);

    return (
      <div className={'cc-vol' + (open ? ' open' : '') + (forceOpen ? ' cc-vol-forced' : '')}>
        <div className="cc-vol-head" onClick={() => { if (!forceOpen) setOpen((o) => !o); }} role="button" tabIndex={0}
          onKeyDown={(e) => { if (forceOpen) return; if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); setOpen((o) => !o); } }}>
          <span className="cc-vol-ic"><Ic n="calculator" s={18} /></span>
          <div>
            <div className="cc-vol-title">Калькуляторы объёмов</div>
            <div className="cc-vol-sub">Стяжка · штукатурка · плитка · покрытия · раскладка · вставка в смету</div>
          </div>
          {!forceOpen && <span className="cc-vol-chev"><Ic n="chevron-down" s={16} /></span>}
        </div>
        <div className="cc-vol-body">
          <div className="cc-vol-tabs" role="tablist">
            {TABS.map((t) => (
              <button key={t.id} type="button" role="tab" aria-selected={tab === t.id} className={'cc-vol-tab' + (tab === t.id ? ' on' : '')}
                onClick={() => { setTab(t.id); setFlash(''); }}>
                {t.label}
              </button>
            ))}
          </div>
          <div style={{ fontSize: 12, color: 'var(--text-tertiary)', marginBottom: 10 }}>{tabMeta.issue}</div>
          {tab === 'screed' && <ScreedForm areaDefault={areaDefault} onResult={onResult} />}
          {tab === 'plaster' && <PlasterForm areaDefault={wallDefault} onResult={onResult} />}
          {tab === 'tile' && <TileForm areaDefault={Math.min(areaDefault, 12)} onResult={onResult} />}
          {tab === 'flooring' && <FlooringForm areaDefault={areaDefault} onResult={onResult} />}
          {tab === 'layout' && <LayoutForm areaDefault={Math.min(areaDefault, 12)} onResult={onResult} />}
          <ResultBlock
            result={bundle.result}
            canApply={canApply}
            onApply={apply}
            applied={flash === (bundle.result && bundle.result.kind)}
          />
          {!canApply && applyHint && bundle.result && bundle.result.workQty > 0 ? (
            <p className="cc-vol-hint" style={{ fontSize: 12, color: 'var(--text-tertiary)', marginTop: 8 }}>{applyHint}</p>
          ) : null}
        </div>
      </div>
    );
  }

  window.VolumeCalcsPanel = VolumeCalcsPanel;
})();
