/* ctor-publish.jsx — модал публикации с diff + слой аннотаций (связи с /calculator) */
const { useState: pbUseState } = React;

const GROUP_META = {
  hierarchy: { label: 'Иерархия', icon: '🗂' },
  roles: { label: 'Роли', icon: '🎭' },
  foremen: { label: 'Прорабы', icon: '👷' },
  presets: { label: 'Пресеты', icon: '🧩' },
  packages: { label: 'Пакеты услуг', icon: '📦' },
};
const FIELD_RU = {
  name: 'название', color: 'цвет', cond: 'условие', note: 'note', days: 'дни', pause: 'простой',
  role: 'роль', inc: 'включение', level: 'уровень', abbr: 'код', brigade: 'бригада', durationMul: 'множитель',
  phone: 'телефон', visibility: 'видимость', scope: 'scope', grade: 'grade', hasDesignProcess: 'дизайн-процесс',
  requiresDesignPhase: 'дизайн-фаза', excludeSlugs: 'исключения', includePhaseIds: 'привязка фаз',
  steps: 'шаги', active: 'активность', icon: 'иконка', desc: 'описание',
};

function DiffGroup({ gkey, g }) {
  const [open, setOpen] = pbUseState(true);
  const total = g.added.length + g.removed.length + g.modified.length;
  if (!total) return null;
  const m = GROUP_META[gkey];
  return (
    <div style={{ border: '.5px solid #ece5da', borderRadius: 12, overflow: 'hidden' }}>
      <button onClick={() => setOpen((o) => !o)} style={{
        display: 'flex', alignItems: 'center', gap: 10, width: '100%', padding: '11px 14px', border: 'none',
        background: '#fafafb', cursor: 'pointer', fontFamily: 'inherit', textAlign: 'left',
      }}>
        <span style={{ ...ctorStyles.iconBtnSm, color: '#8a817a', transform: open ? 'rotate(90deg)' : 'none', transition: 'transform .15s', width: 18, height: 18 }}>{Icon.chevron}</span>
        <span style={{ fontSize: 14, fontWeight: 600, color: '#1a1714', flex: 1 }}>{m.label}</span>
        {g.added.length > 0 && <Tag color="#5aad6e" bg="#f0fdf4">+{g.added.length}</Tag>}
        {g.modified.length > 0 && <Tag color="#92620a" bg="#fffbeb">~{g.modified.length}</Tag>}
        {g.removed.length > 0 && <Tag color="#d05858" bg="#fde8e8">−{g.removed.length}</Tag>}
      </button>
      {open && (
        <div style={{ padding: '6px 14px 12px', display: 'flex', flexDirection: 'column', gap: 2 }}>
          {g.added.map((n) => <DiffRow key={'a' + n.id} kind="add" node={n} />)}
          {g.modified.map((n) => <DiffRow key={'m' + n.id} kind="mod" node={n} />)}
          {g.removed.map((n) => <DiffRow key={'r' + n.id} kind="rem" node={n} />)}
        </div>
      )}
    </div>
  );
}
function Tag({ children, color, bg }) {
  return <span style={{ fontSize: 11, fontWeight: 700, color, background: bg, padding: '2px 8px', borderRadius: 980, fontVariantNumeric: 'tabular-nums' }}>{children}</span>;
}
function DiffRow({ kind, node }) {
  const meta = { add: { c: '#5aad6e', s: '+', l: 'добавлено' }, mod: { c: '#92620a', s: '~', l: 'изменено' }, rem: { c: '#d05858', s: '−', l: 'удалено' } }[kind];
  return (
    <div style={{ display: 'flex', alignItems: 'baseline', gap: 9, padding: '5px 4px' }}>
      <span style={{ color: meta.c, fontWeight: 700, fontSize: 13, width: 12, flexShrink: 0, textAlign: 'center' }}>{meta.s}</span>
      <div style={{ flex: 1, minWidth: 0 }}>
        <span style={{ fontSize: 13, color: '#1a1714' }}>{node.label}</span>
        {node.parent && <span style={{ fontSize: 11.5, color: '#a89e92' }}> · {node.parent}</span>}
        {kind === 'mod' && node.changedKeys && (
          <span style={{ fontSize: 11.5, color: meta.c, marginLeft: 6 }}>
            {node.changedKeys.map((k) => FIELD_RU[k] || k).join(', ')}
          </span>
        )}
      </div>
    </div>
  );
}

