// zephyr-release-status.jsx
// Shared "Release readiness" header + "Critical path" banner used by all 3 views.
// Computes per-release roll-up + highlights the next release's at-risk + must-start-now items.
//
// At-risk rule: epic.status !== "done" AND end-date is within 14 days of today (or already past).
// Critical-path: items inside the *next upcoming* release that are at-risk OR not started yet.

const RS_D = window.ZEPHYR_DATA;
const RS_C = window.ZephyrComponents;

const RELEASES = [
  { id: "demo", label: "Demo Release",      shortLabel: "Demo",      endDate: "2026-04-28" },
  { id: "r1",   label: "Release 1 · 30-Day", shortLabel: "R1 · 30d", endDate: "2026-05-28" },
  { id: "r2",   label: "Release 2 · 60-Day", shortLabel: "R2 · 60d", endDate: "2026-06-27" },
  { id: "r3",   label: "Release 3 · 90-Day", shortLabel: "R3 · 90d", endDate: "2026-07-27" },
];

// "Today" in this prototype — anchor to the program update date so the
// readiness math stays meaningful even when viewed later.
const RS_TODAY = "2026-04-25";

function rsDaysBetween(a, b) {
  const ms = (new Date(b) - new Date(a));
  return Math.round(ms / 86400000);
}

function rsBucketForEpic(epic) {
  for (const r of RELEASES) {
    if (epic.end <= r.endDate) return r.id;
  }
  return "beyond";
}

// risk = "done" | "ontrack" | "atrisk" | "overdue"
function rsRiskFor(epic) {
  if (epic.status === "done") return "done";
  const daysToEnd = rsDaysBetween(RS_TODAY, epic.end);
  if (daysToEnd < 0) return "overdue";
  if (daysToEnd <= 14 && epic.status !== "in_progress") return "atrisk";
  if (daysToEnd <= 7) return "atrisk"; // even in-progress is at-risk inside 7d
  return "ontrack";
}

function rsRollup(epics) {
  const r = { total: epics.length, done: 0, in_progress: 0, todo: 0, atrisk: 0, overdue: 0 };
  for (const e of epics) {
    if (e.status === "done") r.done++;
    else if (e.status === "in_progress") r.in_progress++;
    else r.todo++;
    const risk = rsRiskFor(e);
    if (risk === "atrisk") r.atrisk++;
    if (risk === "overdue") r.overdue++;
  }
  return r;
}

// ───── Components ─────

