import { useState, useEffect, useRef, useCallback } from 'react';
import { api, S } from '../lib.js';

// ── Konstanten ────────────────────────────────────────────────────────────────
const PRIORITIES = [
  { id: 'none',   label: 'Keine',   color: '#666666' },
  { id: 'low',    label: 'Niedrig', color: '#4ecdc4' },
  { id: 'medium', label: 'Mittel',  color: '#ffe66d' },
  { id: 'high',   label: 'Hoch',    color: '#ff6b9d' },
];
const COL_COLORS = ['#4ecdc4','#60a5fa','#a78bfa','#ff6b9d','#ffe66d','#fb923c','#4ade80','#f472b6','#94a3b8'];
const fmtCardDate = s => {
  if (!s) return '';
  const d = new Date(String(s).replace(' ', 'T'));
  if (isNaN(d)) return '';
  return d.toLocaleDateString('de-DE', { day:'2-digit', month:'2-digit', year:'numeric' })
    + ' ' + d.toLocaleTimeString('de-DE', { hour:'2-digit', minute:'2-digit' });
};
const prioOf = id => PRIORITIES.find(p => p.id === id) || PRIORITIES[0];

// ── Karten-Modal ──────────────────────────────────────────────────────────────
function CardModal({ card, columnId, columns, onSave, onClose, toast }) {
  const [title,      setTitle]      = useState(card?.title       || '');
  const [desc,       setDesc]       = useState(card?.description || '');
  const [prio,       setPrio]       = useState(card?.priority    || 'none');
  const [moveToCol,  setMoveToCol]  = useState(card?.column_id   || columnId);
  const [newColName, setNewColName] = useState('');
  const [showNewCol, setShowNewCol] = useState(false);
  const [saving,     setSaving]     = useState(false);
  const titleRef   = useRef(null);
  const newColRef  = useRef(null);
  const isMob = window.innerWidth < 768;

  useEffect(() => { titleRef.current?.focus(); }, []);
  useEffect(() => { if (showNewCol) newColRef.current?.focus(); }, [showNewCol]);

  const save = async () => {
    if (!title.trim()) return;
    setSaving(true);
    try {
      // Neue Spalte anlegen wenn gewünscht
      let targetCol = moveToCol;
      if (showNewCol && newColName.trim()) {
        const nc = await api('/tools/kanban/columns', { body: { title: newColName.trim() } });
        targetCol = nc.id;
      }
      if (card) {
        await api(`/tools/kanban/cards/${card.id}`, {
          method: 'PATCH',
          body: { title, description: desc, priority: prio },
        });
        // Spalte gewechselt?
        if (targetCol && targetCol !== card.column_id) {
          await api(`/tools/kanban/cards/${card.id}/move`, { body: { column_id: targetCol } });
        }
      } else {
        await api('/tools/kanban/cards', { body: { column_id: targetCol || columnId, title, description: desc, priority: prio } });
      }
      onSave();
    } catch (e) { toast(e.message, 'error'); }
    finally { setSaving(false); }
  };

  const onKey = e => {
    if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) save();
    if (e.key === 'Escape') onClose();
  };

  return (
    <div onClick={e => e.target === e.currentTarget && onClose()}
      style={{ position:'fixed',inset:0,background:'rgba(0,0,0,0.7)',zIndex:1000,
        display:'flex',
        alignItems:isMob?'flex-end':'center',
        justifyContent:'center',
        padding:isMob?0:20,
        // Auf Mobile: unten Platz für die fixe Bottom-Nav (56px + safe-area) lassen
        paddingBottom: isMob ? 'calc(56px + env(safe-area-inset-bottom, 0px))' : 20,
      }}>
      <div style={{ background:'#1a1a1e',border:'1px solid rgba(255,255,255,0.12)',
        borderRadius:isMob?'16px 16px 0 0':14,
        width:'100%',maxWidth:460,
        display:'flex',flexDirection:'column',
        maxHeight: isMob ? '80vh' : '90vh',
      }}>
        {/* Drag-Handle + Header – immer sichtbar, nicht scrollend */}
        <div style={{ padding:'18px 20px 0', flexShrink:0 }}>
          {isMob && <div style={{ width:36,height:4,background:'rgba(255,255,255,0.15)',borderRadius:2,margin:'0 auto 14px' }}/>}
          <div style={{ display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:16 }}>
            <div style={{ ...S.head, marginBottom:0 }}>{card ? 'KARTE BEARBEITEN' : 'NEUE KARTE'}</div>
            <button onClick={onClose} style={{ background:'transparent',border:'none',color:'rgba(255,255,255,0.4)',cursor:'pointer',fontSize:18 }}>✕</button>
          </div>
        </div>

        {/* Scrollbarer Inhalt */}
        <div style={{ overflowY:'auto',padding:'0 20px',flex:1,scrollbarWidth:'thin',scrollbarColor:'rgba(255,255,255,0.08) transparent' }}>
          <input ref={titleRef} value={title} onChange={e=>setTitle(e.target.value)} onKeyDown={onKey}
            placeholder="Titel" style={{ ...S.inp, marginBottom:10 }} />

          <textarea value={desc} onChange={e=>setDesc(e.target.value)} onKeyDown={onKey}
            placeholder="Beschreibung (optional)" rows={3}
            style={{ ...S.inp, resize:'vertical', marginBottom:14 }} />

          {/* Priorität */}
          <div style={{ marginBottom:14 }}>
            <div style={{ ...S.head, marginBottom:8 }}>PRIORITÄT</div>
            <div style={{ display:'flex', gap:6, flexWrap:'wrap' }}>
              {PRIORITIES.map(p => (
                <button key={p.id} onClick={()=>setPrio(p.id)} style={{
                  ...S.btn(p.color, true),
                  background: prio===p.id ? `${p.color}28` : `${p.color}0e`,
                  borderColor: prio===p.id ? p.color : `${p.color}35`,
                  fontWeight: prio===p.id ? 700 : 400,
                }}>{p.label}</button>
              ))}
            </div>
          </div>

          {/* Verschieben nach */}
          <div style={{ marginBottom:14 }}>
            <div style={{ ...S.head, marginBottom:8 }}>{card ? 'VERSCHIEBEN NACH' : 'IN SPALTE'}</div>
            {!showNewCol ? (
              <div style={{ display:'flex', gap:6, flexWrap:'wrap' }}>
                {columns.map(c => (
                  <button key={c.id} onClick={()=>setMoveToCol(c.id)} style={{
                    ...S.btn(c.color || '#4ecdc4', true),
                    background: moveToCol===c.id ? `${c.color||'#4ecdc4'}28` : `${c.color||'#4ecdc4'}0e`,
                    borderColor: moveToCol===c.id ? (c.color||'#4ecdc4') : `${c.color||'#4ecdc4'}35`,
                    fontWeight: moveToCol===c.id ? 700 : 400,
                  }}>{c.title}</button>
                ))}
                <button onClick={()=>setShowNewCol(true)} style={S.btn('#888888', true)}>+ Neue Spalte</button>
              </div>
            ) : (
              <div style={{ display:'flex', gap:6 }}>
                <input ref={newColRef} value={newColName} onChange={e=>setNewColName(e.target.value)}
                  onKeyDown={e=>{ if(e.key==='Escape'){setShowNewCol(false);setNewColName('');} }}
                  placeholder="Name der neuen Spalte"
                  style={{ ...S.inp, flex:1, fontSize:12 }} />
                <button onClick={()=>{setShowNewCol(false);setNewColName('');}} style={S.btn('#888888',true)}>✕</button>
              </div>
            )}
          </div>
        </div>

        {/* Aktionsbuttons – immer sichtbar am unteren Rand, nicht scrollend */}
        <div style={{ padding:'14px 20px 24px', flexShrink:0, borderTop:'1px solid rgba(255,255,255,0.07)',
          display:'flex', gap:8, justifyContent:'flex-end' }}>
          <button onClick={onClose} style={S.btn('#888888', true)}>Abbrechen</button>
          <button onClick={save} disabled={!title.trim()||saving} style={S.btn('#4ecdc4', true)}>
            {saving ? '…' : card ? 'Speichern' : 'Erstellen'}
          </button>
        </div>
      </div>
    </div>
  );
}

