// tablenode.jsx — et bord på lærredet + pladser, kontekst-bar, menuer
const { useState: useStateTN } = React;
const TABLE_TYPES = [
  { id: 'round', label: 'Rundt bord', defSeats: 6 },
  { id: 'long', label: 'Langbord', defSeats: 8 },
  { id: 'square', label: 'Firkantet', defSeats: 8 },
  { id: 'horseshoe', label: 'Hestesko', defSeats: 12 },
];

function TableNode({ t, L, selected, bad, seatGuest, groups, hoverSeat, dragging, onTableDown, onSeatDown }) {
  const SR = window.PlaniqGeo.SR;
  const cx = L.w / 2, cy = L.h / 2;
  const used = groups && t ? null : null;
  const grpColor = (id) => (groups.find(g => g.id === id) || {}).color || 1;

  return (
    <div style={{ position: 'absolute', left: t.x, top: t.y, width: L.w, height: L.h, transform: `translate(-50%,-50%) rotate(${t.rot}deg)` }}>
      {/* shape (drag handle) */}
      <svg width={L.w} height={L.h} style={{ position: 'absolute', inset: 0, overflow: 'visible', cursor: 'grab', touchAction: 'none' }}
        onPointerDown={onTableDown}>
        {L.shapes.map((s, i) => {
          const fill = 'var(--surface)';
          const stroke = bad ? 'var(--warn)' : selected ? 'var(--accent)' : 'var(--line-2)';
          const sw = (bad || selected) ? 3 : 2;
          if (s.kind === 'circle') return <circle key={i} cx={cx + s.cx} cy={cy + s.cy} r={s.r} fill={fill} stroke={stroke} strokeWidth={sw} style={{ filter: 'drop-shadow(0 4px 10px rgba(78,60,40,.10))' }} />;
          return <rect key={i} x={cx + s.x} y={cy + s.y} width={s.w} height={s.h} rx={Math.min(22, s.h / 2, s.w / 2)} fill={fill} stroke={stroke} strokeWidth={sw} style={{ filter: 'drop-shadow(0 4px 10px rgba(78,60,40,.10))' }} />;
        })}
      </svg>

      {/* center label */}
      <div style={{ position: 'absolute', left: cx, top: cy, transform: `translate(-50%,-50%) rotate(${-t.rot}deg)`, pointerEvents: 'none', textAlign: 'center', maxWidth: Math.max(120, L.w * 0.5) }}>
        <div style={{ fontFamily: 'var(--font-disp)', fontWeight: 600, fontSize: 15, color: 'var(--ink)', lineHeight: 1.1, textWrap: 'balance' }}>{t.label}</div>
        <div style={{ fontSize: 12.5, fontWeight: 800, color: 'var(--ink-faint)', marginTop: 2 }}>
          {seatedCount(t, seatGuest)}/{t.seats} pladser
        </div>
      </div>

      {/* seats */}
      {L.seats.map((s, i) => {
        const g = seatGuest(t.id, i);
        const hot = hoverSeat && hoverSeat.tableId === t.id && hoverSeat.index === i;
        return (
          <Seat key={i} tableId={t.id} index={i} x={cx + s.x} y={cy + s.y} guest={g} color={g ? grpColor(g.group) : null} hot={hot} dragging={dragging} rot={t.rot}
            onPointerDown={(e) => { if (g) onSeatDown(e, g, { tableId: t.id, index: i }); }} />
        );
      })}
    </div>
  );
}

function seatedCount(t, seatGuest) {
  let n = 0; for (let i = 0; i < t.seats; i++) if (seatGuest(t.id, i)) n++; return n;
}