function ReleaseReadinessHeader({ overrides = {}, onJumpToEpic }) {
  // Apply overrides so this matches what the views render
  const epics = RS_D.epics.map(e => {
    const o = overrides[e.id];
    return o ? { ...e, end: o.end || e.end } : e;
  });

  // Find next non-empty release (the first whose endDate >= today and has any non-done epics)
  const upcomingIdx = RELEASES.findIndex(r => r.endDate >= RS_TODAY);
  const nextRelease = upcomingIdx >= 0 ? RELEASES[upcomingIdx] : RELEASES[RELEASES.length - 1];

  // Critical-path = next release's non-done epics, sorted by risk then by start date
  const cpEpics = epics
    .filter(e => rsBucketForEpic(e) === nextRelease.id && e.status !== "done")
    .map(e => ({ ...e, risk: rsRiskFor(e) }))
    .sort((a, b) => {
      const order = { overdue: 0, atrisk: 1, ontrack: 2 };
      if (order[a.risk] !== order[b.risk]) return order[a.risk] - order[b.risk];
      return a.start.localeCompare(b.start);
    });

  const daysToNext = rsDaysBetween(RS_TODAY, nextRelease.endDate);

  return (
    <div className="zr-rs">
      {/* readiness rail */}
      <div className="zr-rs-rail">
        <div className="zr-rs-rail-label">
          <span className="k">Release Readiness</span>
          <span className="v">as of {new Date(RS_TODAY).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" })}</span>
        </div>
        <div className="zr-rs-cards">
          {RELEASES.map(r => {
            const re = epics.filter(e => rsBucketForEpic(e) === r.id);
            const roll = rsRollup(re);
            const isNext = r.id === nextRelease.id;
            const dDays = rsDaysBetween(RS_TODAY, r.endDate);
            return (
              <div key={r.id} className={`zr-rs-card ${isNext ? "is-next" : ""} ${roll.overdue ? "has-overdue" : ""}`}>
                <div className="head">
                  <div className="ttl">{r.shortLabel}</div>
                  <div className="d">
                    {dDays < 0 ? `${-dDays}d ago` : dDays === 0 ? "today" : `in ${dDays}d`}
                  </div>
                </div>
                <div className="bar">
                  {roll.total === 0 ? (
                    <div className="seg seg-empty" style={{ flex: 1 }} />
                  ) : (
                    <React.Fragment>
                      {roll.done       > 0 && <div className="seg seg-done"  style={{ flex: roll.done }} />}
                      {roll.in_progress> 0 && <div className="seg seg-prog"  style={{ flex: roll.in_progress }} />}
                      {roll.todo       > 0 && <div className="seg seg-todo"  style={{ flex: roll.todo }} />}
                    </React.Fragment>
                  )}
                </div>
                <div className="stats">
                  <span className="s s-total">{roll.total} <em>items</em></span>
                  {roll.in_progress > 0 && <span className="s s-prog">{roll.in_progress} active</span>}
                  {roll.todo        > 0 && <span className="s s-todo">{roll.todo} to start</span>}
                  {roll.atrisk      > 0 && <span className="s s-risk">⚠ {roll.atrisk} at risk</span>}
                  {roll.overdue     > 0 && <span className="s s-over">▲ {roll.overdue} overdue</span>}
                  {roll.total > 0 && roll.todo === 0 && roll.atrisk === 0 && roll.overdue === 0 && (
                    <span className="s s-ok">✓ on track</span>
                  )}
                </div>
              </div>
            );
          })}
        </div>
      </div>

      {/* critical-path banner */}
      {cpEpics.length > 0 && (
        <div className="zr-rs-cp">
          <div className="zr-rs-cp-head">
            <div className="lhs">
              <span className="tag">CRITICAL PATH</span>
              <span className="ttl">To make <strong>{nextRelease.label}</strong> ({daysToNext < 0 ? `${-daysToNext}d overdue` : `${daysToNext} days out`})</span>
            </div>
            <div className="rhs">
              <span className="legend"><i className="dot d-over" /> Overdue</span>
              <span className="legend"><i className="dot d-risk" /> At risk</span>
              <span className="legend"><i className="dot d-ok"   /> On track</span>
            </div>
          </div>
          <div className="zr-rs-cp-list">
            {cpEpics.map(e => {
              const lane = RS_D.workstreams.find(l => l.id === e.lane);
              const dDays = rsDaysBetween(RS_TODAY, e.end);
              return (
                <button key={e.id} className={`zr-rs-cp-row risk-${e.risk}`} onClick={() => onJumpToEpic && onJumpToEpic(e.id)}>
                  <i className={`dot d-${e.risk === "overdue" ? "over" : e.risk === "atrisk" ? "risk" : "ok"}`} />
                  <span className="lane" style={{ color: lane?.color }}>{lane?.label}</span>
                  <span className="ttl">{e.title}</span>
                  <span className="status">{RS_D.statuses[e.status]?.label || e.status}</span>
                  <span className="due">
                    {dDays < 0 ? `${-dDays}d overdue` : dDays === 0 ? "due today" : `${dDays}d left`}
                  </span>
                </button>
              );
            })}
          </div>
        </div>
      )}
    </div>
  );
}

window.ZephyrReleaseStatus = { ReleaseReadinessHeader, RELEASES, rsBucketForEpic, rsRiskFor };
