/* AllocationStrip + AllocationBar — visual primitives for percentage allocations
 *
 * AllocationStrip: full row with stacked bar + per-dimension chips
 * AllocationBar:   thin stacked bar only (no chips)
 * AllocationDiff:  side-by-side before/after for git-log entries
 */

const { useState: useStateA } = React;

/* Colors are derived from the dimension tint, modulated by the work group's
 * position so each chip is visually distinguishable. */
function allocColor(groupId) {
  const wg = window.wgById[groupId];
  if (!wg) return "#888";
  const dim = window.dimById[wg.dimensionId];
  // Build a palette per dimension: dim.tint as base; cycle hue offsets
  const peers = window.WORK_GROUPS.filter(g => g.dimensionId === wg.dimensionId);
  const idx = peers.findIndex(p => p.id === groupId);
  // Build a few light/dark tonal variants of dim.tint
  const PALETTES = {
    "dim-bubble":  ["#FF2E5B", "#C72548", "#FF587C", "#FF829D", "#FFABBD", "#8C1D38", "#BB8FE3", "#7A5AE0"],
    "dim-country": ["#4E7BB3", "#365A88", "#7AA0CC", "#A8C2DE"],
    "dim-other":   ["#C58A2C", "#8C5E12", "#E9B254", "#2D8A4A"],
  };
  const palette = PALETTES[wg.dimensionId] || [dim?.tint || "#888"];
  return palette[idx % palette.length];
}
window.allocColor = allocColor;

function AllocationBar({ allocations, height = 10, showLabels = false, onClickGroup }) {
  const sum = (allocations || []).reduce((s, a) => s + a.pct, 0);
  // If sum > 100, scale to 100. If sum < 100, leave empty trailing space.
  const denom = Math.max(sum, 100);
  return (
    <div className="alloc-bar" style={{ height }}>
      {(allocations || []).map((a, i) => {
        const w = (a.pct / denom) * 100;
        const wg = window.wgById[a.groupId];
        return (
          <div key={i} className="alloc-seg"
            style={{ width: `${w}%`, background: allocColor(a.groupId) }}
            title={`${wg?.name || a.groupId} · ${a.pct}%`}
            onClick={onClickGroup ? (e) => { e.stopPropagation(); onClickGroup(a.groupId); } : undefined}>
            {showLabels && w > 8 && <span className="alloc-seg-label">{a.pct}%</span>}
          </div>
        );
      })}
      {sum < 100 && (
        <div className="alloc-seg alloc-seg-empty" style={{ width: `${((100 - sum) / denom) * 100}%` }}
          title={`${100 - sum}% unallocated`} />
      )}
    </div>
  );
}
window.AllocationBar = AllocationBar;

function AllocationChip({ allocation, onClick, dense = false }) {
  const wg = window.wgById[allocation.groupId];
  const dim = wg ? window.dimById[wg.dimensionId] : null;
  const crumb = wg ? window.workGroupBreadcrumb(wg.id).map(b => b.name).join(" / ") : allocation.groupId;
  const color = allocColor(allocation.groupId);
  return (
    <button className={`alloc-chip ${dense ? "alloc-chip-dense" : ""}`}
      style={{ "--alloc-color": color }}
      onClick={onClick} title={`${dim?.name} dimension`}>
      <span className="alloc-chip-swatch" />
      {!dense && dim && <span className="alloc-chip-dim">{dim.short || dim.name}</span>}
      <span className="alloc-chip-name">{crumb}</span>
      <span className="alloc-chip-pct">{allocation.pct}%</span>
    </button>
  );
}
window.AllocationChip = AllocationChip;