function Seat({ tableId, index, x, y, guest, color, hot, dragging, rot, onPointerDown }) {
  const SR = window.PlaniqGeo.SR;
  const d = SR * 2;
  return (
    <div style={{ position: 'absolute', left: x, top: y, transform: 'translate(-50%,-50%)' }}>
      <div style={{ transform: `rotate(${-rot}deg)` }}>
        <div
          data-seat-table={tableId}
          data-seat-index={index}
          onPointerDown={onPointerDown}
          style={{
            width: d + 18, height: d + 18, margin: -9, display: 'grid', placeItems: 'center',
            cursor: guest ? 'grab' : 'default', touchAction: 'none', borderRadius: '50%',
          }}>
          <div style={{
            width: d, height: d, borderRadius: '50%', display: 'grid', placeItems: 'center',
            transition: 'transform .14s var(--ease), box-shadow .14s, background .14s',
            transform: hot ? 'scale(1.2)' : 'scale(1)', pointerEvents: 'none',
            background: guest ? `var(--grp-${color})` : (hot ? 'var(--accent-soft)' : 'var(--surface-2)'),
            border: guest ? '2.5px solid #fff' : `2px dashed ${hot ? 'var(--accent)' : 'var(--line-2)'}`,
            boxShadow: guest ? '0 2px 6px rgba(78,60,40,.18)' : (hot ? '0 0 0 4px var(--accent-soft)' : 'none'),
            color: '#fff', fontWeight: 800, fontFamily: 'var(--font-disp)', fontSize: d * 0.34, position: 'relative',
          }}>
            {guest ? initialsOf(guest.name) : (hot ? <Icon name="plus" size={18} color="var(--accent-deep)" /> : '')}
            {guest && guest.child && <span style={{ position: 'absolute', bottom: -3, right: -3, background: '#fff', borderRadius: '50%', width: 17, height: 17, display: 'grid', placeItems: 'center', boxShadow: '0 1px 2px rgba(0,0,0,.2)' }}><Icon name="baby" size={11} color="var(--accent-deep)" sw={2.2} /></span>}
            {guest && guest.diet.length > 0 && <span style={{ position: 'absolute', top: -4, right: -4, background: 'var(--sage-deep)', borderRadius: '50%', width: 16, height: 16, display: 'grid', placeItems: 'center' }}><Icon name="leaf" size={10} color="#fff" /></span>}
          </div>
        </div>
        {guest && <div style={{ position: 'absolute', top: d + 4, left: '50%', transform: 'translateX(-50%)', fontSize: 11.5, fontWeight: 800, color: 'var(--ink-soft)', whiteSpace: 'nowrap', pointerEvents: 'none' }}>{guest.name.split(' ')[0]}</div>}
      </div>
    </div>
  );
}

function AddTableMenu({ onPick, onClose, defaultType }) {
  return (
    <>
      <div style={{ position: 'fixed', inset: 0, zIndex: 40 }} onPointerDown={onClose}></div>
      <div className="card anim-pop" style={{ position: 'absolute', top: 58, left: 0, zIndex: 41, padding: 10, width: 280, borderRadius: 18 }}>
        <p className="muted" style={{ fontSize: 13, fontWeight: 800, padding: '4px 8px 8px' }}>VÆLG BORDTYPE</p>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
          {TABLE_TYPES.map(tt => (
            <button key={tt.id} onClick={() => onPick(tt.id)} className="col" style={{
              padding: '14px 10px', borderRadius: 14, gap: 8, alignItems: 'center', border: `1.5px solid ${tt.id === defaultType ? 'var(--accent)' : 'var(--line)'}`,
              background: tt.id === defaultType ? 'var(--accent-tint)' : 'var(--surface)',
            }} onMouseEnter={e => e.currentTarget.style.borderColor = 'var(--accent)'} onMouseLeave={e => e.currentTarget.style.borderColor = tt.id === defaultType ? 'var(--accent)' : 'var(--line)'}>
              <TableGlyph type={tt.id} />
              <span style={{ fontSize: 14, fontWeight: 800 }}>{tt.label}</span>
            </button>
          ))}
        </div>
      </div>
    </>
  );
}