function PublishModal({ diff, blockers, version, onPublish, onClose }) {
  const t = diff.totals;
  const hasBlockers = blockers && blockers.length > 0;
  const summaryParts = [];
  if (t.added) summaryParts.push(`+${t.added} ${plural(t.added, 'узел', 'узла', 'узлов')}`);
  if (t.fields) summaryParts.push(`~${t.fields} ${plural(t.fields, 'поле', 'поля', 'полей')}`);
  if (t.removed) summaryParts.push(`−${t.removed} удалено`);

  return (
    <div style={ctorStyles.modalBackdrop} onClick={onClose}>
      <div style={{ ...ctorStyles.modal, width: 'min(560px, 100%)', maxHeight: '86vh', display: 'flex', flexDirection: 'column', padding: 0 }} onClick={(e) => e.stopPropagation()} className="ctor-fade">
        {/* head */}
        <div style={{ padding: '24px 28px 16px', borderBottom: '.5px solid #f0ece5' }}>
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
            <h3 style={{ fontSize: 20, fontWeight: 600, letterSpacing: '-.02em', color: '#1a1714', margin: 0 }}>Опубликовать изменения</h3>
            <button onClick={onClose} style={{ ...ctorStyles.iconBtn, color: '#8a817a' }}>{Icon.x}</button>
          </div>
          <p style={{ fontSize: 14, color: '#8a817a', margin: '8px 0 0', lineHeight: 1.5 }}>
            {summaryParts.length ? <>Будет опубликовано: <strong style={{ color: '#1a1714' }}>{summaryParts.join(' · ')}</strong>. Текущая версия каталога — v{version}, станет v{version + 1}.</> : 'Нет изменений для публикации.'}
          </p>
        </div>

        {/* body */}
        <div style={{ padding: '16px 28px', overflowY: 'auto', flex: 1, display: 'flex', flexDirection: 'column', gap: 10 }}>
          {hasBlockers && (
            <div style={{ background: '#fde8e8', border: '.5px solid #f5c4c4', borderRadius: 12, padding: '12px 14px' }}>
              <div style={{ fontSize: 13, fontWeight: 600, color: '#f04e62', marginBottom: 6 }}>Публикация заблокирована</div>
              <ul style={{ margin: 0, paddingLeft: 18, color: '#a8362f', fontSize: 12.5, lineHeight: 1.6 }}>
                {blockers.map((b, i) => <li key={i}>{b}</li>)}
              </ul>
            </div>
          )}
          {!hasBlockers && t.changes === 0 && (
            <div style={{ fontSize: 13.5, color: '#8a817a', textAlign: 'center', padding: '24px 0' }}>Черновик совпадает с опубликованной версией.</div>
          )}
          {Object.keys(diff.groups).map((gk) => <DiffGroup key={gk} gkey={gk} g={diff.groups[gk]} />)}

          {t.changes > 0 && (
            <div style={{ display: 'flex', gap: 9, alignItems: 'flex-start', background: '#fdf8ee', border: '.5px solid #f3e4c5', borderRadius: 12, padding: '11px 14px', marginTop: 4 }}>
              <span style={{ fontSize: 14 }}>⚠️</span>
              <span style={{ fontSize: 12.5, color: '#a1761f', lineHeight: 1.5 }}>Активные сметы в работе не изменятся. Новые расчёты в калькуляторе получат версию v{version + 1}.</span>
            </div>
          )}
        </div>

        {/* actions */}
        <div style={{ padding: '16px 28px 22px', borderTop: '.5px solid #f0ece5', display: 'flex', gap: 10, justifyContent: 'flex-end' }}>
          <button onClick={onClose} style={ctorStyles.btnGhost}>Отмена</button>
          <button onClick={onPublish} disabled={hasBlockers || t.changes === 0}
            style={{ ...ctorStyles.btnPrimary, opacity: (hasBlockers || t.changes === 0) ? 0.4 : 1, cursor: (hasBlockers || t.changes === 0) ? 'not-allowed' : 'pointer' }}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M4 14.899A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242"></path><line x1="12" y1="12" x2="12" y2="21"></line><polyline points="16 16 12 12 8 16"></polyline></svg>
            Опубликовать v{version + 1}
          </button>
        </div>
      </div>
    </div>
  );
}

