/* ctor-path.jsx — «Путь сделки до сметы» в Конструкторе (KSH-480): карточка на главной и окно по стадиям.
   Данные — window.DealPath.build() (lk/deal-path.js): стадии с текстами, посчитанными из настроек.
   CtorPathCard — цепочка стадий на главной (как «Фазы каталога»); стадия или ↗ открывает окно.
   CtorPathModal — широкое окно (LKW.Modal): линия стадий, переключатель «С дизайн-проектом / Без», по стадии — что происходит,
   кто что делает, что видит клиент (макет его главной), когда открывается следующая стадия, когда сделка застряла и
   какие разделы Конструктора ею управляют. ← и → листают стадии. Адрес окна — #path=<стадия> (ссылка и скриншоты).
   «Глазами клиента» — всплывающее окно с настоящим кабинетом клиента на пробной сделке (lk/client-sandbox.html), открывается на стадии,
   выбранной здесь (ветка без ДП; стадии ДП — с заявки). Смета собирается мастером из каталога и черновика Конструктора.
   «×» и Esc внутри окна присылают client-sandbox:close; Esc здесь и клик по затемнению закрывают только его, не окно пути.
   Префикс cdp: общий top-level scope с другими ctor-*.jsx. Exports on window: CtorPathCard, CtorPathModal, cdpReadHash */
const { useEffect: cdpUseEffect, useRef: cdpUseRef, useState: cdpUseState } = React;

/* #path или #path=<id стадии> → id ('' — первая стадия); null — окна в адресе нет */
function cdpReadHash() {
  const m = /^#path(?:=([\w-]+))?$/.exec(window.location.hash || '');
  return m ? (m[1] || '') : null;
}
function cdpWriteHash(id) {
  try {
    const url = window.location.pathname + window.location.search + (id == null ? '' : '#path' + (id ? '=' + id : ''));
    window.history.replaceState(null, '', url);
  } catch (e) { /* адрес — удобство, без него окно работает */ }
}

function CtorPathCard({ path, onOpen }) {
  const W = window.LKW;
  const list = path.design;
  return (
    <section className="cv-w c2-phases cdp-card" aria-labelledby="cdp-card-h">
      <W.WHead id="cdp-card-h" title="Путь сделки до сметы" sub={' · ' + path.plain.length + ' стадий, с дизайн-проектом ' + list.length} text="Как устроено" onOpen={() => onOpen('')} />
      <ol className="c2-chain cdp-chain" style={{ gridTemplateColumns: 'repeat(' + list.length + ', minmax(0, 1fr))' }}>{list.map((s) => (
        <li key={s.id} className={s.design ? 'is-dp' : undefined}>
          <button type="button" className="c2-rb" onClick={() => onOpen(s.id)}>
            <span className="c2-pn">{s.n}{s.design ? ' · с ДП' : ''}</span>
            <span className="c2-pt">{s.title}</span>
            <span className="c2-ps">{s.owner === 'client' ? 'ход клиента' : 'ведёт ' + s.ownerL.toLowerCase()}</span>
          </button>
        </li>))}</ol>
    </section>);
}

/* «Видит клиент»: главная его кабинета на этой стадии — где он сейчас, главное действие и мини-путь своей ветки */
function CdpClient({ s, steps }) {
  const cur = steps.findIndex((x) => x.id === s.client.step);
  const title = (steps[cur] || {}).title || '';
  // на экране — главное действие кнопкой или строка статуса; остальные состояния стадии — подписью ниже
  const shown = s.client.action || s.client.now;
  const other = s.client.texts.filter((t) => t !== shown);
  return (
    <section className="cdp-sec" aria-labelledby="cdp-cl-h">
      <h3 className="cdp-sh" id="cdp-cl-h">Видит клиент</h3>
      <div className="cdp-screen" aria-label="Главная кабинета клиента">
        <div className="cdp-scard">
          <span className="lab">Где вы сейчас</span>
          <span className="t">{title}</span>
          {s.client.action ? <span className="cdp-sbtn">{s.client.action}</span> : <span className="s">{s.client.now}</span>}
        </div>
        <ol className="cdp-spath">{steps.map((x, i) => (
          <li key={x.id} className={i < cur ? 'is-done' : i === cur ? 'is-cur' : ''} aria-current={i === cur ? 'step' : undefined}>
            <i aria-hidden="true" /><span>{x.title}</span>
          </li>))}</ol>
      </div>
      <p className="cdp-p">{s.client.sees}</p>
      {other.length ? <p className="cdp-p cdp-mute">Ещё на этой стадии: {other.map((t) => '«' + t + '»').join(', ')}.</p> : null}
    </section>);
}