function TableGlyph({ type, size = 46 }) {
  const seat = (cx, cy) => <circle cx={cx} cy={cy} r="3.4" fill="var(--accent)" />;
  let body, seats;
  if (type === 'round') {
    body = <circle cx="23" cy="23" r="11" fill="none" stroke="var(--ink-soft)" strokeWidth="2" />;
    seats = [0,1,2,3,4,5].map(i => { const a = i/6*Math.PI*2; return <circle key={i} cx={23+Math.cos(a)*17} cy={23+Math.sin(a)*17} r="3.4" fill="var(--accent)" />; });
  } else if (type === 'long') {
    body = <rect x="9" y="18" width="28" height="10" rx="4" fill="none" stroke="var(--ink-soft)" strokeWidth="2" />;
    seats = [0,1,2,3].map(i => <g key={i}>{seat(13+i*7, 12)}{seat(13+i*7, 34)}</g>);
  } else if (type === 'square') {
    body = <rect x="15" y="15" width="16" height="16" rx="3" fill="none" stroke="var(--ink-soft)" strokeWidth="2" />;
    seats = [<g key="a">{seat(19,9)}{seat(27,9)}{seat(19,37)}{seat(27,37)}{seat(9,19)}{seat(9,27)}{seat(37,19)}{seat(37,27)}</g>];
  } else {
    body = <path d="M13 12 V30 H33 V12" fill="none" stroke="var(--ink-soft)" strokeWidth="2" strokeLinejoin="round" />;
    seats = [<g key="a">{seat(8,15)}{seat(8,23)}{seat(8,30)}{seat(38,15)}{seat(38,23)}{seat(38,30)}{seat(18,37)}{seat(28,37)}</g>];
  }
  return <svg width={size} height={size} viewBox="0 0 46 46">{body}{seats}</svg>;
}

