/* Sprint Planner — Kanban Board view.
   Used when a project's cadence is Kanban (continuous flow), and available as a
   switchable view for any project. Columns are statuses, cards are tickets,
   columns carry WIP limits. Estimates render in the project's unit via ProjConfig. */

const { useState: useStateBd, useEffect: useEffectBd, useMemo: useMemoBd } = React;

const KANBAN_COLS = [
  { id: 'backlog', name: 'Backlog',     wip: 0, tone: 'var(--ink-4)' },
  { id: 'todo',    name: 'To do',       wip: 0, tone: 'var(--ink-3)' },
  { id: 'doing',   name: 'In progress', wip: 5, tone: 'var(--accent)' },
  { id: 'review',  name: 'In review',   wip: 3, tone: 'oklch(0.55 0.13 295)' },
  { id: 'done',    name: 'Done',        wip: 0, tone: 'var(--good)' },
];

/* Deterministic seed status (planner tickets carry no status field) */
function seedStatus(t, i) {
  const n = parseInt(String(t.id).replace(/\D/g, '').slice(-1), 10);
  const cycle = ['doing', 'review', 'done', 'todo', 'doing', 'backlog', 'review', 'done', 'todo', 'doing'];
  return cycle[(isNaN(n) ? i : n) % cycle.length];
}

function Board({ tickets, onRemove }) {
  const [cols, setCols] = useStateBd(() => {
    const m = {}; KANBAN_COLS.forEach(c => m[c.id] = []);
    tickets.forEach((t, i) => { const s = seedStatus(t, i); (m[s] || m.todo).push(t.id); });
    return m;
  });
  const [drag, setDrag] = useStateBd(null);
  const [over, setOver] = useStateBd(null);

  // keep placements stable across ticket changes; place new tickets, drop removed
  useEffectBd(() => {
    setCols(prev => {
      const ids = new Set(tickets.map(t => t.id));
      const m = {}; KANBAN_COLS.forEach(c => m[c.id] = []);
      const placed = new Set();
      KANBAN_COLS.forEach(c => (prev[c.id] || []).forEach(id => { if (ids.has(id) && !placed.has(id)) { m[c.id].push(id); placed.add(id); } }));
      tickets.forEach((t, i) => { if (!placed.has(t.id)) { const s = seedStatus(t, i); (m[s] || m.todo).push(t.id); } });
      return m;
    });
  }, [tickets]);

  const byId = useMemoBd(() => Object.fromEntries(tickets.map(t => [t.id, t])), [tickets]);

  const move = (id, toCol) => setCols(prev => {
    const m = {}; KANBAN_COLS.forEach(c => m[c.id] = (prev[c.id] || []).filter(x => x !== id));
    m[toCol] = [...m[toCol], id];
    return m;
  });

  return (
    <div className="kanban">
      {KANBAN_COLS.map(c => {
        const ids = cols[c.id] || [];
        const wipOver = c.wip > 0 && ids.length > c.wip;
        return (
          <section key={c.id}
            className={"kcol" + (wipOver ? " is-overwip" : "") + (over === c.id ? " is-drop" : "")}
            onDragOver={e => { e.preventDefault(); setOver(c.id); }}
            onDragLeave={() => setOver(o => o === c.id ? null : o)}
            onDrop={e => { e.preventDefault(); if (drag) move(drag, c.id); setDrag(null); setOver(null); }}>
            <header className="kcol__head">
              <span className="kcol__dot" style={{ background: c.tone }} />
              <span className="kcol__name">{c.name}</span>
              <span className="kcol__count">{ids.length}{c.wip > 0 ? ` / ${c.wip}` : ''}</span>
            </header>
            {wipOver && <div className="kcol__wipwarn"><Icon d={ICONS.alert} size={11} /> Over WIP limit — finish work before pulling more</div>}
            <div className="kcol__list">
              {ids.map(id => {
                const t = byId[id]; if (!t) return null;
                const p = PEOPLE.find(x => x.id === t.assignee);
                const est = window.ProjConfig ? ProjConfig.estLabel(t.hours) : t.hours + 'h';
                return (
                  <article key={id} className="kcard" draggable data-type={t.type}
                    onDragStart={() => setDrag(id)} onDragEnd={() => { setDrag(null); setOver(null); }}>
                    <div className="kcard__top">
                      <span className="kcard__type">{TYPE_LABEL[t.type]}</span>
                      <span className="kcard__id">{t.id}</span>
                      {t.priority && <span className="kcard__prio">{t.priority}</span>}
                    </div>
                    <div className="kcard__title">{t.title}</div>
                    <div className="kcard__foot">
                      {p
                        ? <span className="avatar avatar--sm" data-tone={p.tone} title={p.name}>{p.name.charAt(0)}</span>
                        : <span className="kcard__unassigned">unassigned</span>}
                      {est && <span className="kcard__est">{est}</span>}
                    </div>
                  </article>
                );
              })}
              {ids.length === 0 && <div className="kcol__empty">Drop here</div>}
            </div>
          </section>
        );
      })}
    </div>
  );
}

window.Board = Board;