// ── Spalten-Header ────────────────────────────────────────────────────────────
function ColumnHeader({ col, onUpdate, onDelete, toast }) {
  const [editTitle, setEditTitle] = useState(false);
  const [titleVal,  setTitleVal]  = useState(col.title);
  const [showColor, setShowColor] = useState(false);
  const inputRef = useRef(null);

  useEffect(() => { if (editTitle) inputRef.current?.focus(); }, [editTitle]);

  const commitTitle = async () => {
    setEditTitle(false);
    if (titleVal.trim() && titleVal.trim() !== col.title) {
      try { await onUpdate(col.id, { title: titleVal.trim() }); }
      catch (e) { toast(e.message, 'error'); setTitleVal(col.title); }
    } else { setTitleVal(col.title); }
  };

  const setColor = async (color) => {
    setShowColor(false);
    try { await onUpdate(col.id, { color }); }
    catch (e) { toast(e.message, 'error'); }
  };

  return (
    <div style={{ marginBottom:12 }}>
      {/* Farbstreifen oben */}
      <div style={{ height:3,borderRadius:'2px 2px 0 0',background:col.color||'#4ecdc4',margin:'-12px -12px 10px',marginTop:-12 }}/>

      <div style={{ display:'flex', alignItems:'center', gap:6 }}>
        {/* Farbpicker-Button */}
        <div style={{ position:'relative' }}>
          <button onClick={()=>setShowColor(v=>!v)} title="Farbe ändern"
            style={{ width:16,height:16,borderRadius:'50%',background:col.color||'#4ecdc4',
              border:'2px solid rgba(255,255,255,0.2)',cursor:'pointer',flexShrink:0,padding:0 }}/>
          {showColor && (
            <div style={{ position:'absolute',top:22,left:0,zIndex:200,
              background:'#1a1a1e',border:'1px solid rgba(255,255,255,0.12)',
              borderRadius:10,padding:8,display:'flex',flexWrap:'wrap',gap:6,width:130 }}>
              {COL_COLORS.map(c => (
                <button key={c} onClick={()=>setColor(c)} style={{
                  width:22,height:22,borderRadius:'50%',background:c,border:
                  (col.color||'#4ecdc4')===c?'2px solid #fff':'2px solid transparent',
                  cursor:'pointer',padding:0,transition:'border 0.1s',
                }}/>
              ))}
            </div>
          )}
        </div>

        {/* Titel */}
        {editTitle ? (
          <input ref={inputRef} value={titleVal} onChange={e=>setTitleVal(e.target.value)}
            onBlur={commitTitle}
            onKeyDown={e=>{ if(e.key==='Enter') commitTitle(); if(e.key==='Escape'){setTitleVal(col.title);setEditTitle(false);} }}
            style={{ ...S.inp, fontSize:12,fontWeight:700,padding:'3px 7px',flex:1 }} />
        ) : (
          <span onDoubleClick={()=>setEditTitle(true)} title="Doppelklick zum Umbenennen"
            style={{ flex:1,fontSize:12,fontWeight:700,fontFamily:'monospace',color:'#fff',
              cursor:'pointer',overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap' }}>
            {col.title}
          </span>
        )}

        <span style={{ color:'rgba(255,255,255,0.3)',fontSize:11,fontFamily:'monospace',flexShrink:0 }}>
          {col.cards.length}
        </span>
        <button onClick={()=>onDelete(col.id)} title="Spalte löschen"
          style={{ background:'transparent',border:'none',color:'rgba(255,255,255,0.2)',
            cursor:'pointer',fontSize:13,padding:'0 2px',lineHeight:1,flexShrink:0 }}>✕</button>
      </div>
    </div>
  );
}

// ── Einzelne Karte ─────────────────────────────────────────────────────────────
function KanbanCard({ card, col, allCols, onEdit, onDelete, onMove, isDragging, dragHandlers }) {
  const prio     = prioOf(card.priority);
  const colIdx   = allCols.findIndex(c => c.id === col.id);
  const cardIdx  = col.cards.findIndex(c => c.id === card.id);
  const isFirst  = cardIdx === 0;
  const isLast   = cardIdx === col.cards.length - 1;
  const isFirstCol = colIdx === 0;
  const isLastCol  = colIdx === allCols.length - 1;

  const arrowBtn = (label, disabled, onClick) => (
    <button onClick={disabled ? undefined : onClick} disabled={disabled}
      style={{ background:'transparent',border:'none',padding:'1px 4px',lineHeight:1,fontSize:13,
        color: disabled ? 'rgba(255,255,255,0.1)' : 'rgba(255,255,255,0.4)',
        cursor: disabled ? 'default' : 'pointer' }}>
      {label}
    </button>
  );

  return (
    <div {...dragHandlers} style={{
      background: isDragging ? 'rgba(78,205,196,0.06)' : 'rgba(255,255,255,0.04)',
      border: `1px solid ${isDragging ? '#4ecdc4' : 'rgba(255,255,255,0.08)'}`,
      borderLeft: `3px solid ${prio.color}`,
      borderRadius:8, padding:'10px 10px 8px', marginBottom:6,
      cursor:'grab', opacity: isDragging ? 0.45 : 1,
      transition:'border-color 0.12s, opacity 0.12s', userSelect:'none',
    }}>
      {/* Titel-Zeile */}
      <div style={{ display:'flex',alignItems:'flex-start',gap:6,marginBottom:card.description?6:8 }}>
        <span style={{ flex:1,fontSize:13,fontFamily:'monospace',color:'#fff',wordBreak:'break-word',lineHeight:1.4 }}>
          {card.title}
        </span>
        <div style={{ display:'flex',gap:3,flexShrink:0 }}>
          <button onClick={()=>onEdit(card)} title="Bearbeiten"
            style={{ background:'transparent',border:'none',color:'rgba(255,255,255,0.35)',
              cursor:'pointer',fontSize:12,padding:'1px 3px',lineHeight:1 }}>✎</button>
          <button onClick={()=>onDelete(card.id)} title="Löschen"
            style={{ background:'transparent',border:'none',color:'rgba(255,255,255,0.2)',
              cursor:'pointer',fontSize:12,padding:'1px 3px',lineHeight:1 }}>✕</button>
        </div>
      </div>

      {/* Beschreibung */}
      {card.description && (
        <div style={{ fontSize:11,color:'rgba(255,255,255,0.4)',fontFamily:'monospace',
          lineHeight:1.4,whiteSpace:'pre-wrap',wordBreak:'break-word',marginBottom:8 }}>
          {card.description}
        </div>
      )}

      {/* Priorität + Pfeile */}
      <div style={{ display:'flex',alignItems:'center',justifyContent:'space-between',gap:4 }}>
        {prio.id !== 'none' ? (
          <span style={{ fontSize:9,fontFamily:'monospace',letterSpacing:1,
            color:prio.color, background:`${prio.color}15`,
            border:`1px solid ${prio.color}30`, borderRadius:4, padding:'1px 5px' }}>
            {prio.label.toUpperCase()}
          </span>
        ) : <span/>}

        <div style={{ display:'flex',gap:0,flexShrink:0 }}>
          {arrowBtn('↑', isFirst,  ()=>onMove(card.id, col.id, cardIdx-1))}
          {arrowBtn('↓', isLast,   ()=>onMove(card.id, col.id, cardIdx+1))}
          {arrowBtn('←', isFirstCol, ()=>onMove(card.id, allCols[colIdx-1]?.id))}
          {arrowBtn('→', isLastCol,  ()=>onMove(card.id, allCols[colIdx+1]?.id))}
        </div>
      </div>

      {/* Erstellungsdatum */}
      {card.created_at && (
        <div style={{ fontSize:9,fontFamily:'monospace',color:'rgba(255,255,255,0.2)',
          marginTop:6, textAlign:'right', letterSpacing:0.5 }}>
          {fmtCardDate(card.created_at)}
        </div>
      )}
    </div>
  );
}

// ── Hauptkomponente ───────────────────────────────────────────────────────────
export default function Kanban({ toast, mobile }) {
  const [columns,     setColumns]     = useState([]);
  const [loading,     setLoading]     = useState(true);
  const [modal,       setModal]       = useState(null); // null | { card?, columnId }
  const [newColInput, setNewColInput] = useState('');
  const [addingCol,   setAddingCol]   = useState(false);
  const [dragCardId,  setDragCardId]  = useState(null);
  const [dragOverCol, setDragOverCol] = useState(null);
  const [dragOverPos, setDragOverPos] = useState(null);
  const newColRef = useRef(null);

  const load = useCallback(() => {
    setLoading(true);
    api('/tools/kanban/board')
      .then(d => setColumns(d.columns || []))
      .catch(() => toast('Fehler beim Laden', 'error'))
      .finally(() => setLoading(false));
  }, []);

  useEffect(() => { load(); }, [load]);
  useEffect(() => { if (addingCol) newColRef.current?.focus(); }, [addingCol]);

  // ── Spalten-Aktionen ────────────────────────────────────────────────────────
  const addColumn = async () => {
    if (!newColInput.trim()) return;
    try {
      await api('/tools/kanban/columns', { body: { title: newColInput.trim() } });
      setNewColInput(''); setAddingCol(false); load();
    } catch (e) { toast(e.message, 'error'); }
  };

  const updateColumn = async (id, patch) => {
    await api(`/tools/kanban/columns/${id}`, { method:'PATCH', body: patch });
    load();
  };

  const deleteColumn = async (id) => {
    const col = columns.find(c => c.id === id);
    const msg = col?.cards?.length
      ? `Spalte "${col.title}" und alle ${col.cards.length} Karte(n) löschen?`
      : `Spalte "${col?.title}" löschen?`;
    if (!confirm(msg)) return;
    try { await api(`/tools/kanban/columns/${id}`, { method:'DELETE' }); load(); }
    catch (e) { toast(e.message, 'error'); }
  };

  // ── Karten-Aktionen ─────────────────────────────────────────────────────────
  const deleteCard = async (id) => {
    if (!confirm('Karte löschen?')) return;
    try { await api(`/tools/kanban/cards/${id}`, { method:'DELETE' }); load(); }
    catch (e) { toast(e.message, 'error'); }
  };

  const moveCard = async (cardId, colIdOrPos, posOrUndef) => {
    // Aufruf-Varianten:
    // onMove(id, col.id, newPos)  → Position innerhalb Spalte
    // onMove(id, targetColId)     → Spalte wechseln, ans Ende
    try {
      if (posOrUndef !== undefined) {
        await api(`/tools/kanban/cards/${cardId}/move`, { body:{ column_id:colIdOrPos, position:posOrUndef } });
      } else {
        await api(`/tools/kanban/cards/${cardId}/move`, { body:{ column_id:colIdOrPos } });
      }
      load();
    } catch (e) { toast(e.message, 'error'); }
  };

  // ── Drag & Drop ─────────────────────────────────────────────────────────────
  const onDragStart = (e, cardId) => {
    setDragCardId(cardId);
    e.dataTransfer.effectAllowed = 'move';
  };
  const onDragEnd = () => { setDragCardId(null); setDragOverCol(null); setDragOverPos(null); };

  const onDragOverCard = (e, colId, pos) => {
    e.preventDefault(); e.stopPropagation();
    e.dataTransfer.dropEffect = 'move';
    setDragOverCol(colId); setDragOverPos(pos);
  };
  const onDragOverColBg = (e, colId) => {
    e.preventDefault();
    e.dataTransfer.dropEffect = 'move';
    const col = columns.find(c => c.id === colId);
    setDragOverCol(colId); setDragOverPos(col ? col.cards.length : 0);
  };
  const onDrop = async (e, colId, pos) => {
    e.preventDefault();
    if (!dragCardId) return;
    const targetPos = pos !== undefined ? pos : dragOverPos;
    setDragCardId(null); setDragOverCol(null); setDragOverPos(null);
    try {
      await api(`/tools/kanban/cards/${dragCardId}/move`, { body:{ column_id:colId, position:targetPos } });
      load();
    } catch (err) { toast(err.message, 'error'); }
  };

  // ── Render ────────────────────────────────────────────────────────────────────
  if (loading) return (
    <div style={{ padding: mobile ? '14px 14px 90px' : '36px 44px' }}>
      <div style={{ color:'rgba(255,255,255,0.35)',fontFamily:'monospace',fontSize:12 }}>Lädt…</div>
    </div>
  );

  return (
    <div style={{ padding: mobile ? '14px 14px 90px' : '36px 44px', height:'100%', boxSizing:'border-box', display:'flex', flexDirection:'column' }}>

      {/* ── Header ─────────────────────────────────────────────────────────── */}
      <div style={{ display:'flex', alignItems:'center', gap:10, marginBottom:24, flexWrap:'wrap' }}>
        <h2 style={{ margin:0, fontSize:15, fontFamily:'monospace', color:'rgba(255,255,255,0.55)', letterSpacing:2, fontWeight:400 }}>
          KANBAN BOARD
        </h2>
        <div style={{ flex:1 }}/>
        {addingCol ? (
          <div style={{ display:'flex', gap:6 }}>
            <input ref={newColRef} value={newColInput} onChange={e=>setNewColInput(e.target.value)}
              onKeyDown={e=>{ if(e.key==='Enter') addColumn(); if(e.key==='Escape'){setAddingCol(false);setNewColInput('');} }}
              placeholder="Spaltenname" style={{ ...S.inp, width: mobile?140:180, fontSize:12 }} />
            <button onClick={addColumn} style={S.btn('#4ecdc4', true)}>Hinzufügen</button>
            <button onClick={()=>{setAddingCol(false);setNewColInput('');}} style={S.btn('#888888', true)}>✕</button>
          </div>
        ) : (
          <button onClick={()=>setAddingCol(true)} style={S.btn('#4ecdc4', true)}>+ Spalte</button>
        )}
      </div>

      {/* ── Board ──────────────────────────────────────────────────────────── */}
      {columns.length === 0 ? (
        <div style={{ ...S.card, textAlign:'center', padding:40 }}>
          <div style={{ color:'rgba(255,255,255,0.25)',fontFamily:'monospace',fontSize:12 }}>
            Noch keine Spalten. Erstelle eine Spalte um loszulegen.
          </div>
        </div>
      ) : (
        <div style={{ display:'flex', gap:14, overflowX:'auto', flex:1,
          paddingBottom:12, scrollbarWidth:'thin', scrollbarColor:'rgba(255,255,255,0.08) transparent' }}>
          {columns.map(col => (
            <div key={col.id}
              onDragOver={e=>onDragOverColBg(e, col.id)}
              onDrop={e=>onDrop(e, col.id, col.cards.length)}
              style={{
                ...S.card,
                minWidth: mobile ? 260 : 280,
                maxWidth: 320,
                width: mobile ? 260 : 280,
                flexShrink:0,
                display:'flex', flexDirection:'column',
                padding:12, overflow:'hidden',
                border:`1px solid ${dragOverCol===col.id && dragCardId ? (col.color||'#4ecdc4')+'66' : 'rgba(255,255,255,0.07)'}`,
                transition:'border-color 0.15s',
              }}>

              <ColumnHeader col={col} onUpdate={updateColumn} onDelete={deleteColumn} toast={toast}/>

              {/* Karten-Liste */}
              <div style={{ flex:1, overflowY:'auto', scrollbarWidth:'thin', scrollbarColor:'rgba(255,255,255,0.08) transparent' }}>
                {col.cards.map((card, cardIdx) => (
                  <div key={card.id}
                    onDragOver={e=>onDragOverCard(e, col.id, cardIdx)}
                    onDrop={e=>{ e.stopPropagation(); onDrop(e, col.id, cardIdx); }}>
                    {dragCardId && dragOverCol===col.id && dragOverPos===cardIdx && (
                      <div style={{ height:3,background:col.color||'#4ecdc4',borderRadius:2,marginBottom:4,opacity:0.7 }}/>
                    )}
                    <KanbanCard
                      card={card} col={col} allCols={columns}
                      onEdit={card=>setModal({ card, columnId:col.id })}
                      onDelete={deleteCard}
                      onMove={moveCard}
                      isDragging={dragCardId===card.id}
                      dragHandlers={{ draggable:true, onDragStart:e=>onDragStart(e,card.id), onDragEnd }}
                    />
                  </div>
                ))}
                {dragCardId && dragOverCol===col.id && dragOverPos===col.cards.length && (
                  <div style={{ height:3,background:col.color||'#4ecdc4',borderRadius:2,marginTop:2,opacity:0.7 }}/>
                )}
              </div>

              {/* Karte hinzufügen */}
              <button onClick={()=>setModal({ card:null, columnId:col.id })}
                style={{ ...S.btn(col.color||'#4ecdc4', true), width:'100%', marginTop:10, textAlign:'center' }}>
                + Karte
              </button>
            </div>
          ))}
        </div>
      )}

      {/* ── Modal ──────────────────────────────────────────────────────────── */}
      {modal && (
        <CardModal
          card={modal.card}
          columnId={modal.columnId}
          columns={columns}
          onSave={()=>{ setModal(null); load(); }}
          onClose={()=>setModal(null)}
          toast={toast}
        />
      )}
    </div>
  );
}