/* «Глазами клиента» поверх окна пути; своя память во фрейме — настоящие сделки и Конструктор она не меняет */
function CdpSandbox({ at, onClose }) {
  cdpUseEffect(() => {
    const m = (e) => { if (e.data && e.data.type === 'client-sandbox:close') onClose(); };
    // Esc ловим раньше окна пути (LKW.Modal слушает document на всплытии): закрывается только это окно
    const k = (e) => { if (e.key === 'Escape') { e.stopPropagation(); onClose(); } };
    window.addEventListener('message', m);
    document.addEventListener('keydown', k, true);
    return () => { window.removeEventListener('message', m); document.removeEventListener('keydown', k, true); };
  }, []);
  return ReactDOM.createPortal(
    <React.Fragment>
      <div className="cdp-sbx-scrim" onClick={onClose} />
      <div className="cdp-sbx" role="dialog" aria-modal="true" aria-label="Глазами клиента">
        <iframe title="Глазами клиента" src={'lk/client-sandbox.html?from=ctor&drafts=1&at=' + encodeURIComponent(at)} />
      </div>
    </React.Fragment>, document.body);
}

function CtorPathModal({ path, at, design, onDesign, onAt, onClose, onGo, canGo }) {
  const W = window.LKW;
  const list = design ? path.design : path.plain;
  // стадии ДП нет в ветке без дизайн-проекта — открываем ближайшую следующую общую
  const idx = Math.max(0, list.findIndex((x) => x.id === at) >= 0 ? list.findIndex((x) => x.id === at)
    : list.findIndex((x) => path.design.findIndex((y) => y.id === x.id) > path.design.findIndex((y) => y.id === at)));
  const s = list[idx];
  const prev = list[idx - 1], next = list[idx + 1];
  cdpUseEffect(() => {
    const k = (e) => {
      const t = e.target;
      if (t && (t.isContentEditable || /^(INPUT|TEXTAREA|SELECT)$/.test(t.tagName))) return;
      if (e.key === 'ArrowLeft' && prev) { e.preventDefault(); onAt(prev.id); }
      if (e.key === 'ArrowRight' && next) { e.preventDefault(); onAt(next.id); }
    };
    document.addEventListener('keydown', k);
    return () => document.removeEventListener('keydown', k);
  }, [prev && prev.id, next && next.id]);
  // на телефоне линия стадий листается вбок: текущая стадия — в видимой части
  const rail = cdpUseRef(null);
  cdpUseEffect(() => {
    const el = rail.current && rail.current.querySelector('[aria-current="step"]');
    if (el && el.scrollIntoView && rail.current.scrollWidth > rail.current.clientWidth) el.scrollIntoView({ block: 'nearest', inline: 'nearest' });
  }, [s.id, design]);
  const can = (id) => !canGo || canGo(id);
  const [sbx, setSbx] = cdpUseState(false);
  const toggle = (
    <React.Fragment>
      <button type="button" className="cdp-try" onClick={() => setSbx(true)}>Глазами клиента</button>
      <div className="cdp-seg" role="group" aria-label="Ветка сделки">
        <button type="button" aria-pressed={design ? 'true' : 'false'} onClick={() => onDesign(true)}>С дизайн-проектом</button>
        <button type="button" aria-pressed={design ? 'false' : 'true'} onClick={() => onDesign(false)}>Без</button>
      </div>
    </React.Fragment>);
  return (
    <W.Modal title="Путь сделки до сметы" sub="От заявки до сметы в кабинете клиента" size="wide" className="cdp-mod" onClose={onClose} head={toggle}>
      <ol className="cdp-rail" ref={rail} style={{ gridTemplateColumns: 'repeat(' + list.length + ', minmax(0, 1fr))' }}>{list.map((x, i) => (
        <li key={x.id} className={(i < idx ? 'is-done' : i === idx ? 'is-cur' : '') + (x.design ? ' is-dp' : '')}>
          <button type="button" aria-current={i === idx ? 'step' : undefined} onClick={() => onAt(x.id)}>
            <span className="n">{x.n}</span>
            <span className="t">{x.title}</span>
            <span className="o">{x.ownerL.toLowerCase()}</span>
          </button>
        </li>))}</ol>
      <div className="cdp-body" key={s.id}>
        <div className="cdp-main">
          <p className="cdp-eyebrow">Стадия {s.n} из {list.length} · у менеджера в «Сделках» колонка «{s.column}»</p>
          <h2 className="cdp-h">{s.title}</h2>
          <p className="cdp-lead">{s.lead}</p>
          <section className="cdp-sec" aria-labelledby="cdp-who-h">
            <h3 className="cdp-sh" id="cdp-who-h">Кто что делает и видит</h3>
            <ul className="cdp-who">{s.who.map((w) => (
              <li key={w.role}><b>{w.label}</b><span>{w.does}</span></li>))}</ul>
          </section>
          <div className="cdp-two">
            <section className="cdp-sec" aria-labelledby="cdp-next-h">
              <h3 className="cdp-sh" id="cdp-next-h">{next ? 'Стадия «' + next.title + '» открывается, когда' : 'Дальше'}</h3>
              <ul className="cdp-list">{s.next.map((t) => <li key={t}><W.Ic n="check" s={15} /><span>{t}</span></li>)}</ul>
            </section>
            <section className="cdp-sec" aria-labelledby="cdp-stuck-h">
              <h3 className="cdp-sh" id="cdp-stuck-h">Сделка застряла, если</h3>
              <ul className="cdp-list is-stuck">{s.stuck.map((t) => <li key={t}><W.Ic n="clock" s={15} /><span>{t}</span></li>)}</ul>
            </section>
          </div>
        </div>
        <aside className="cdp-side">
          <CdpClient s={s} steps={path.clientSteps(design)} />
          {s.settings.length ? <section className="cdp-sec" aria-labelledby="cdp-set-h">
            <h3 className="cdp-sh" id="cdp-set-h">Чем управлять в Конструкторе</h3>
            <div className="cdp-set">{s.settings.map((x) => (
              can(x.go)
                ? <button key={x.go + x.label} type="button" className="cdp-sr" onClick={() => { onClose(); onGo(x.go); }}>
                  <span className="tx"><span className="t">{x.label}</span><span className="lab">{x.value}</span></span><W.Ic n="ne" s={14} /></button>
                : <div key={x.go + x.label} className="cdp-sr"><span className="tx"><span className="t">{x.label}</span><span className="lab">{x.value}</span></span></div>))}</div>
          </section> : null}
        </aside>
      </div>
      <div className="cdp-foot">
        {prev ? <button type="button" className="cdp-step" onClick={() => onAt(prev.id)}><span aria-hidden="true">←</span> {prev.title}</button> : <span />}
        {next ? <button type="button" className="cdp-step" onClick={() => onAt(next.id)}>{next.title} <span aria-hidden="true">→</span></button> : null}
      </div>
      {sbx ? <CdpSandbox at={path.plain.some((x) => x.id === s.id) ? s.id : 'lead'} onClose={() => setSbx(false)} /> : null}
    </W.Modal>);
}

Object.assign(window, { CtorPathCard, CtorPathModal, CdpSandbox, cdpReadHash, cdpWriteHash });
