// Shared sidebar. Pages pass `active` so the current item is highlighted.
//
// IA Phase 6 (PR #80) collapsed the previous 25-item, 4-group nav into a flat
// Chats / Reports / Alerts / Settings list. That removed every entry point
// to the entity-list pages (Contributors, Teams, Repositories, Projects,
// Sprints, PRs, Files, Incidents, Monitor alerts) and the analytical
// dashboards (Exec board, Portfolio, AI cost, Team detail) — even though
// their backends still existed. This file restores navigation to those
// pages by re-introducing a 3-group structure:
//
//   * top-level: Chats, Reports, Alerts (no group label)
//   * "Entities" group: Contributors, Teams, Repositories, Projects,
//     Sprints, Pull requests, Files
//   * "Insights" group: Exec board, Portfolio, Incidents, Monitor alerts,
//     Team detail, AI cost
//   * bottom: Settings, Notifications (bell), Logout
//
// Icons: per CLAUDE.md the product runs air-gapped. We do NOT pull in an
// icon font / sprite from a CDN, nor do we vendor a heavyweight icon
// library. Each icon below is a hand-drawn inline SVG using
// stroke=currentColor so it inherits the sidebar's foreground colour and
// recolours on hover / active without extra CSS rules.
//
// Geometry: 18×18 viewBox, 1.6px strokes, rounded joins. Sized to sit on
// the same vertical centreline as the 0.95rem label text.

function NavIcon({ name }) {
  const common = {
    width: 18,
    height: 18,
    viewBox: "0 0 24 24",
    fill: "none",
    stroke: "currentColor",
    strokeWidth: 1.8,
    strokeLinecap: "round",
    strokeLinejoin: "round",
    "aria-hidden": "true",
    focusable: "false",
  };
  switch (name) {
    case "chats":
      // Speech bubble.
      return (
        <svg {...common}>
          <path d="M21 12a8 8 0 0 1-11.6 7.1L4 20l1-4.4A8 8 0 1 1 21 12z" />
        </svg>
      );
    case "reports":
      // Bar chart.
      return (
        <svg {...common}>
          <path d="M4 20V10" />
          <path d="M10 20V4" />
          <path d="M16 20v-7" />
          <path d="M22 20H2" />
        </svg>
      );
    case "alerts":
      // Triangle warning.
      return (
        <svg {...common}>
          <path d="M12 3 2 20h20L12 3z" />
          <path d="M12 10v5" />
          <path d="M12 18h.01" />
        </svg>
      );
    case "settings":
      // Gear.
      return (
        <svg {...common}>
          <circle cx="12" cy="12" r="3" />
          <path d="M19.4 15a1.7 1.7 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.8-.3 1.7 1.7 0 0 0-1 1.5V21a2 2 0 0 1-4 0v-.1a1.7 1.7 0 0 0-1-1.5 1.7 1.7 0 0 0-1.8.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0 .3-1.8 1.7 1.7 0 0 0-1.5-1H3a2 2 0 0 1 0-4h.1a1.7 1.7 0 0 0 1.5-1 1.7 1.7 0 0 0-.3-1.8l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.8.3h.1a1.7 1.7 0 0 0 1-1.5V3a2 2 0 0 1 4 0v.1a1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.8v.1a1.7 1.7 0 0 0 1.5 1H21a2 2 0 0 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1z" />
        </svg>
      );
    case "notifications":
      // Bell.
      return (
        <svg {...common}>
          <path d="M6 8a6 6 0 1 1 12 0c0 7 3 7 3 9H3c0-2 3-2 3-9z" />
          <path d="M10 21a2 2 0 0 0 4 0" />
        </svg>
      );
    case "logout":
      // Door + arrow.
      return (
        <svg {...common}>
          <path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" />
          <path d="M16 17l5-5-5-5" />
          <path d="M21 12H9" />
        </svg>
      );
    case "contributors":
      // Two people.
      return (
        <svg {...common}>
          <path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" />
          <circle cx="9" cy="7" r="4" />
          <path d="M22 21v-2a4 4 0 0 0-3-3.87" />
          <path d="M16 3.13a4 4 0 0 1 0 7.75" />
        </svg>
      );
    case "teams":
      // Three people grouped.
      return (
        <svg {...common}>
          <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" />
          <circle cx="9" cy="7" r="4" />
          <path d="M23 21v-2a4 4 0 0 0-3-3.87" />
          <path d="M16 3.13a4 4 0 0 1 0 7.75" />
        </svg>
      );
    case "repos":
      // Box / package.
      return (
        <svg {...common}>
          <path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z" />
          <path d="M3.27 6.96 12 12.01l8.73-5.05" />
          <path d="M12 22.08V12" />
        </svg>
      );
    case "projects":
      // Folder.
      return (
        <svg {...common}>
          <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z" />
        </svg>
      );
    case "sprints":
      // Flag.
      return (
        <svg {...common}>
          <path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z" />
          <path d="M4 22V15" />
        </svg>
      );
    case "prs":
      // Git pull request fork.
      return (
        <svg {...common}>
          <circle cx="6" cy="6" r="2" />
          <circle cx="6" cy="18" r="2" />
          <circle cx="18" cy="18" r="2" />
          <path d="M6 8v8" />
          <path d="M18 11v5" />
          <path d="M11 4h5a2 2 0 0 1 2 2v5" />
        </svg>
      );
    case "files":
      // Document.
      return (
        <svg {...common}>
          <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
          <path d="M14 2v6h6" />
          <path d="M8 13h8" />
          <path d="M8 17h8" />
        </svg>
      );
    case "exec":
      // Compass.
      return (
        <svg {...common}>
          <circle cx="12" cy="12" r="10" />
          <path d="m16.24 7.76-2.12 6.36-6.36 2.12 2.12-6.36z" />
        </svg>
      );
    case "portfolio":
      // Briefcase.
      return (
        <svg {...common}>
          <rect x="2" y="7" width="20" height="14" rx="2" />
          <path d="M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16" />
        </svg>
      );
    case "incidents":
      // Siren / alert circle.
      return (
        <svg {...common}>
          <circle cx="12" cy="12" r="10" />
          <path d="M12 8v4" />
          <path d="M12 16h.01" />
        </svg>
      );
    case "monitor-alerts":
      // Activity pulse.
      return (
        <svg {...common}>
          <path d="M22 12h-4l-3 9L9 3l-3 9H2" />
        </svg>
      );
    case "team-detail":
      // Single user with details bars.
      return (
        <svg {...common}>
          <circle cx="9" cy="8" r="4" />
          <path d="M3 21v-2a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v2" />
          <path d="M17 11h4" />
          <path d="M17 15h4" />
        </svg>
      );
    case "ai-cost":
      // Coin / dollar.
      return (
        <svg {...common}>
          <circle cx="12" cy="12" r="10" />
          <path d="M12 6v12" />
          <path d="M15 9a3 3 0 0 0-3-2 3 3 0 0 0 0 6 3 3 0 0 1 0 6 3 3 0 0 1-3-2" />
        </svg>
      );
    default:
      return null;
  }
}

