/* Krytz · Priority recompute demo
 *
 * Tasks carry 7 signals. Weighted sum yields a score 0-1.
 * Sliders adjust weights, a "deadline" slider adjusts the focused
 * task's deadline-pressure. The list re-sorts live with FLIP
 * animation (absolute positioning + transition transform).
 */

(function () {
  const { useState, useMemo, useRef, useLayoutEffect } = React;

  const ROW_H = 72;
  const ROW_GAP = 8;

  const SIGNALS = ['urgency', 'dependency', 'deadline', 'recency', 'mention', 'fit', 'effort'];

  const TASKS = [
    { id: 'bug',     title: 'Fix staging deploy bug',     project: 'Eng',     base: { urgency: 0.92, dependency: 0.88, deadline: 0.62, recency: 0.80, mention: 0.40, fit: 0.70, effort: 0.30 } },
    { id: 'asha',    title: 'Send Asha proposal v3',     project: 'Sales',   base: { urgency: 0.74, dependency: 0.50, deadline: 0.84, recency: 0.65, mention: 0.85, fit: 0.78, effort: 0.55 } },
    { id: 'deck',    title: 'Q3 investor deck',          project: 'GTM',     base: { urgency: 0.65, dependency: 0.35, deadline: 0.55, recency: 0.45, mention: 0.55, fit: 0.62, effort: 0.78 } },
    { id: 'qa',      title: 'QA sign-off for v2.3',      project: 'Eng',     base: { urgency: 0.70, dependency: 0.80, deadline: 0.50, recency: 0.72, mention: 0.30, fit: 0.66, effort: 0.42 } },
    { id: 'docs',    title: 'Update API docs',           project: 'Eng',     base: { urgency: 0.32, dependency: 0.18, deadline: 0.28, recency: 0.30, mention: 0.20, fit: 0.50, effort: 0.40 } },
    { id: 'metrics', title: 'Q3 metrics review',         project: 'Strat',   base: { urgency: 0.45, dependency: 0.40, deadline: 0.36, recency: 0.55, mention: 0.45, fit: 0.58, effort: 0.62 } },
  ];

  function computeScore(base, weights, override) {
    let total = 0, sum = 0;
    SIGNALS.forEach((s) => {
      const w = weights[s];
      let v = base[s];
      if (override && override[s] !== undefined) v = override[s];
      if (s === 'effort') v = 1 - v; // less effort is better
      total += v * w;
      sum += w;
    });
    return sum > 0 ? total / sum : 0;
  }

  function PriorityRecompute() {
    const [weights, setWeights] = useState({
      urgency: 1.0, dependency: 0.9, deadline: 0.9,
      recency: 0.4, mention: 0.5, fit: 0.6, effort: 0.5,
    });
    const [focusId, setFocusId] = useState('asha');
    const [focusDeadline, setFocusDeadline] = useState(0.84);

    const ranked = useMemo(() => {
      const scored = TASKS.map((t) => {
        const override = t.id === focusId ? { deadline: focusDeadline } : null;
        return { ...t, score: computeScore(t.base, weights, override), override };
      });
      scored.sort((a, b) => b.score - a.score);
      return scored.map((t, i) => ({ ...t, rank: i }));
    }, [weights, focusId, focusDeadline]);

    const prevRank = useRef({});
    const deltaMap = useMemo(() => {
      const m = {};
      ranked.forEach((t) => {
        const prev = prevRank.current[t.id];
        m[t.id] = prev === undefined ? 0 : prev - t.rank;
      });
      return m;
    }, [ranked]);

    useLayoutEffect(() => {
      const next = {};
      ranked.forEach((t) => { next[t.id] = t.rank; });
      prevRank.current = next;
    }, [ranked]);

    const setW = (key, v) => setWeights((w) => ({ ...w, [key]: v }));

    return (
      <div className="pr-grid">
        <div className="pr-controls">
          <h4>Signal weights</h4>
          <div className="pr-sub">Drag to rebalance — list resorts live</div>

          {SIGNALS.map((s) => (
            <div key={s} className="pr-slider-row">
              <div className="pr-slabel">
                <span>{s}</span>
                <span className="v">{weights[s].toFixed(2)}</span>
              </div>
              <input
                type="range" min="0" max="1.5" step="0.01"
                value={weights[s]}
                onChange={(e) => setW(s, parseFloat(e.target.value))}
                className="pr-slider"
              />
            </div>
          ))}

          <div className="pr-task-select">
            <h4>Override · deadline pressure</h4>
            <div className="pr-sub">Pick a task, drag its deadline closer</div>

            <div className="pr-task-select-list">
              {TASKS.map((t) => (
                <button
                  key={t.id}
                  className={t.id === focusId ? 'is-on' : ''}
                  onClick={() => {
                    setFocusId(t.id);
                    setFocusDeadline(t.base.deadline);
                  }}
                >
                  {t.title}
                </button>
              ))}
            </div>

            <div className="pr-slider-row" style={{ marginTop: 16 }}>
              <div className="pr-slabel">
                <span>deadline · {focusId}</span>
                <span className="v">{focusDeadline.toFixed(2)}</span>
              </div>
              <input
                type="range" min="0" max="1" step="0.01"
                value={focusDeadline}
                onChange={(e) => setFocusDeadline(parseFloat(e.target.value))}
                className="pr-slider"
              />
            </div>
          </div>
        </div>

        <div className="pr-list" style={{ height: (ROW_H + ROW_GAP) * ranked.length }}>
          {ranked.map((t) => {
            const delta = deltaMap[t.id] || 0;
            return (
              <div
                key={t.id}
                className={`pr-row is-rank-${t.rank + 1} ${t.id === focusId ? 'is-focus' : ''}`}
                style={{ transform: `translateY(${t.rank * (ROW_H + ROW_GAP)}px)` }}
              >
                <div className="pr-rank">#{t.rank + 1}</div>
                <div>
                  <div className="pr-title">{t.title}</div>
                  <div className="pr-meta">
                    <span className="m"><strong>{t.project}</strong></span>
                    <span className="m">U <strong>{t.base.urgency.toFixed(2)}</strong></span>
                    <span className="m">D <strong>{(t.override?.deadline ?? t.base.deadline).toFixed(2)}</strong></span>
                    <span className="m">dep <strong>{t.base.dependency.toFixed(2)}</strong></span>
                  </div>
                </div>
                <div className="pr-score">
                  <span className="num">{t.score.toFixed(3)}</span>
                  <span className={`delta ${delta > 0 ? 'up' : delta < 0 ? 'down' : ''}`}>
                    {delta === 0 ? '· stable' : (delta > 0 ? `▲ ${delta}` : `▼ ${Math.abs(delta)}`)}
                  </span>
                </div>
                <div className="pr-bar" style={{ width: `${t.score * 100}%` }} />
              </div>
            );
          })}
        </div>
      </div>
    );
  }

  window.PriorityRecompute = PriorityRecompute;
})();