function TableContextBar({ t, L, usedSeats, seatedDiet, mut, onClose }) {
  const [editing, setEditing] = useStateTN(false);
  const DIET = window.PlaniqData.DIET_TYPES;
  const dietKeys = Object.keys(seatedDiet);
  // Redigér-dialogen erstatter handlingspanelet, mens den er åben.
  if (editing) {
    return <TableEditModal t={t} usedSeats={usedSeats}
      onSave={(patch) => { mut.updateTable(t.id, patch); setEditing(false); }}
      onClose={() => setEditing(false)} />;
  }

  return (
    <Modal onClose={onClose} maxWidth={360}>
      {/* overskrift: bordnavn + belægning */}
      <div className="row gap-3" style={{ marginBottom: 16, alignItems: 'flex-start' }}>
        <div className="col" style={{ flex: 1, minWidth: 0, gap: 4 }}>
          <h2 style={{ fontSize: 21, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{t.label}</h2>
          <span className="muted" style={{ fontSize: 14, fontWeight: 700 }}>{usedSeats}/{t.seats} pladser brugt</span>
        </div>
      </div>

      {dietKeys.length > 0 && (
        <div className="row gap-2" style={{ flexWrap: 'wrap', marginBottom: 16 }}>
          {dietKeys.map(d => <span key={d} className="chip" style={{ background: 'var(--sage-tint)', color: 'var(--sage-deep)', border: 'none' }}><Icon name="leaf" size={13} />{DIET.find(x=>x.id===d)?.short} {seatedDiet[d]}</span>)}
        </div>
      )}

      {/* handlinger */}
      <div className="col gap-2">
        <button className="btn" style={{ width: '100%', justifyContent: 'flex-start' }} onClick={() => setEditing(true)}><Icon name="edit" size={19} /> Redigér navn og pladser</button>
        <div className="row gap-2">
          <button className="btn" style={{ flex: 1 }} onClick={() => mut.updateTable(t.id, { rot: (t.rot + 45) % 360 })}><Icon name="rotate" size={19} /> Rotér</button>
          <button className="btn" style={{ flex: 1 }} onClick={() => mut.duplicateTable(t.id)}><Icon name="copy" size={19} /> Dublér</button>
        </div>
        <button className="btn" style={{ width: '100%', justifyContent: 'flex-start', color: 'var(--warn)', borderColor: 'var(--warn-soft)' }} onClick={() => { mut.removeTable(t.id); onClose(); }}><Icon name="trash" size={19} /> Slet bord</button>
      </div>

      <div className="row" style={{ justifyContent: 'flex-end', marginTop: 18 }}>
        <button className="btn btn-ghost" onClick={onClose}>Luk</button>
      </div>
    </Modal>
  );
}

function TableEditModal({ t, usedSeats, onSave, onClose }) {
  const MIN = Math.max(1, usedSeats); // kan ikke gå under antal placerede gæster
  const MAX = 24;
  const [name, setName] = useStateTN(t.label);
  const [seats, setSeats] = useStateTN(t.seats);
  const seatsNum = parseInt(seats, 10);
  const seatsValid = !isNaN(seatsNum) && seatsNum >= MIN && seatsNum <= MAX;
  const valid = name.trim() && seatsValid;
  const save = () => { if (valid) onSave({ label: name.trim(), seats: seatsNum }); };

  return (
    <Modal onClose={onClose} maxWidth={420}>
      <h2 style={{ marginBottom: 20 }}>Redigér bord</h2>
      <div className="col gap-4">
        <div className="field"><label>Navn på bordet</label>
          <input className="input" autoFocus value={name} onChange={e => setName(e.target.value)}
            onKeyDown={e => { if (e.key === 'Enter' && valid) save(); }} /></div>
        <div className="field"><label>Antal siddepladser</label>
          <div className="row gap-2" style={{ alignItems: 'stretch' }}>
            <button className="btn btn-icon" type="button" disabled={seatsNum <= MIN}
              onClick={() => setSeats(Math.max(MIN, (seatsNum || MIN) - 1))}><Icon name="minus" size={20} /></button>
            <input className="input" type="number" min={MIN} max={MAX} value={seats}
              onChange={e => setSeats(e.target.value)}
              onKeyDown={e => { if (e.key === 'Enter' && valid) save(); }}
              style={{ width: 90, textAlign: 'center', fontWeight: 800 }} />
            <button className="btn btn-icon" type="button" disabled={seatsNum >= MAX}
              onClick={() => setSeats(Math.min(MAX, (seatsNum || MIN) + 1))}><Icon name="plus" size={20} /></button>
          </div>
          {usedSeats > 0 && <span className="muted" style={{ fontSize: 13.5 }}>Mindst {MIN} — der sidder {usedSeats} {usedSeats === 1 ? 'gæst' : 'gæster'} ved bordet.</span>}
          {!seatsValid && seats !== '' && <span style={{ color: 'var(--warn)', fontSize: 13.5 }}>Vælg mellem {MIN} og {MAX} pladser.</span>}
        </div>
      </div>
      <div className="row gap-3" style={{ justifyContent: 'flex-end', marginTop: 26 }}>
        <button className="btn btn-ghost" onClick={onClose}>Annullér</button>
        <button className="btn btn-sage" disabled={!valid} onClick={save}>Gem</button>
      </div>
    </Modal>
  );
}

function WarningsPopover({ violations, onJump, onClose }) {
  return (
    <>
      <div style={{ position: 'fixed', inset: 0, zIndex: 40 }} onPointerDown={onClose}></div>
      <div className="card anim-pop" style={{ position: 'absolute', top: 50, right: 0, zIndex: 41, padding: 10, width: 320, borderRadius: 18 }}>
        <div className="row gap-2" style={{ padding: '4px 8px 10px' }}><Icon name="warn" size={18} color="var(--warn)" /><p style={{ fontWeight: 800, fontSize: 14.5, color: 'var(--warn)' }}>Brudte regler</p></div>
        <div className="col gap-2">
          {violations.map((v, i) => (
            <button key={i} className="col" onClick={() => onJump(v.a.seat ? v.a.seat.tableId : v.b.seat.tableId)} style={{ padding: '10px 12px', borderRadius: 12, background: 'var(--warn-soft)', alignItems: 'flex-start', gap: 4, textAlign: 'left' }}>
              <span className="row gap-2" style={{ fontSize: 12.5, fontWeight: 800, color: 'var(--warn)' }}><Icon name={v.type === 'apart' ? 'unlink' : 'link'} size={14} />{v.type === 'apart' ? 'Må ikke sidde sammen' : 'Skal sidde sammen'}</span>
              <span style={{ fontSize: 14.5, fontWeight: 700 }}>{v.msg}</span>
              <span className="row gap-2 faint" style={{ fontSize: 12.5, fontWeight: 800 }}>Vis bord <Icon name="chevR" size={13} /></span>
            </button>
          ))}
        </div>
      </div>
    </>
  );
}

Object.assign(window, { TableNode, Seat, AddTableMenu, TableContextBar, WarningsPopover, TableGlyph, TABLE_TYPES });