// Top-level (no group label).
const TOP_ITEMS = [
  { key: "chats",   label: "Chats",   href: "/chat.html" },
  { key: "reports", label: "Reports", href: "/reports.html" },
  { key: "alerts",  label: "Alerts",  href: "/alerts.html" },
];

// Grouped sections (group label rendered above the items).
const NAV_GROUPS = [
  {
    label: "Entities",
    items: [
      { key: "contributors", label: "Contributors",  href: "/contributors.html" },
      { key: "teams",        label: "Teams",         href: "/teams.html" },
      { key: "repos",        label: "Repositories",  href: "/repository.html" },
      { key: "projects",     label: "Projects",      href: "/projects.html" },
      { key: "sprints",      label: "Sprints",       href: "/sprints.html" },
      { key: "prs",          label: "Pull requests", href: "/prs.html" },
      { key: "files",        label: "Files",         href: "/files.html" },
    ],
  },
  {
    label: "Insights",
    items: [
      { key: "exec",            label: "Exec board",     href: "/exec-board.html" },
      { key: "portfolio",       label: "Portfolio",      href: "/portfolio.html" },
      { key: "incidents",       label: "Incidents",      href: "/incidents.html" },
      { key: "monitor-alerts",  label: "Monitor alerts", href: "/monitor-alerts.html" },
      { key: "team-detail",     label: "Team detail",    href: "/team-detail.html" },
      { key: "ai-cost",         label: "AI cost",        href: "/ai-cost.html" },
    ],
  },
];

const SETTINGS_ITEM = { key: "settings", label: "Settings", href: "/settings.html" };
const BELL_ITEM = { key: "notifications", label: "Notifications", href: "/notifications.html" };

