/* eslint-disable */
/* timing-grid.jsx — cue-sheet сетка мероприятия: треки × тайм-слоты × карточки. */

(function () {
  const R = window.React;
  const { useState, useRef } = R;
  const D = window.TimingData;

  const TIME_W = 70;
  const COL_MIN = 158;

  /* ---------- Карточка в ячейке ---------- */
  function GridCard({ card, color, onPatch, onDel, dragInfo, onDragState }) {
    const [hover, setHover] = useState(false);
    return (
      <div
        draggable
        onDragStart={e => { e.stopPropagation(); dragInfo.current = { type: 'card', id: card.id }; onDragState(card.id); }}
        onDragEnd={() => { dragInfo.current = null; onDragState(null); }}
        onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
        style={{
          position: 'relative', background: 'var(--color-surface)',
          border: '1px solid var(--color-line-subtle)', borderLeft: '3px solid ' + color,
          borderRadius: 6, padding: '6px 8px 7px', cursor: 'grab', boxShadow: 'var(--shadow-card)',
        }}>
        <textarea
          value={card.title}
          rows={1}
          placeholder="…"
          onChange={e => onPatch({ title: e.target.value })}
          onDragStart={e => e.preventDefault()}
          style={{
            display: 'block', width: '100%', border: 0, background: 'transparent', resize: 'none',
            padding: 0, margin: 0, fontFamily: 'inherit', fontSize: 12, fontWeight: 500, lineHeight: 1.3,
            color: 'var(--color-ink-900)', outline: 'none', overflow: 'hidden', minHeight: 16,
          }}
          ref={el => { if (el) { el.style.height = 'auto'; el.style.height = el.scrollHeight + 'px'; } }}
        />
        {(card.dur || card.who) && (
          <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginTop: 4, flexWrap: 'wrap' }}>
            {card.dur ? <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10, fontWeight: 600, color: color, background: 'var(--color-muted-50)', padding: '0 5px', borderRadius: 4, fontVariantNumeric: 'tabular-nums' }}>{D.dur(card.dur)}</span> : null}
            {card.who ? <span style={{ fontSize: 10.5, color: 'var(--color-ink-500)' }}>{card.who}</span> : null}
          </div>
        )}
        {hover && (
          <button onClick={onDel} title="Удалить" style={{
            position: 'absolute', top: 2, right: 2, width: 18, height: 18, borderRadius: 4, border: 0,
            background: 'var(--color-surface)', color: 'var(--color-ink-400)', display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}><Icon name="x" size={11} /></button>
        )}
      </div>
    );
  }

  /* ---------- Ячейка (drop-зона) ---------- */
  function Cell({ track, slot, cards, ops, dragInfo, over, setOver, dragId, onDragState, isLast }) {
    const isOver = over && over.t === track.id && over.s === slot.id;
    return (
      <div
        onDragOver={e => { e.preventDefault(); setOver({ t: track.id, s: slot.id }); }}
        onDrop={e => {
          e.preventDefault();
          const di = dragInfo.current;
          if (di && di.type === 'card') ops.moveCard(di.id, track.id, slot.id);
          else if (di && di.type === 'lib') ops.addCardFromLib(track.id, slot.id, di.block);
          dragInfo.current = null; setOver(null); onDragState(null);
        }}
        style={{
          borderRight: '1px solid var(--color-line-subtle)',
          borderBottom: isLast ? 'none' : '1px solid var(--color-line-subtle)',
          background: isOver ? 'rgba(44,58,87,0.05)' : 'transparent',
          padding: 6, minHeight: 56, display: 'flex', flexDirection: 'column', gap: 5,
          transition: 'background .1s',
        }}>
        {cards.map(c => (
          <GridCard key={c.id} card={c} color={D.trackColor(track.color)}
            onPatch={p => ops.patchCard(c.id, p)} onDel={() => ops.delCard(c.id)}
            dragInfo={dragInfo} onDragState={onDragState} />
        ))}
        <button onClick={() => ops.addCard(track.id, slot.id)} className="tm-cell-add"
          style={{
            border: '1px dashed transparent', borderRadius: 5, background: 'transparent',
            color: 'var(--color-ink-300)', padding: cards.length ? '2px' : '0', minHeight: cards.length ? 0 : 30,
            display: 'flex', alignItems: 'center', justifyContent: 'center', flex: cards.length ? '0 0 auto' : 1,
          }}>
          <Icon name="plus" size={cards.length ? 12 : 14} />
        </button>
      </div>
    );
  }

  /* ---------- Заголовок трека ---------- */
  function TrackHead({ track, ops, canDelete }) {
    const [hover, setHover] = useState(false);
    const [palette, setPalette] = useState(false);
    return (
      <div onMouseEnter={() => setHover(true)} onMouseLeave={() => { setHover(false); setPalette(false); }}
        style={{
          position: 'sticky', top: 0, zIndex: 6, background: 'var(--color-muted-50)',
          borderRight: '1px solid var(--color-line-subtle)', borderBottom: '1px solid var(--color-line-strong)',
          padding: '8px 8px 8px 10px', display: 'flex', alignItems: 'center', gap: 7,
        }}>
        <div style={{ position: 'relative', flex: '0 0 auto' }}>
          <button onClick={() => setPalette(p => !p)} title="Цвет" style={{ width: 11, height: 11, borderRadius: '50%', border: 0, padding: 0, background: D.trackColor(track.color) }} />
          {palette && (
            <div style={{ position: 'absolute', top: 16, left: 0, zIndex: 20, display: 'flex', gap: 4, background: 'var(--color-elevated)', border: '1px solid var(--color-line-subtle)', borderRadius: 6, padding: 5, boxShadow: 'var(--shadow-modal)' }}>
              {D.TRACK_PALETTE.map(p => (
                <button key={p.key} onClick={() => { ops.patchTrack(track.id, { color: p.key }); setPalette(false); }}
                  style={{ width: 14, height: 14, borderRadius: '50%', border: track.color === p.key ? '2px solid var(--color-ink-900)' : '1px solid var(--color-line-subtle)', padding: 0, background: p.color }} />
              ))}
            </div>
          )}
        </div>
        <input value={track.name} onChange={e => ops.patchTrack(track.id, { name: e.target.value })}
          style={{ flex: 1, minWidth: 0, border: '1px solid transparent', background: 'transparent', borderRadius: 4, padding: '2px 4px', margin: '-2px -4px', fontSize: 12, fontWeight: 600, color: 'var(--color-ink-900)', outline: 'none' }}
          onFocus={e => { e.target.style.background = 'var(--color-surface)'; e.target.style.borderColor = 'var(--color-line-strong)'; }}
          onBlur={e => { e.target.style.background = 'transparent'; e.target.style.borderColor = 'transparent'; }}
        />
        {hover && canDelete && (
          <button onClick={() => ops.delTrack(track.id)} title="Удалить колонку" style={{ flex: '0 0 auto', width: 18, height: 18, border: 0, borderRadius: 4, background: 'transparent', color: 'var(--color-ink-400)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
            <Icon name="trash" size={12} />
          </button>
        )}
      </div>
    );
  }

  /* ---------- Сетка ---------- */
  function EventGrid({ grid, ops, dragInfo }) {
    const [over, setOver] = useState(null);
    const [dragId, setDragId] = useState(null);
    const slots = grid.slots.slice().sort((a, b) => a.time - b.time);
    const tracks = grid.tracks;
    const cols = TIME_W + 'px repeat(' + tracks.length + ', minmax(' + COL_MIN + 'px, 1fr)) 40px';

    return (
      <div style={{ height: '100%', overflow: 'auto' }} onDragLeave={e => { if (e.target === e.currentTarget) setOver(null); }}>
        <div style={{ display: 'grid', gridTemplateColumns: cols, minWidth: 'min-content' }}>
          {/* corner */}
          <div style={{ position: 'sticky', top: 0, left: 0, zIndex: 8, background: 'var(--color-muted-50)', borderRight: '1px solid var(--color-line-strong)', borderBottom: '1px solid var(--color-line-strong)', padding: '8px 6px', fontSize: 9.5, fontWeight: 600, letterSpacing: '.06em', textTransform: 'uppercase', color: 'var(--color-ink-400)', display: 'flex', alignItems: 'center' }}>Время</div>
          {/* track headers */}
          {tracks.map(t => <TrackHead key={t.id} track={t} ops={ops} canDelete={tracks.length > 1} />)}
          {/* add-track header */}
          <div style={{ position: 'sticky', top: 0, zIndex: 6, background: 'var(--color-muted-50)', borderBottom: '1px solid var(--color-line-strong)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
            <button onClick={ops.addTrack} title="Добавить колонку" style={{ width: 24, height: 24, borderRadius: 6, border: '1px solid var(--color-line-subtle)', background: 'var(--color-surface)', color: 'var(--color-ink-500)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
              <Icon name="plus" size={14} />
            </button>
          </div>

          {/* rows */}
          {slots.map((slot, i) => {
            const next = slots[i + 1];
            let delta = next ? next.time - slot.time : 0;
            if (!delta) { grid.cards.filter(c => c.slotId === slot.id && c.dur).forEach(c => { delta = Math.max(delta, c.dur); }); }
            const isLast = i === slots.length - 1;
            return (
              <R.Fragment key={slot.id}>
                {/* time cell */}
                <TimeCell slot={slot} delta={delta} ops={ops} isLast={isLast} canDelete={slots.length > 1} />
                {tracks.map(t => (
                  <Cell key={t.id} track={t} slot={slot}
                    cards={grid.cards.filter(c => c.trackId === t.id && c.slotId === slot.id)}
                    ops={ops} dragInfo={dragInfo} over={over} setOver={setOver} dragId={dragId} onDragState={setDragId} isLast={isLast} />
                ))}
                {/* spacer under add-track col */}
                <div style={{ borderBottom: isLast ? 'none' : '1px solid var(--color-line-subtle)' }} />
              </R.Fragment>
            );
          })}

          {/* add slot row */}
          <div style={{ gridColumn: '1 / -1', padding: '10px 12px' }}>
            <button onClick={ops.addSlot} style={{
              display: 'inline-flex', alignItems: 'center', gap: 6, padding: '7px 12px',
              border: '1px dashed var(--color-line-strong)', borderRadius: 'var(--radius-card)',
              background: 'transparent', color: 'var(--color-ink-500)', fontSize: 12.5, fontWeight: 500,
            }}><Icon name="plus" size={13} /> Тайм-слот</button>
          </div>
        </div>
      </div>
    );
  }

  function TimeCell({ slot, delta, ops, isLast, canDelete }) {
    const [hover, setHover] = useState(false);
    return (
      <div onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
        style={{
          position: 'sticky', left: 0, zIndex: 4, background: 'var(--color-canvas)',
          borderRight: '1px solid var(--color-line-strong)', borderBottom: isLast ? 'none' : '1px solid var(--color-line-subtle)',
          padding: '8px 4px 8px 8px', display: 'flex', flexDirection: 'column', gap: 1,
        }}>
        <input value={D.fmt(slot.time)} onChange={e => ops.patchSlot(slot.id, { time: D.parse(e.target.value) })}
          style={{ width: 52, border: '1px solid transparent', background: 'transparent', borderRadius: 4, padding: '1px 3px', fontFamily: 'var(--font-mono)', fontSize: 13, fontWeight: 600, color: 'var(--color-ink-900)', fontVariantNumeric: 'tabular-nums', outline: 'none' }}
          onFocus={e => { e.target.style.background = 'var(--color-surface)'; e.target.style.borderColor = 'var(--color-line-strong)'; }}
          onBlur={e => { e.target.style.background = 'transparent'; e.target.style.borderColor = 'transparent'; }}
        />
        {delta > 0 && <span style={{ fontSize: 9.5, color: 'var(--color-ink-400)', fontFamily: 'var(--font-mono)', paddingLeft: 3 }}>+{D.dur(delta)}</span>}
        {hover && canDelete && (
          <button onClick={() => ops.delSlot(slot.id)} title="Удалить слот" style={{ marginTop: 2, width: 18, height: 18, border: 0, borderRadius: 4, background: 'transparent', color: 'var(--color-ink-400)', display: 'flex', alignItems: 'center' }}>
            <Icon name="trash" size={11} />
          </button>
        )}
      </div>
    );
  }

  window.TimingGrid = { EventGrid };
})();