function plural(n, one, few, many) {
  const m10 = n % 10, m100 = n % 100;
  if (m10 === 1 && m100 !== 11) return one;
  if (m10 >= 2 && m10 <= 4 && (m100 < 10 || m100 >= 20)) return few;
  return many;
}

/* ---------- Annotation layer — связи конструктора с другими экранами ---------- */
const FLOW = [
  { t: 'Конструктор', s: 'publish → версия каталога', c: '#e8793a', strong: true },
  { t: 'Заметки проекта', s: 'syncProjectNotes → треды на узлах', c: '#d05858' },
  { t: 'Публичный /calculator', s: 'chips пресетов public', c: '#5aad6e' },
  { t: 'Lead «Получить расчёт»', s: 'заявка с сайта', c: '#92620a' },
  { t: 'Менеджер · new-calc', s: 'picker пресетов + команда', c: '#7c3aed' },
  { t: 'Проект · Смета', s: 'snapshot дерева estimate-lines', c: '#e8793a' },
  { t: 'ЛК всех ролей', s: 'заметки + ответы в тредах', c: '#d05858' },
  { t: 'Прораб · Kanban', s: 'generateOrderTree()', c: '#1a1714' },
];
function AnnotationLayer({ onClose }) {
  return (
    <div style={{ position: 'fixed', right: 20, bottom: 20, zIndex: 180, width: 'min(360px, calc(100vw - 40px))' }} className="ctor-fade">
      <div style={{ background: '#fff', borderRadius: 18, boxShadow: '0 16px 48px rgba(0,0,0,.16), 0 0 0 .5px rgba(0,0,0,.06)', overflow: 'hidden' }}>
        <div style={{ padding: '15px 18px', borderBottom: '.5px solid #f0ece5', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
          <div>
            <div style={{ fontSize: 14.5, fontWeight: 600, color: '#1a1714' }}>Куда идут данные</div>
            <div style={{ fontSize: 12, color: '#8a817a', marginTop: 2 }}>Опубликованная версия → /calculator. Черновик — нет.</div>
          </div>
          <button onClick={onClose} style={{ ...ctorStyles.iconBtn, color: '#8a817a' }}>{Icon.x}</button>
        </div>
        <div style={{ padding: '14px 18px 18px' }}>
          {FLOW.map((f, i) => (
            <div key={i} style={{ display: 'flex', gap: 12, position: 'relative', paddingBottom: i < FLOW.length - 1 ? 14 : 0 }}>
              <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', flexShrink: 0 }}>
                <span style={{ width: 11, height: 11, borderRadius: '50%', background: f.c, border: f.strong ? '2px solid #fff' : 'none', boxShadow: f.strong ? '0 0 0 2px ' + f.c : 'none', marginTop: 3 }}></span>
                {i < FLOW.length - 1 && <span style={{ width: 1.5, flex: 1, background: '#ece5da', marginTop: 3 }}></span>}
              </div>
              <div style={{ paddingBottom: 2 }}>
                <div style={{ fontSize: 13, fontWeight: f.strong ? 700 : 600, color: f.strong ? f.c : '#1a1714' }}>{f.t}</div>
                <div style={{ fontSize: 11.5, color: '#8a817a', marginTop: 1 }}>{f.s}</div>
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { PublishModal, AnnotationLayer });
