/* ctor-skirt.jsx — «юбка»/бампер под узлом дерева: перечень заметок и материалов
   с точным количеством и редактированием прямо на месте (ревью Roma).
   Если 2 заметки и 3 материала — показываем 5 строк, каждая редактируема,
   с указанием, кто оставил заметку. Привязан снизу к телу этапа/задачи/подзадачи. */
const { useState: skUseState } = React;

function SkirtNote({ note, onPatch, onDel }) {
  const [edit, setEdit] = skUseState(false);
  const [val, setVal] = skUseState(note.text || '');
  return (
    <div style={{ display: 'flex', alignItems: 'flex-start', gap: 8, padding: '5px 9px', borderRadius: 8, background: '#fff' }}>
      <span style={{ width: 6, height: 6, borderRadius: '50%', background: note.color || '#4e7fca', flexShrink: 0, marginTop: 6 }} />
      <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4, fontSize: 10.5, fontWeight: 700, color: note.color || '#4e7fca', flexShrink: 0, marginTop: 2 }}>
        <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" /></svg>
        {note.role || 'Заметка'}
      </span>
      {edit ?
        <input autoFocus value={val} onChange={(e) => setVal(e.target.value)}
          onBlur={() => { onPatch({ text: val }); setEdit(false); }}
          onKeyDown={(e) => { if (e.key === 'Enter') { onPatch({ text: val }); setEdit(false); } if (e.key === 'Escape') { setVal(note.text || ''); setEdit(false); } }}
          style={{ flex: 1, minWidth: 0, border: '.5px solid #e4ddd2', borderRadius: 6, background: '#fafafa', fontFamily: 'inherit', fontSize: 12, color: '#1a1714', outline: 'none', padding: '3px 7px' }} /> :
        <span onClick={() => setEdit(true)} title="Редактировать заметку" style={{ flex: 1, minWidth: 0, fontSize: 12, color: '#5c5249', lineHeight: 1.45, cursor: 'text' }}>
          {(note.text || '').trim() || <span style={{ color: '#bcb3a7' }}>пустая заметка — нажмите, чтобы заполнить</span>}
        </span>}
      <span style={{ fontSize: 10, color: '#bcb3a7', flexShrink: 0, marginTop: 3 }}>{note.author ? note.author.split(' ')[0] : ''}</span>
      <button onClick={onDel} title="Удалить" style={skIconBtn}>×</button>
    </div>
  );
}

function SkirtMaterial({ bind, mat, onPatch, onDel }) {
  const name = bind.isManual ? (bind.manualName || 'Ручная позиция') : (mat ? mat.name : 'материал не найден');
  const qty = bind.defaultQty == null ? 1 : bind.defaultQty;
  const unit = bind.unitPrice != null ? +bind.unitPrice : (mat ? (+mat.clientUnitPrice || +mat.unitPrice || 0) : 0);
  const total = Math.round(unit * qty);
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '5px 9px', borderRadius: 8, background: '#fff' }}>
      <span style={{ fontSize: 11, flexShrink: 0 }}>📦</span>
      <span style={{ flex: 1, minWidth: 0, fontSize: 12, fontWeight: 600, color: mat || bind.isManual ? '#1a1714' : '#f04e62', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{name}</span>
      <span style={{ display: 'inline-flex', alignItems: 'center', gap: 3, background: '#f0ece5', borderRadius: 7, padding: '2px 6px', flexShrink: 0 }}>
        <input type="number" min={0} step={0.5} value={qty} onChange={(e) => onPatch({ defaultQty: Math.max(0, +e.target.value || 0) })}
          style={{ width: 38, border: 'none', background: 'transparent', fontFamily: 'inherit', fontSize: 11.5, fontWeight: 700, color: '#1a1714', textAlign: 'right', outline: 'none', fontVariantNumeric: 'tabular-nums' }} />
        <input value={bind.unit || 'шт'} onChange={(e) => onPatch({ unit: e.target.value })} style={{ width: 30, border: 'none', background: 'transparent', fontFamily: 'inherit', fontSize: 11, color: '#8a817a', outline: 'none' }} />
      </span>
      <span style={{ display: 'inline-flex', alignItems: 'baseline', gap: 4, flexShrink: 0, width: 132, justifyContent: 'flex-end' }} title="Цена за единицу × количество = итого">
        <span style={{ fontSize: 11, color: '#8a817a', fontVariantNumeric: 'tabular-nums' }}>{skRub(unit)} ₽/{bind.unit || 'шт'}</span>
        <span style={{ fontSize: 11, color: '#cfc6ba' }}>·</span>
        <span style={{ fontSize: 12, fontWeight: 800, color: '#1a1714', fontVariantNumeric: 'tabular-nums' }}>{skRub(total)} ₽</span>
      </span>
      <button onClick={onDel} title="Убрать материал" style={skIconBtn}>×</button>
    </div>
  );
}