function AllocationStrip({ allocations, go, compact = false }) {
  const sum = (allocations || []).reduce((s, a) => s + a.pct, 0);
  const status = window.allocationStatus(allocations);
  if (!allocations || allocations.length === 0) {
    return <div className="alloc-strip-empty">No active allocations.</div>;
  }
  return (
    <div className="alloc-strip">
      <div className="alloc-strip-bar-row">
        <AllocationBar allocations={allocations} height={compact ? 8 : 12} showLabels={!compact} />
        <span className={`alloc-sum alloc-sum-${status.kind}`} title={
          status.kind === "ok" ? "Fully allocated" :
          status.kind === "over" ? `Over-allocated by ${Math.round(status.sum - 100)}%` :
          `Under-allocated — ${Math.round(100 - status.sum)}% unassigned`
        }>
          {status.kind === "over" && <Icon name="alert" />}
          {status.kind === "under" && <Icon name="info-circle" />}
          {status.kind === "ok" && <Icon name="check-circle" />}
          <strong>{Math.round(status.sum)}%</strong>
        </span>
      </div>
      <div className="alloc-chips">
        {allocations.map((a, i) => (
          <AllocationChip key={i} allocation={a} onClick={() => go && go("team", { id: a.groupId })} dense={compact} />
        ))}
      </div>
    </div>
  );
}
window.AllocationStrip = AllocationStrip;

/* Side-by-side diff used in git log */
function AllocationDiff({ from, to, note }) {
  return (
    <div className="alloc-diff">
      <div className="alloc-diff-side">
        <div className="alloc-diff-h">Before</div>
        <AllocationBar allocations={from} height={8} />
        <div className="alloc-diff-list">
          {from.map((a, i) => (
            <div key={i} className="alloc-diff-row">
              <span className="alloc-chip-swatch" style={{ background: allocColor(a.groupId) }} />
              <span className="alloc-diff-name">{window.wgById[a.groupId]?.name}</span>
              <span className="alloc-diff-pct">{a.pct}%</span>
            </div>
          ))}
        </div>
      </div>
      <Icon name="arrow-right" style={{ alignSelf: "center", color: "var(--fg-3)", flexShrink: 0 }} />
      <div className="alloc-diff-side">
        <div className="alloc-diff-h">After</div>
        <AllocationBar allocations={to} height={8} />
        <div className="alloc-diff-list">
          {to.map((a, i) => {
            const beforePct = from.find(f => f.groupId === a.groupId)?.pct ?? 0;
            const delta = a.pct - beforePct;
            return (
              <div key={i} className="alloc-diff-row">
                <span className="alloc-chip-swatch" style={{ background: allocColor(a.groupId) }} />
                <span className="alloc-diff-name">{window.wgById[a.groupId]?.name}</span>
                <span className="alloc-diff-pct">
                  {a.pct}%
                  {delta !== 0 && (
                    <span className={`alloc-delta ${delta > 0 ? "pos" : "neg"}`}>
                      {delta > 0 ? "+" : ""}{delta}
                    </span>
                  )}
                </span>
              </div>
            );
          })}
        </div>
      </div>
      {note && <div className="alloc-diff-note">{note}</div>}
    </div>
  );
}
window.AllocationDiff = AllocationDiff;