// GIT-1054: overall integration-health dot. Lazily fetched on Sidebar mount
// so every authed page surfaces the indicator even if the user is not on the
// integrations-health page itself. The integrations_health page also publishes
// to window.GR.integrationsHealth + dispatches a "gr:integrations-health"
// event on each successful poll, so the dot stays fresh while that tab is open.
const HEALTH_DOT_TONE = {
  ok:        { color: "#22c55e", title: "All datasources healthy" },
  degraded:  { color: "#eab308", title: "Some datasources degraded" },
  failing:   { color: "#ef4444", title: "One or more datasources failing" },
  never_run: { color: "#94a3b8", title: "Datasource extraction pending" },
  unknown:   { color: "#94a3b8", title: "Status unknown" },
};

function IntegrationHealthDot() {
  const [overall, setOverall] = React.useState(() =>
    (window.GR && window.GR.integrationsHealth && window.GR.integrationsHealth.overall) || null
  );

  React.useEffect(() => {
    let cancelled = false;
    function apply(value) { if (!cancelled) setOverall(value); }

    if (!overall && window.GR && window.GR.api && window.GR.api.isAuthed()) {
      window.GR.api.get("/api/v1/integrations/health")
        .then((b) => {
          if (b && b.overall_status) {
            window.GR.integrationsHealth = {
              overall: b.overall_status,
              updatedAt: b.last_computed_at,
            };
            apply(b.overall_status);
          }
        })
        .catch(() => { /* never fail the chrome over a status dot */ });
    }

    function onEvent(e) {
      const detail = e && e.detail;
      if (detail && detail.overall_status) apply(detail.overall_status);
    }
    window.addEventListener("gr:integrations-health", onEvent);
    return () => {
      cancelled = true;
      window.removeEventListener("gr:integrations-health", onEvent);
    };
  }, []);

  const tone = HEALTH_DOT_TONE[overall || "unknown"];
  return (
    <a
      href="/integrations-health.html"
      className="gr-sidebar-health-dot"
      aria-label={tone.title}
      title={tone.title}
      style={{ display: "flex", alignItems: "center", gap: "0.5rem" }}
    >
      <span
        aria-hidden="true"
        style={{
          display: "inline-block",
          width: "0.65rem",
          height: "0.65rem",
          borderRadius: "50%",
          background: tone.color,
        }}
      />
      <span>Integrations</span>
    </a>
  );
}

// Inline style for group labels. Lifted from the pre-IA Sidebar (PR #80~1) so
// we don't depend on a sibling CSS edit landing first; the CSS file gets an
// optional .gr-sidebar-group-label class for any future consumer.
const GROUP_LABEL_STYLE = {
  fontSize: "0.7rem",
  color: "#5b6478",
  textTransform: "uppercase",
  letterSpacing: "0.05em",
  padding: "0.6rem 0.75rem 0.25rem",
};

function NavLink({ item, active }) {
  const { cls } = window.GR;
  return (
    <a href={item.href} className={cls(active === item.key && "is-active")}>
      <NavIcon name={item.key} />
      <span>{item.label}</span>
    </a>
  );
}

window.GR.Sidebar = function Sidebar({ active }) {
  const { cls } = window.GR;
  const onLogout = () => { window.GR.api.clearAuth(); window.location.href = "/login.html"; };
  return (
    <aside className="gr-sidebar">
      <div className="gr-sidebar-brand">Gitrevio</div>

      {TOP_ITEMS.map((item) => (
        <NavLink key={item.key} item={item} active={active} />
      ))}

      {NAV_GROUPS.map((g) => (
        <React.Fragment key={g.label}>
          <div className="gr-sidebar-group-label" style={GROUP_LABEL_STYLE}>{g.label}</div>
          {g.items.map((item) => (
            <NavLink key={item.key} item={item} active={active} />
          ))}
        </React.Fragment>
      ))}

      <div className="gr-sidebar-spacer" />

      <IntegrationHealthDot />

      <NavLink item={SETTINGS_ITEM} active={active} />

      <a
        key={BELL_ITEM.key}
        href={BELL_ITEM.href}
        className={cls(active === BELL_ITEM.key && "is-active")}
        aria-label="Notifications"
      >
        <NavIcon name="notifications" />
        <span>{BELL_ITEM.label}</span>
      </a>

      <div className="gr-sidebar-meta">Gitrevio v1.0 · Flexiana</div>
      <a href="#" onClick={(e) => { e.preventDefault(); onLogout(); }}>
        <NavIcon name="logout" />
        <span>Logout</span>
      </a>
    </aside>
  );
};