/* nodeId, notes(obj id→[]), setNotes, bomLines(array), setBindings, materialsLib, color */
function NodeSkirt({ nodeId, notes, setNotes, bomLines, setBindings, materialsLib, color }) {
  const noteList = (notes && notes[nodeId]) || [];
  const matList = bomLines || [];
  const MDx = window.MaterialsData;
  if (noteList.length === 0 && matList.length === 0) return null;

  const patchNote = (nid, patch) => setNotes && setNotes((all) => ({ ...all, [nodeId]: (all[nodeId] || []).map((n) => n.id === nid ? { ...n, ...patch } : n) }));
  const delNote = (nid) => setNotes && setNotes((all) => ({ ...all, [nodeId]: (all[nodeId] || []).filter((n) => n.id !== nid) }));
  const patchMat = (bid, patch) => setBindings && setBindings((all) => ({ ...all, [nodeId]: (all[nodeId] || []).map((b) => b.id === bid ? { ...b, ...patch } : b) }));
  const delMat = (bid) => setBindings && setBindings((all) => ({ ...all, [nodeId]: (all[nodeId] || []).filter((b) => b.id !== bid) }));

  return (
    <div style={{ margin: '1px 0 6px 30px', borderLeft: '2px solid ' + (color || '#e4ddd2'), borderRadius: '0 8px 8px 0', background: '#f7f5f1', padding: '6px 8px', display: 'flex', flexDirection: 'column', gap: 3 }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '0 4px 3px' }}>
        <span style={{ fontSize: 9.5, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '.05em', color: '#a89e92' }}>Привязано к узлу</span>
        <span style={{ flex: 1, height: 1, background: '#ece5da' }} />
        {noteList.length > 0 && <span style={{ fontSize: 10.5, fontWeight: 700, color: '#4e7fca' }}>{noteList.length} замет.</span>}
        {matList.length > 0 && <span style={{ fontSize: 10.5, fontWeight: 700, color: '#5aad6e' }}>{matList.length} матер.</span>}
      </div>
      {noteList.map((n) => <SkirtNote key={n.id} note={n} onPatch={(p) => patchNote(n.id, p)} onDel={() => delNote(n.id)} />)}
      {matList.map((b) => <SkirtMaterial key={b.id} bind={b} mat={b.isManual ? null : (MDx ? MDx.materialById(materialsLib, b.materialId) : null)} onPatch={(p) => patchMat(b.id, p)} onDel={() => delMat(b.id)} />)}
    </div>
  );
}

const skRub = (n) => (Math.round(n) || 0).toLocaleString('ru-RU');
const skIconBtn = { width: 18, height: 18, borderRadius: 5, border: 'none', background: 'transparent', color: '#c7beb2', cursor: 'pointer', fontSize: 15, lineHeight: 1, flexShrink: 0, fontFamily: 'inherit' };

Object.assign(window, { NodeSkirt });