/* ===== AllocateForm — drawer body for adjusting capacity allocations ===== */
function AllocateForm({ person, cur }) {
  const initial = (cur?.allocations || []).map(a => ({ ...a }));
  const [allocs, setAllocs] = useStateA(initial.length ? initial : [{ groupId: "wg-wealth", pct: 100 }]);
  const [effective, setEffective] = useStateA(window.dstr(new Date(window.TODAY.getFullYear(), window.TODAY.getMonth() + 1, 1)));
  const [note, setNote] = useStateA("");

  const sum = allocs.reduce((s, a) => s + (parseFloat(a.pct) || 0), 0);
  const status = window.allocationStatus(allocs);

  const update = (i, key, value) => {
    setAllocs(allocs.map((a, j) => j === i ? { ...a, [key]: key === "pct" ? Number(value) : value } : a));
  };
  const remove = (i) => setAllocs(allocs.filter((_, j) => j !== i));
  const add = () => {
    const usedIds = new Set(allocs.map(a => a.groupId));
    const next = window.WORK_GROUPS.find(g => !usedIds.has(g.id));
    setAllocs([...allocs, { groupId: next?.id || "wg-wealth", pct: 0 }]);
  };
  const balance = () => {
    // proportionally scale to 100
    if (sum === 0) return;
    setAllocs(allocs.map(a => ({ ...a, pct: Math.round((a.pct / sum) * 100) })));
  };

  return (
    <>
      <div className="field">
        <label>Effective from</label>
        <div className="ctrl">
          <Icon name="calendar" style={{ color: "var(--fg-4)" }} />
          <input value={effective} onChange={(e) => setEffective(e.target.value)} />
        </div>
        <span className="hint">Future-dated changes are accepted — the previous record will be closed automatically on this date.</span>
      </div>

      <div>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 8 }}>
          <label style={{ fontSize: 11, fontWeight: 500, color: "var(--fg-3)", letterSpacing: "0.04em" }}>Allocations</label>
          <div style={{ display: "flex", gap: 6, alignItems: "center" }}>
            <span className={`alloc-sum alloc-sum-${status.kind}`}>
              {status.kind === "over" && <Icon name="alert" />}
              {status.kind === "under" && <Icon name="info-circle" />}
              {status.kind === "ok" && <Icon name="check-circle" />}
              <strong>{Math.round(sum)}%</strong>
            </span>
            {Math.round(sum) !== 100 && (
              <button className="btn btn-ghost" style={{ height: 22, padding: "0 6px", fontSize: 11 }} onClick={balance}>Balance to 100%</button>
            )}
          </div>
        </div>

        <div className="alloc-form-list">
          {allocs.map((a, i) => {
            const wg = window.wgById[a.groupId];
            const dim = wg ? window.dimById[wg.dimensionId] : null;
            return (
              <div key={i} className="alloc-form-row">
                <span className="alloc-chip-swatch" style={{ background: window.allocColor(a.groupId), width: 10, height: 10 }} />
                <select value={a.groupId} onChange={(e) => update(i, "groupId", e.target.value)} className="alloc-form-select">
                  {window.DIMENSIONS.map(x => (
                    <optgroup key={x.id} label={x.name}>
                      {window.WORK_GROUPS.filter(g => g.dimensionId === x.id).map(g => {
                        const cb = window.workGroupBreadcrumb(g.id).map(b => b.name).join(" / ");
                        return <option key={g.id} value={g.id}>{cb}</option>;
                      })}
                    </optgroup>
                  ))}
                </select>
                <input type="number" min="0" max="100" value={a.pct} onChange={(e) => update(i, "pct", e.target.value)} className="alloc-form-pct" />
                <span style={{ color: "var(--fg-3)", fontSize: 12 }}>%</span>
                <button className="btn btn-icon btn-ghost" onClick={() => remove(i)} title="Remove" style={{ height: 26, width: 26 }}><Icon name="cancel" /></button>
              </div>
            );
          })}
          <button className="btn btn-ghost" onClick={add} style={{ alignSelf: "flex-start", height: 26 }}>
            <Icon name="plus" />Add allocation
          </button>
        </div>

        <div style={{ marginTop: 10 }}>
          <window.AllocationBar allocations={allocs} height={12} showLabels />
        </div>
      </div>

      <div className="field">
        <label>Note (visible in event log)</label>
        <div className="ctrl"><textarea rows={2} value={note} onChange={(e) => setNote(e.target.value)} placeholder="Why this re-allocation…" style={{ resize: "vertical", height: 50 }} /></div>
      </div>

      <div className="diff-preview">
        <div className="dp-title">Change preview</div>
        <window.AllocationDiff from={cur?.allocations || []} to={allocs} note={note || null} />
      </div>
    </>
  );
}
window.AllocateForm = AllocateForm;
