/* estimate-view.jsx — общий компонент сметы проекта для всех кабинетов (спека 2026-10-23-client-lk-v2-design.md §4, DESIGN.md §7).
   Данные — ProjectStore.views.projectEstimate(project, lens): фаза → этап → работы + материалы этапа.
   Режим просмотра: клиент (lens client) и команда — прораб, офис (lens team, + «кто делает» и закупка).
   Порядок колонок, нумерация фаз «/00», формат денег и статусы — одинаковые везде; отличается только набор колонок.
   Зависит только от React и window.ProjectStore; стили — estimate-view.css (всё под .pe). */
(function () {
  const rub = (n) => (Math.round(n) || 0).toLocaleString('ru-RU') + ' ₽';
  const plural = (n, a, b, c) => { const m = Math.abs(n) % 100, k = m % 10; return m > 10 && m < 20 ? c : k > 1 && k < 5 ? b : k === 1 ? a : c; };
  const qtyR = (q) => (Math.round((+q || 0) * 100) / 100).toLocaleString('ru-RU');
  const PAY_L = { done: 'оплачено', check: 'оплата на проверке', due: 'счёт выставлен', overdue: 'счёт просрочен' };
  const W_TONE = { done: 'done', progress: 'prog', review: 'wait', returned: 'prog' };
  const S_TONE = { done: 'done', progress: 'prog' };

  function Pill({ tone, children }) { return <span className={'pe-pill' + (tone ? ' is-' + tone : '')}>{children}</span>; }

  // quiet — фаза закрыта целиком: статус «закрыт» уже сказан у фазы, у этапов его не повторяем
  function StageBlock({ st, team, open, onToggle, quiet }) {
    const n = st.works.length;
    return (
      <div className={'pe-st' + (open ? ' open' : '') + (st.status === 'done' ? ' is-done' : '')}>
        <button type="button" className="pe-sh" aria-expanded={open} onClick={onToggle}>
          <span className="pe-sn">{st.name}<span className="pe-mut"> · {n ? n + ' ' + plural(n, 'работа', 'работы', 'работ') : 'только материалы'}{st.mats.length ? ' · ' + st.mats.length + ' мат.' : ''}</span></span>
          <span className="pe-sr">{n > 0 && team && !quiet && <Pill tone={S_TONE[st.status]}>{st.statusL}</Pill>}<span className="pe-num">{rub(st.sum + st.matSum)}</span><span className="pe-chev" aria-hidden="true"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M6 9l6 6 6-6" /></svg></span></span>
        </button>
        {open && <div className="pe-sb">
          {n > 0 && <div className="pe-t">
            <div className="pe-r pe-hd"><span>Работа</span><span className="pe-q">Кол-во</span><span className="pe-p">Цена</span><span className="pe-s">Сумма</span><span className="pe-x">Статус</span></div>
            {st.works.map((w) => (
              <div key={w.id} className={'pe-r' + (!team && w.status === 'done' ? ' is-acc' : '')}>
                <span className="pe-n">{w.name}{team && w.who ? <span className="pe-mut"> · {w.sub ? 'подрядчик: ' : ''}{w.who}</span> : null}</span>
                <span className="pe-q pe-num">{qtyR(w.qty)}{w.unit ? ' ' + w.unit : ''}</span>
                <span className="pe-p pe-num">{rub(w.unitPrice)}</span>
                <span className="pe-s pe-num">{rub(w.sum)}</span>
                {/* клиенту ход работ показывают «Этапы»: в смете только тихая отметка о принятой работе, без «впереди» и «в работе» (KSH-469) */}
                <span className="pe-x">{team ? <Pill tone={W_TONE[w.status]}>{w.statusL}</Pill> : w.status === 'done' ? <span className="pe-acc">✓ принята</span> : null}</span>
              </div>))}
          </div>}
          {st.mats.length > 0 && <div className="pe-t pe-mt">
            <div className="pe-r pe-hd pe-mh"><span>Материалы этапа</span><span className="pe-q">Кол-во</span><span className="pe-p" /><span className="pe-s">{rub(st.matSum)}</span><span className="pe-x" /></div>
            {st.mats.map((m) => <MatRow key={m.id} m={m} team={team} />)}
          </div>}
          {st.start && <div className="pe-mut pe-dates">Сроки этапа: {st.start}{st.end && st.end !== st.start ? ' – ' + st.end : ''}</div>}
        </div>}
      </div>);
  }

  function MatRow({ m, team }) {
    const tone = m.approval === 'pending' ? 'wait' : m.approval === 'approved' ? 'done' : m.approval === 'rejected' ? 'prog' : '';
    return (
      <div className="pe-r pe-rm">
        <span className="pe-n pe-mn">{m.cover ? <img className="pe-th" src={m.cover} alt="" loading="lazy" /> : <span className="pe-th" aria-hidden="true" />}
          <span>{m.name}{m.replacedFrom ? <span className="pe-mut"> · вместо {m.replacedFrom}</span> : null}{team && m.procL ? <span className="pe-mut"> · {m.procL}</span> : null}</span></span>
        <span className="pe-q pe-num">{qtyR(m.qty)}{m.unit ? ' ' + m.unit : ''}</span>
        <span className="pe-p" />
        <span className="pe-s pe-num">{rub(m.sum)}</span>
        <span className="pe-x">{m.approval ? <Pill tone={tone}>{m.approvalL}</Pill> : null}</span>
      </div>);
  }

  // project — проект ProjectStore; lens — 'client' | 'team'; note — подпись под итогом (например, про аванс и оплату по фазам);
  // main — свой узел вместо фаз в .pe-main (вид «По комнатам» клиента): итоги справа остаются; без него разметка прежняя
  function ProjectEstimate({ project, lens, note, main }) {
    const P = window.ProjectStore;
    const e = P && P.views.projectEstimate ? P.views.projectEstimate(project, lens) : null;
    const [open, setOpen] = React.useState(() => {
      // по умолчанию раскрыт этап, который идёт сейчас
      const o = {}; if (e) { const cur = e.phases.flatMap((ph) => ph.stages).find((s) => s.status === 'progress'); if (cur) o[cur.id] = true; }
      return o;
    });
    if (!e) return <div className="pe pe-empty">Смета появится, когда проект будет создан из согласованной сметы.</div>;
    const team = e.lens === 'team';
    const all = e.phases.flatMap((ph) => ph.stages);
    const allOpen = all.length > 0 && all.every((s) => open[s.id]);
    const t = e.totals;
    // pe-c — контейнер: раскладка зависит от ширины места (окно клиента, страница прораба, ящик сделки), а не экрана
    return (
      <div className="pe-c"><div className="pe">
        <div className="pe-main">
          {main || <React.Fragment>
          <div className="pe-bar">
            <span className="pe-mut">{e.phases.length} {plural(e.phases.length, 'фаза', 'фазы', 'фаз')} · {all.length} {plural(all.length, 'этап', 'этапа', 'этапов')}</span>
            <button type="button" className="pe-lnk" onClick={() => setOpen(allOpen ? {} : Object.fromEntries(all.map((s) => [s.id, true])))}>{allOpen ? 'Свернуть все' : 'Развернуть все'}</button>
          </div>
          {e.phases.map((ph) => { const closed = ph.stages.length > 0 && ph.stages.every((s) => s.status === 'done'); return (
            <section key={ph.idx} className={'pe-ph' + (closed ? ' is-done' : '')}>
              <div className="pe-phh">
                <span><span className="pe-no">{ph.no}</span> {ph.name}</span>
                <span className="pe-sr">{closed && ph.pay !== 'done' && <Pill tone="done">закрыта</Pill>}{ph.pay && PAY_L[ph.pay] && <Pill tone={ph.pay === 'done' ? 'done' : ph.pay === 'overdue' ? 'prog' : 'wait'}>{closed && ph.pay === 'done' ? 'закрыта · оплачена' : PAY_L[ph.pay]}</Pill>}<span className="pe-num">{rub(ph.sum + ph.matSum)}</span></span>
              </div>
              {ph.stages.map((st) => <StageBlock key={st.id} st={st} team={team} open={!!open[st.id]} onToggle={() => setOpen({ ...open, [st.id]: !open[st.id] })} quiet={closed} />)}
            </section>); })}
          {e.unstaged.length > 0 && <section className="pe-ph">
            <div className="pe-phh"><span>Материалы без этапа</span><span className="pe-num">{rub(e.unstagedSum)}</span></div>
            <div className="pe-t pe-mt">{e.unstaged.map((m) => <MatRow key={m.id} m={m} team={team} />)}</div>
          </section>}
          {e.changes.length > 0 && <section className="pe-ph">
            <div className="pe-phh"><span>История изменений</span><span className="pe-num">{t.changes ? (t.changes > 0 ? '+' : '') + rub(t.changes) : ''}</span></div>
            {e.changes.map((c) => <div key={c.id} className="pe-line"><span>{c.title}<span className="pe-mut"> · согласовано{c.at ? ' ' + c.at : ''}</span></span><span className="pe-num">{c.sum ? (c.sum > 0 ? '+' : '') + rub(c.sum) : ''}</span></div>)}
          </section>}
          </React.Fragment>}
        </div>
        <aside className="pe-tot">
          <div className="pe-mut">Итого по смете</div>
          <div className="pe-big pe-num">{rub(t.total)}</div>
          <div className="pe-line"><span>Работы</span><span className="pe-num">{rub(t.works)}</span></div>
          <div className="pe-line"><span>Материалы</span><span className="pe-num">{rub(t.materials)}</span></div>
          {t.discount > 0 && <div className="pe-line"><span>Скидка</span><span className="pe-num">−{rub(t.discount)}</span></div>}
          {t.changes !== 0 && <div className="pe-line"><span>Допсоглашения</span><span className="pe-num">{t.changes > 0 ? '+' : ''}{rub(t.changes)}</span></div>}
          <div className="pe-line pe-paid"><span>Оплачено</span><span className="pe-num">{rub(t.paid)}</span></div>
          {t.check > 0 && <div className="pe-line"><span>На проверке у бухгалтерии</span><span className="pe-num">{rub(t.check)}</span></div>}
          <div className="pe-line"><span>Осталось</span><span className="pe-num">{rub(t.left)}</span></div>
          <div className="pe-bar-p" aria-hidden="true"><i style={{ width: (t.total ? Math.min(100, Math.round((t.paid / t.total) * 100)) : 0) + '%' }} /></div>
          {note && <div className="pe-mut pe-note">{note}</div>}
        </aside>
      </div></div>);
  }

  window.ProjectEstimate = ProjectEstimate;
})();
