// Analytics — Overview (Business Report)
// Ported from the standalone "Your Overview" prototype. The shell wrapper
// (sidebar + topbar) was removed; this renders only the report content.
/* global React, ReactDOM */
const { useState, useEffect, useMemo } = React;
//
// Wrapped in an IIFE: this file defines components named App, Icon and
// SectionLabel, which the messaging components also define. Left at global
// scope the last script to load wins, and Messaging would render this
// report instead of the inbox. Only mountAnalyticsOverview is exported.

(function () {
/* ────────────────────────────────────────────────────────────
   Tiny SVG primitives — sparkline, bar, line
   ──────────────────────────────────────────────────────────── */

function Sparkline({ data, w = 80, h = 24, color = "#004CE6", showDots = false, strokeWidth = 1.5 }) {
  const max = Math.max(...data);
  const min = Math.min(...data);
  const range = max - min || 1;
  const stepX = w / (data.length - 1);
  const points = data.map((v, i) => [i * stepX, h - (v - min) / range * (h - 4) - 2]);
  const path = points.map((p, i) => i === 0 ? `M ${p[0]} ${p[1]}` : `L ${p[0]} ${p[1]}`).join(" ");
  const area = `${path} L ${w} ${h} L 0 ${h} Z`;
  const last = points[points.length - 1];
  return (
    <svg width={w} height={h} viewBox={`0 0 ${w} ${h}`} style={{ display: "block" }}>
      <defs>
        <linearGradient id={`spark-fill-${color.replace("#", "")}`} x1="0" x2="0" y1="0" y2="1">
          <stop offset="0%" stopColor={color} stopOpacity="0.12" />
          <stop offset="100%" stopColor={color} stopOpacity="0" />
        </linearGradient>
      </defs>
      <path d={area} fill={`url(#spark-fill-${color.replace("#", "")})`} />
      <path d={path} fill="none" stroke={color} strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round" />
      {showDots && <circle cx={last[0]} cy={last[1]} r="2.5" fill={color} />}
    </svg>);

}

function BarChart({ data, w = 280, h = 120, color = "#004CE6", labels, highlight = -1, valuePrefix = "", valueSuffix = "", stack = null, stackColor = "#D92D20", stackLabel = "" }) {
  const [hover, setHover] = useState(-1);
  const max = Math.max(...data.map((v, i) => v + (stack ? stack[i] : 0)));
  const padTop = 16;
  const padBottom = 20;
  const innerH = h - padTop - padBottom;
  const gap = 6;
  const barW = (w - gap * (data.length - 1)) / data.length;
  const active = hover >= 0 ? hover : highlight;
  return (
    <div className="chart-wrap" style={{ position: "relative" }}>
      <svg
        width="100%" height={h} viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none"
        style={{ display: "block" }}
        onMouseLeave={() => setHover(-1)}>
        
        {[0.25, 0.5, 0.75].map((t, i) =>
        <line key={i} x1="0" x2={w} y1={padTop + innerH * (1 - t)} y2={padTop + innerH * (1 - t)} stroke="#F2F4F7" strokeWidth="1" />
        )}
        {data.map((v, i) => {
          const bh = v / max * innerH;
          const sv = stack ? stack[i] : 0;
          const sh = sv / max * innerH;
          const x = i * (barW + gap);
          const y = padTop + innerH - bh;
          const sy = y - sh;
          const isActive = active === i;
          const fill = isActive ? "#003BB3" : color;
          return (
            <g key={i}>
              <rect x={x} y={y} width={barW} height={bh} rx="2" fill={fill} opacity={active === -1 || isActive ? 1 : 0.45} style={{ transition: "opacity 0.12s" }} />
              {stack && sh > 0 &&
              <rect x={x} y={sy} width={barW} height={sh} rx="2" fill={stackColor} opacity={active === -1 || isActive ? 0.95 : 0.45} style={{ transition: "opacity 0.12s" }} />
              }
              {/* hover hit-area */}
              <rect
                x={i * (barW + gap) - gap / 2}
                y={0}
                width={barW + gap}
                height={h}
                fill="transparent"
                onMouseEnter={() => setHover(i)}
                style={{ cursor: "pointer" }} />
              
            </g>);

        })}
      </svg>
      {labels &&
      <div className="chart-labels" style={{ position: "absolute", left: 0, right: 0, bottom: 2, display: "flex", justifyContent: "space-between", padding: "0 2px", pointerEvents: "none" }}>
          {labels.map((l, i) => {
          const isActive = active === i;
          return <span key={i} style={{ flex: 1, textAlign: "center", fontSize: 10, color: isActive ? "#101828" : "#98A2B3", fontWeight: isActive ? 600 : 400, fontFamily: 'Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif' }}>{l}</span>;
        })}
        </div>
      }
      {hover >= 0 &&
      <div
        className="chart-tooltip"
        style={{ left: `${(hover + 0.5) / data.length * 100}%` }}>
        
          <div className="tt-label">{labels ? labels[hover] : `Pt ${hover + 1}`}</div>
          <div className="tt-value">{valuePrefix}{(data[hover] + (stack ? stack[hover] : 0)).toLocaleString()}{valueSuffix}</div>
          {stack &&
        <>
            <div style={{ display: "flex", alignItems: "center", gap: 6, marginTop: 4, fontSize: 11, color: "#D0D5DD" }}>
              <span style={{ width: 6, height: 6, borderRadius: 1, background: color, display: "inline-block" }} />
              Answered: <span style={{ color: "white", fontWeight: 500, marginLeft: "auto" }}>{data[hover]}</span>
            </div>
            <div style={{ display: "flex", alignItems: "center", gap: 6, marginTop: 2, fontSize: 11, color: "#D0D5DD" }}>
              <span style={{ width: 6, height: 6, borderRadius: 1, background: stackColor, display: "inline-block" }} />
              {stackLabel}: <span style={{ color: "white", fontWeight: 500, marginLeft: "auto" }}>{stack[hover]}</span>
            </div>
            </>
        }
        </div>
      }
    </div>);

}

function LineChart({ data, w = 280, h = 120, color = "#004CE6", labels, target, valuePrefix = "", valueSuffix = "" }) {
  const [hover, setHover] = useState(-1);
  const [targetHover, setTargetHover] = useState(false);
  const max = Math.max(...data, target || 0) * 1.1;
  const min = Math.min(...data) * 0.9;
  const range = max - min || 1;
  const padTop = 12;
  const padBottom = 20;
  const padLeft = 16;
  const padRight = 16;
  const innerH = h - padTop - padBottom;
  const innerW = w - padLeft - padRight;
  const stepX = innerW / (data.length - 1);
  const pts = data.map((v, i) => [padLeft + i * stepX, padTop + innerH - (v - min) / range * innerH]);
  const path = pts.map((p, i) => i === 0 ? `M ${p[0]} ${p[1]}` : `L ${p[0]} ${p[1]}`).join(" ");
  const area = `${path} L ${pts[pts.length - 1][0]} ${padTop + innerH} L ${pts[0][0]} ${padTop + innerH} Z`;
  const hitW = innerW / (data.length - 1);
  return (
    <div className="chart-wrap" style={{ position: "relative" }}>
      <svg
        width="100%" height={h} viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none"
        style={{ display: "block" }}
        onMouseLeave={() => setHover(-1)}>
        
        <defs>
          <linearGradient id={`line-fill-${color.replace("#", "")}`} x1="0" x2="0" y1="0" y2="1">
            <stop offset="0%" stopColor={color} stopOpacity="0.16" />
            <stop offset="100%" stopColor={color} stopOpacity="0" />
          </linearGradient>
        </defs>
        {[0.25, 0.5, 0.75].map((t, i) =>
        <line key={i} x1={padLeft} x2={w - padRight} y1={padTop + innerH * (1 - t)} y2={padTop + innerH * (1 - t)} stroke="#F2F4F7" strokeWidth="1" />
        )}
        {target != null &&
        <g className="target-line-group">
          <line
            x1={padLeft} x2={w - padRight}
            y1={padTop + innerH - (target - min) / range * innerH}
            y2={padTop + innerH - (target - min) / range * innerH}
            stroke="#98A2B3" strokeWidth="1" strokeDasharray="3 3" />
          <rect
            x={padLeft - 4} width={w - padLeft - padRight + 8}
            y={padTop + innerH - (target - min) / range * innerH - 8}
            height={16}
            fill="transparent"
            style={{ cursor: "help" }}
            onMouseEnter={() => setTargetHover(true)}
            onMouseLeave={() => setTargetHover(false)} />
        </g>
        }
        <path d={area} fill={`url(#line-fill-${color.replace("#", "")})`} />
        <path d={path} fill="none" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
        {hover >= 0 &&
        <line x1={pts[hover][0]} x2={pts[hover][0]} y1={padTop} y2={padTop + innerH} stroke="#D0D5DD" strokeWidth="1" strokeDasharray="2 2" />
        }
        {pts.map(([x, y], i) => {
          const isActive = hover === i;
          const r = isActive ? 5 : i === pts.length - 1 ? 3.5 : 2;
          return <circle key={i} cx={x} cy={y} r={r} fill={color} stroke="white" strokeWidth={isActive || i === pts.length - 1 ? 1.5 : 0} style={{ transition: "r 0.12s" }} />;
        })}
        {/* hit areas */}
        {pts.map(([x], i) =>
        <rect
          key={i}
          x={x - hitW / 2}
          y={0}
          width={hitW}
          height={h}
          fill="transparent"
          onMouseEnter={() => setHover(i)}
          style={{ cursor: "pointer" }} />

        )}
      </svg>
      {labels &&
      <div className="chart-labels" style={{ position: "absolute", left: padLeft, right: padRight, bottom: 2, display: "flex", justifyContent: "space-between", pointerEvents: "none" }}>
          {labels.map((l, i) =>
        <span key={i} style={{ fontSize: 10, color: hover === i ? "#101828" : "#98A2B3", fontWeight: hover === i ? 600 : 400, fontFamily: 'Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif', transform: i === 0 ? "translateX(-50%)" : i === labels.length - 1 ? "translateX(50%)" : "translateX(0)" }}>{l}</span>
        )}
        </div>
      }
      {hover >= 0 &&
      <div
        className="chart-tooltip"
        style={{ left: `${pts[hover][0] / w * 100}%` }}>
        
          <div className="tt-label">{labels ? labels[hover] : `Pt ${hover + 1}`}</div>
          <div className="tt-value">{valuePrefix}{data[hover].toLocaleString()}{valueSuffix}</div>
        </div>
      }
      {target != null && targetHover &&
      <div
        style={{
          position: "absolute",
          left: "50%",
          top: `${(padTop + innerH - (target - min) / range * innerH) / h * 100}%`,
          transform: "translate(-50%, -130%)",
          background: "#101828",
          color: "white",
          fontSize: 11,
          fontWeight: 500,
          padding: "4px 8px",
          borderRadius: 4,
          whiteSpace: "nowrap",
          pointerEvents: "none",
          zIndex: 6
        }}>
          Target: {valuePrefix}{target}{valueSuffix}
        </div>
      }
    </div>);

}

/* ────────────────────────────────────────────────────────────
   Icons (Lucide-style strokes)
   ──────────────────────────────────────────────────────────── */

const Icon = ({ d, size = 16, stroke = "currentColor", strokeWidth = 2, fill = "none" }) =>
<svg width={size} height={size} viewBox="0 0 24 24" fill={fill} stroke={stroke} strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round">
    {d}
  </svg>;

const IconInfo = (p) => <Icon {...p} d={<><circle cx="12" cy="12" r="10" /><line x1="12" y1="16" x2="12" y2="12" /><line x1="12" y1="8" x2="12.01" y2="8" /></>} />;

function InfoTip({ text }) {
  return (
    <span className="info-tip" tabIndex="0">
      <IconInfo size={12} stroke="#98A2B3" strokeWidth={2} />
      <span className="info-tip-bubble">{text}</span>
    </span>
  );
}

const IconArrowDown = (p) => <Icon {...p} d={<><line x1="12" y1="5" x2="12" y2="19" /><polyline points="19 12 12 19 5 12" /></>} />;
const IconArrowUp = (p) => <Icon {...p} d={<><line x1="12" y1="19" x2="12" y2="5" /><polyline points="5 12 12 5 19 12" /></>} />;
const IconArrowRight = (p) => <Icon {...p} d={<><line x1="5" y1="12" x2="19" y2="12" /><polyline points="12 5 19 12 12 19" /></>} />;
const IconRefresh = (p) => <Icon {...p} d={<><polyline points="23 4 23 10 17 10" /><polyline points="1 20 1 14 7 14" /><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15" /></>} />;
const IconEdit = (p) => <Icon {...p} d={<><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" /><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" /></>} />;
const IconSparkles = (p) => <Icon {...p} d={<><path d="M12 3v18M3 12h18M5.5 5.5l13 13M18.5 5.5l-13 13" strokeWidth="1.5" /></>} />;
const IconCheck = (p) => <Icon {...p} d={<polyline points="20 6 9 17 4 12" />} />;
const IconAlert = (p) => <Icon {...p} d={<><circle cx="12" cy="12" r="10" /><line x1="12" y1="8" x2="12" y2="12" /><line x1="12" y1="16" x2="12.01" y2="16" /></>} />;
const IconBolt = (p) => <Icon {...p} d={<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" />} />;

/* JustCall sidebar nav icons */
const NavIcon = {
  home: <Icon d={<><path d="M3 9.5L12 3l9 6.5V20a2 2 0 0 1-2 2h-4v-7H9v7H5a2 2 0 0 1-2-2V9.5z" /></>} size={20} />,
  phone: <Icon d={<path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z" />} size={20} />,
  chart: <Icon d={<><line x1="18" y1="20" x2="18" y2="10" /><line x1="12" y1="20" x2="12" y2="4" /><line x1="6" y1="20" x2="6" y2="14" /></>} size={20} />,
  bot: <Icon d={<><rect x="3" y="11" width="18" height="10" rx="2" /><circle cx="12" cy="5" r="2" /><path d="M12 7v4" /><line x1="8" y1="16" x2="8" y2="16" /><line x1="16" y1="16" x2="16" y2="16" /></>} size={20} />,
  hash: <Icon d={<><line x1="4" y1="9" x2="20" y2="9" /><line x1="4" y1="15" x2="20" y2="15" /><line x1="10" y1="3" x2="8" y2="21" /><line x1="16" y1="3" x2="14" y2="21" /></>} size={20} />,
  flow: <Icon d={<><circle cx="6" cy="6" r="3" /><circle cx="18" cy="18" r="3" /><path d="M9 6h6a3 3 0 0 1 3 3v6" /></>} size={20} />,
  dialer: <Icon d={<><circle cx="12" cy="12" r="10" /><polygon points="10 8 16 12 10 16 10 8" /></>} size={20} />,
  inbox: <Icon d={<><polyline points="22 12 16 12 14 15 10 15 8 12 2 12" /><path d="M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z" /></>} size={20} />,
  users: <Icon d={<><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" /></>} size={20} />,
  contacts: <Icon d={<><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" /><circle cx="12" cy="7" r="4" /></>} size={20} />,
  log: <Icon d={<><circle cx="12" cy="12" r="10" /><polyline points="12 6 12 12 16 14" /></>} size={20} />,
  settings: <Icon d={<><circle cx="12" cy="12" r="3" /><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z" /></>} size={20} />
};

/* ────────────────────────────────────────────────────────────
   Sidebar (production JustCall)
   ──────────────────────────────────────────────────────────── */

function Sidebar() {
  const items = [
  { key: "home", label: "Your Overview", icon: NavIcon.home, active: true },
  { key: "analytics", label: "Analytics", icon: NavIcon.chart },
  { key: "ai", label: "AI Voice Agent", icon: NavIcon.bot, badge: "New" },
  { key: "phone", label: "Phone Numbers", icon: NavIcon.hash },
  { key: "workflows", label: "Workflows", icon: NavIcon.flow, badge: "New" },
  { key: "dialer", label: "Sales Dialer", icon: NavIcon.dialer },
  { key: "justcall-ai", label: "JustCall AI", icon: NavIcon.bot },
  { key: "inbox", label: "Email Inbox", icon: NavIcon.inbox },
  { key: "teams", label: "Teams", icon: NavIcon.users },
  { key: "contacts", label: "Contacts", icon: NavIcon.contacts },
  { key: "logs", label: "Call Logs", icon: NavIcon.log }];

  return (
    <aside className="sidebar">
      <div className="sidebar-logo">
        <div className="logo-mark">
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none">
            <path d="M5 4h4v16H5zM11 4h4v10a4 4 0 0 1-4 4z" fill="#3B82F6" />
            <circle cx="17" cy="6" r="2" fill="#3B82F6" />
          </svg>
        </div>
        <div className="logo-word">JustCall</div>
      </div>

      <nav className="sidebar-nav">
        {items.map((it) =>
        <a key={it.key} className={"nav-item" + (it.active ? " is-active" : "")} href="#">
            <span className="nav-icon">{it.icon}</span>
            <span className="nav-label">{it.label}</span>
            {it.badge && <span className="nav-badge">{it.badge}</span>}
          </a>
        )}
      </nav>

      <div className="sidebar-foot">
        <a className="nav-item" href="#">
          <span className="nav-icon">{NavIcon.settings}</span>
          <span className="nav-label">Settings</span>
        </a>
        <div className="credits-card">
          <div className="credits-head">
            <span className="t-label-xs" style={{ color: "rgba(255,255,255,0.6)" }}>Usage</span>
            <span className="credits-amount">$48.20</span>
          </div>
          <div className="credits-bar"><div style={{ width: "62%" }} /></div>
          <button className="credits-cta">View Usage Balance</button>
        </div>
        <div className="user-row">
          <div className="user-avatar">MR</div>
          <div className="user-meta">
            <div className="user-name">Maya Rao</div>
            <div className="user-team">Acme Support</div>
          </div>
        </div>
      </div>
    </aside>);

}

/* ────────────────────────────────────────────────────────────
   Header
   ──────────────────────────────────────────────────────────── */

function Header({ range, setRange }) {
  const [secs, setSecs] = useState(12);
  useEffect(() => {
    const id = setInterval(() => setSecs((s) => s + 1), 1000);
    return () => clearInterval(id);
  }, []);
  return (
    <div className="page-header">
      <div>
        <h1 className="t-h-xxxl">Your Overview</h1>
        <div className="page-sub">
          Week of Apr 24–30
        </div>
      </div>
      <div className="page-actions">
        <div className="seg">
          {["Today", "Week", "Month"].map((r) =>
          <button key={r} className={"seg-btn" + (range === r ? " is-active" : "")} onClick={() => setRange(r)}>{r}</button>
          )}
        </div>
        <button className="btn-ghost"><IconEdit size={16} /> Edit</button>
      </div>
    </div>);

}

/* ────────────────────────────────────────────────────────────
   Attention rail
   ──────────────────────────────────────────────────────────── */

const SEVERITY = {
  CRITICAL: { color: "#D92D20", bg: "#FEF3F2", dot: "#D92D20" },
  WARNING: { color: "#B54708", bg: "#FFFAEB", dot: "#F79009" },
  INSIGHT: { color: "#175CD3", bg: "#E6EEFF", dot: "#004CE6" },
  POSITIVE: { color: "#027A48", bg: "#ECFDF3", dot: "#12B76A" }
};

function RecommendedActionsModal({ onClose }) {
  useEffect(() => {
    const fn = (e) => { if (e.key === "Escape") onClose(); };
    window.addEventListener("keydown", fn);
    return () => window.removeEventListener("keydown", fn);
  }, [onClose]);
  const recs = [
  { title: "Rebalance inbound call routing", sub: "Shift overflow to Lauren and Stephen, who maintained >95% answer rates last week.",
    icon: <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#6938EF" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><path d="M17 3 L21 7 L17 11" /><path d="M3 7 H21" /><path d="M7 13 L3 17 L7 21" /><path d="M3 17 H21" /></svg> },
  { title: "Enable automatic callbacks", sub: "Recover the 37 abandoned calls to capture missed opportunities.",
    icon: <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#6938EF" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.12.9.32 1.78.59 2.63a2 2 0 0 1-.45 2.11L8 9.71a16 16 0 0 0 6.29 6.29l1.25-1.25a2 2 0 0 1 2.11-.45c.85.27 1.73.47 2.63.59A2 2 0 0 1 22 16.92z" /></svg> },
  { title: "Increase queue timeout from 20s to 35s", sub: "Temporary change to reduce call abandonment during peak periods.",
    icon: <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#6938EF" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="13" r="8" /><path d="M12 9v4l2.5 2" /><path d="M9 2h6" /></svg> }];

  return (
    <div className="ra-overlay" onClick={onClose}>
      <div className="ra-modal" role="dialog" aria-modal="true" aria-label="Recommended actions" onClick={(e) => e.stopPropagation()}>
        <button type="button" className="ra-close" onClick={onClose} aria-label="Close">
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"><line x1="6" y1="6" x2="18" y2="18" /><line x1="18" y1="6" x2="6" y2="18" /></svg>
        </button>
        <div className="ra-body" style={{ width: '637px', height: '399px' }}>
          <div className="ra-title">Recommended actions</div>
          <div className="ra-sub">Choose from our suggested actions</div>
          <div className="ra-list" style={{ marginTop: '22px' }}>
            {recs.map((r, i) =>
            <button key={i} type="button" className="ra-row">
                <span className="ra-ic" aria-hidden="true">{r.icon}</span>
                <span className="ra-txt">
                  <span className="ra-row-title">{r.title}</span>
                  <span className="ra-row-sub">{r.sub}</span>
                </span>
                <span className="ra-arrow" aria-hidden="true">
                  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="7" y1="17" x2="17" y2="7" /><polyline points="9 7 17 7 17 15" /></svg>
                </span>
              </button>
            )}
          </div>
        </div>
      </div>
    </div>);

}

function AttentionCard({ severity, headline, diagnostic, cta, onCta }) {
  const sev = SEVERITY[severity];
  return (
    <div className="attn-cell">
      <div className="attn-sev" style={{ color: sev.color }}>
        {severity}
      </div>
      <div className="attn-head">{headline}</div>
      <div className="attn-diag">{diagnostic}</div>
      <a className="attn-cta" href="#" onClick={(e) => { if (onCta) { e.preventDefault(); onCta(); } }}>
        {cta} <IconArrowRight size={14} stroke="#004CE6" />
      </a>
    </div>);

}

function AttentionRail() {
  const [showRecs, setShowRecs] = useState(false);
  const cards = [
  { severity: "CRITICAL", headline: "Inbound calls dropped 18%", diagnostic: "411 vs 501 prior week", cta: "View actions", onCta: () => setShowRecs(true) },
  { severity: "WARNING", headline: "Avg wait time creeping up", diagnostic: "47s vs 32s last week", cta: "See queues" },
  { severity: "INSIGHT", headline: "Tuesday 2–4pm is your peak", diagnostic: "31% of weekly volume", cta: "Open schedule" },
  { severity: "POSITIVE", headline: "AI resolution up 8%", diagnostic: "62% auto-resolved · ~14 hrs saved", cta: "View details" }];

  return (
    <div className="card attn-summary">
      <div className="attn-summary-head" style={{ color: "rgb(252, 252, 253)" }}>
        <span className="attn-summary-title">
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" style={{ verticalAlign: "-4px", marginRight: "6px" }}>
            <defs>
              <linearGradient id="ai-spark" x1="0" y1="0" x2="1" y2="1">
                <stop offset="0%" stopColor="#673BFF" />
                <stop offset="100%" stopColor="#2D72FF" />
              </linearGradient>
            </defs>
            <path d="M12 3 C12 7.5 13.5 9 18 9 C13.5 9 12 10.5 12 15 C12 10.5 10.5 9 6 9 C10.5 9 12 7.5 12 3 Z" fill="url(#ai-spark)" />
            <path d="M18.5 14 C18.5 16 19 16.5 21 16.5 C19 16.5 18.5 17 18.5 19 C18.5 17 18 16.5 16 16.5 C18 16.5 18.5 16 18.5 14 Z" fill="url(#ai-spark)" />
          </svg>
          AI Summary
        </span>
      </div>
      <div className="attn-summary-grid">
        {cards.map((c, i) => <AttentionCard key={i} {...c} />)}
      </div>
      {showRecs && <RecommendedActionsModal onClose={() => setShowRecs(false)} />}
    </div>);

}

/* ────────────────────────────────────────────────────────────
   Hero — primary metric + AI digest
   ──────────────────────────────────────────────────────────── */

function PrimaryMetric() {
  const target = 70;
  const value = 67;
  return (
    <div className="card hero-left">
      <div className="metric-label">
        <div className="metric-label-stack">
          <span className="t-label-xs" style={{ color: "#667085" }}>Service level today</span>
          <span className="metric-sub">Operations</span>
        </div>
      </div>

      <div className="metric-body">
        <div className="metric-value">
          <span className="big-num">{value}</span><span className="big-pct">%</span>
        </div>
      </div>

      <div className="goal">
        <div className="goal-bar-thin">
          <div className="goal-fill-thin" style={{ width: `${value}%` }} />
          <div className="goal-target-thin" style={{ left: `${target}%` }} />
        </div>
        <div className="goal-foot">
          <span>0%</span>
          <span className="goal-target-text">Target: {target}%</span>
        </div>
      </div>

      <div className="metric-foot">
        <span className="chip chip-down">
          <IconArrowDown size={12} /> 3% vs prior period
        </span>
        <span className="metric-context">vs last week</span>
      </div>
    </div>);

}

function NarrativeDigest() {
  const bullets = [
  { kind: "down", text: <><b>Service level slipped to 67%</b> — below the 70% target for the first time in 6 weeks, driven by a 42% jump in missed calls.</> },
  { kind: "down", text: <><b>Tuesday 2–4pm peak is the pressure point</b> — 31% of weekly volume lands there, and queue overflow caused most abandonment.</> },
  { kind: "up", text: <><b>CSAT climbed to 4.6</b> from 4.3 — fast answers are driving it: callers reached within 20s consistently rate calls higher.</> },
  { kind: "up", text: <><b>Sales dialer connect rate hit 34%</b> vs 29% three weeks ago — local-presence numbers are paying off.</> }];

  return (
    <div className="card hero-right" style={{ color: "rgb(198, 198, 198)" }}>
      <div className="digest-head">
        <span className="digest-title" style={{ color: "rgb(102, 112, 133)", fontSize: "10px", letterSpacing: "0.2px" }}>WEEK ON WEEK MOVEMENT</span>
      </div>
      <ul className="digest-list">
        {bullets.map((b, i) =>
        <li key={i}>
            <span className={"bullet bullet-" + b.kind}>
              {b.kind === "up" ? <IconArrowUp size={10} stroke="white" strokeWidth={3} /> : <IconArrowDown size={10} stroke="white" strokeWidth={3} />}
            </span>
            <span className="digest-text">{b.text}</span>
          </li>
        )}
      </ul>
    </div>);

}

/* ────────────────────────────────────────────────────────────
   At-a-glance strip
   ──────────────────────────────────────────────────────────── */

const STATUS = {
  on: { label: "On track", bg: "#ECFDF3", color: "#027A48", dot: "#12B76A" },
  below: { label: "Below target", bg: "#FEF3F2", color: "#D92D20", dot: "#D92D20" },
  risk: { label: "At risk", bg: "#FFFAEB", color: "#B54708", dot: "#F79009" }
};

function GlanceCard({ label, value, suffix, spark, status, delta, tip }) {
  const s = STATUS[status];
  return (
    <div className="card glance-card">
      <div className="glance-head">
        <div className="t-label-xs label-with-tip" style={{ color: "#667085" }}>
          {label}{tip && <InfoTip text={tip} />}
        </div>
        <span className="status-chip" style={{ background: s.bg, color: s.color }}>
          <span className="status-dot" style={{ background: s.dot }} />
          {s.label}
        </span>
      </div>
      <div className="glance-body">
        <div className="glance-value">
          <span className="big-num-md">{value}</span>
          {suffix && <span className="big-pct-md">{suffix}</span>}
          <span className={"delta " + (delta.dir === "down" ? "delta-down" : delta.dir === "up" ? "delta-up" : "delta-neutral")}>
            {delta.dir === "down" ? <IconArrowDown size={11} /> : delta.dir === "up" ? <IconArrowUp size={11} /> : null}
            {delta.text}
          </span>
        </div>
        <Sparkline data={spark} w={120} h={42} color={status === "below" ? "#D92D20" : status === "risk" ? "#F79009" : "#12B76A"} />
      </div>
    </div>);

}

function GlanceStrip() {
  const cards = [
  { label: "Service Level", value: "67", suffix: "%", spark: [62, 65, 64, 66, 70, 68, 67], status: "below", delta: { dir: "down", text: "3% vs prior" } },
  { label: "AI Resolution", value: "62", suffix: "%", spark: [54, 55, 58, 57, 60, 61, 62], status: "on", delta: { dir: "up", text: "8% vs prior" } },
  { label: "Dialer Connect Rate", value: "34", suffix: "%", spark: [29, 30, 31, 30, 32, 33, 34], status: "on", delta: { dir: "up", text: "5% vs prior" } },
  { label: "CSAT", value: "4.6", suffix: "/5", spark: [4.3, 4.4, 4.4, 4.5, 4.5, 4.5, 4.6], status: "on", delta: { dir: "up", text: "0.3 vs prior" } }];

  return (
    <div className="glance-strip">
      {cards.map((c, i) => <GlanceCard key={i} {...c} />)}
    </div>);

}

function GlanceGrid() {
  const cards = [
  { label: "Service Level", tip: "% of inbound calls answered within target time (typically 20s). Below 80% means callers are waiting too long.", value: "67", suffix: "%", spark: [62, 65, 64, 66, 70, 68, 67], status: "below", delta: { dir: "down", text: "3% vs prior" } },
  { label: "AI Resolution", tip: "% of AI-handled conversations resolved without human handover. Higher means the AI agent is deflecting more cases successfully.", value: "62", suffix: "%", spark: [54, 55, 58, 57, 60, 61, 62], status: "on", delta: { dir: "up", text: "8% vs prior" } },
  { label: "Dialer Connect Rate", tip: "% of outbound dialer attempts that reach a live person. Tracks list quality and dial-time effectiveness.", value: "34", suffix: "%", spark: [29, 30, 31, 30, 32, 33, 34], status: "on", delta: { dir: "up", text: "5% vs prior" } },
  { label: "CSAT", tip: "Customer satisfaction score from post-call surveys, on a 1–5 scale. Reflects perceived quality of support interactions.", value: "4.6", suffix: "/5", spark: [4.3, 4.4, 4.4, 4.5, 4.5, 4.5, 4.6], status: "on", delta: { dir: "up", text: "0.3 vs prior" } }];

  return (
    <div className="glance-grid">
      {cards.map((c, i) => <GlanceCard key={i} {...c} />)}
    </div>);

}

/* ────────────────────────────────────────────────────────────
   Sectioned metric card (chart card)
   ──────────────────────────────────────────────────────────── */

function MetricCard({ title, tip, value, suffix, delta, status, children, footer }) {
  const s = status ? STATUS[status] : null;
  return (
    <div className="card metric-card">
      <div className="mc-head">
        <div className="mc-label t-label-xs label-with-tip" style={{ color: "#667085" }}>
          {title}{tip && <InfoTip text={tip} />}
        </div>
        {s &&
        <span className="status-chip status-chip-sm" style={{ background: s.bg, color: s.color }}>
            <span className="status-dot" style={{ background: s.dot }} />
            {s.label}
          </span>
        }
      </div>
      <div className="mc-value-row">
        <div className="mc-value">
          <span className="big-num-sm">{value}</span>
          {suffix && <span className="big-pct-sm">{suffix}</span>}
        </div>
        {delta &&
        <span className={"delta " + (delta.dir === "down" ? "delta-down" : delta.dir === "up" ? "delta-up" : "delta-neutral")}>
            {delta.dir === "down" ? <IconArrowDown size={11} /> : delta.dir === "up" ? <IconArrowUp size={11} /> : null}
            {delta.text}
          </span>
        }
      </div>
      <div className="mc-chart">{children}</div>
      {footer && <div className="mc-foot">{footer}</div>}
    </div>);

}

/* ────────────────────────────────────────────────────────────
   Sections
   ──────────────────────────────────────────────────────────── */

const DAY_LABELS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];

function SectionLabel({ children }) {
  return <div className="section-label">{children}</div>;
}

function ViewAllCard({ title, sub, href = "#" }) {
  return (
    <a className="view-all-card" href={href}>
      <div>
        <div className="va-title">{title}</div>
        <div className="va-sub">{sub}</div>
      </div>
      <span className="va-cta">View all <IconArrowRight size={14} /></span>
    </a>);

}

function Sankey({ h = 360 }) {
  const wrapRef = React.useRef(null);
  const [w, setW] = React.useState(920);
  useEffect(() => {
    const el = wrapRef.current;
    if (!el) return;
    const measure = () => setW(Math.max(700, el.clientWidth));
    measure();
    const ro = new ResizeObserver(measure);
    ro.observe(el);
    return () => ro.disconnect();
  }, []);
  const padX = 8;
  const rightLabelW = 160;
  const padY = 12;
  const nodeW = 18;
  const colW = (w - padX - rightLabelW - nodeW * 4) / 3;
  const [hover, setHover] = React.useState(null);

  const COL = {
    totalDark: "#1A5876",   // deep teal-navy for Total Calls
    outboundBlue: "#3690BC", // medium teal-blue
    blueMid: "#7DBADA",      // light blue (col 2 outbound calls)
    blueLite: "#CFE3EF",     // very light blue (sales dialer)
    inboundPurple: "#7C3AED",// vivid purple
    purpleMid: "#A78BFA",    // medium light purple (col 2 inbound calls)
    purpleLite: "#D5C7FA",   // very light purple (ai agent)
    teal: "#7DD8B7",         // mint green (positive outcomes)
    coral: "#F09782",        // soft coral (negative outcomes)
    amber: "#F8B94D",        // amber (machine / handover)
    // legacy aliases used elsewhere
    blue: "#3690BC",
    blueLight: "#7DBADA",
    purple: "#7C3AED",
    purpleLight: "#A78BFA"
  };

  const root = { id: "total", label: "Total Calls", value: 1200, col: 0, color: COL.totalDark };
  const outbound = { id: "out", label: "Outbound Calls", value: 600, col: 1, color: COL.outboundBlue };
  const inbound = { id: "in", label: "Inbound Calls", value: 600, col: 1, color: COL.inboundPurple };
  const outCalls = { id: "outCalls", label: "Calls", value: 300, col: 2, color: COL.blueMid };
  const sales = { id: "sales", label: "Sales Dialer Calls", value: 300, col: 2, color: COL.blueLite };
  const inCalls = { id: "inCalls", label: "Calls", value: 350, col: 2, color: COL.purpleMid };
  const aiAgent = { id: "aiAgent", label: "AI Agent Calls", value: 250, col: 2, color: COL.purpleLite };
  const connected = { id: "connected", label: "Connected", value: 200, col: 3, color: COL.teal };
  const notConnected1 = { id: "nc1", label: "Not Connected", value: 100, col: 3, color: COL.coral };
  const connectedHuman = { id: "ch", label: "Connected to Human", value: 150, col: 3, color: COL.teal };
  const connectedMachine = { id: "cm", label: "Connected to Machine", value: 100, col: 3, color: COL.amber };
  const notConnected2 = { id: "nc2", label: "Not Connected", value: 50, col: 3, color: COL.coral };
  const answered = { id: "answered", label: "Answered", value: 250, col: 3, color: COL.teal };
  const missed = { id: "missed", label: "Missed", value: 100, col: 3, color: COL.coral };
  const aiAnswered = { id: "aiAnswered", label: "Answered", value: 50, col: 3, color: COL.teal };
  const handover = { id: "handover", label: "Human Handover", value: 200, col: 3, color: COL.amber };

  const cols = [
  [root],
  [outbound, inbound],
  [outCalls, sales, inCalls, aiAgent],
  [connected, notConnected1, connectedHuman, connectedMachine, notConnected2, answered, missed, aiAnswered, handover]];


  const innerH = h - padY * 2;
  const minGap = 10;
  const branchGap = 50;
  const baseScale = (innerH - branchGap) / 1200;

  // Position outbound branch (top) and inbound branch (bottom), centered as a pair
  const totalContentH = 1200 * baseScale + branchGap;
  const topY = padY + (innerH - totalContentH) / 2;

  // Col 0: root spans full content (1200 units, NO internal gap so flows leaving stack correctly)
  root.h = 1200 * baseScale + branchGap; // include branchGap so its outflows can split
  root.y = topY;
  root.x = padX;

  // Col 1: outbound at top, inbound at bottom of root with branchGap
  outbound.h = 600 * baseScale;
  outbound.y = topY;
  outbound.x = padX + (nodeW + colW);
  inbound.h = 600 * baseScale;
  inbound.y = topY + 600 * baseScale + branchGap;
  inbound.x = outbound.x;

  // Col 2: outbound's children stacked at outbound.y; inbound's children stacked at inbound.y
  // Use minGap between siblings within a branch.
  const layoutCol2 = (parent, kids) => {
    const sum = kids.reduce((s, k) => s + k.value, 0);
    const gapsCount = kids.length - 1;
    const totalKidH = sum * baseScale + gapsCount * minGap;
    let y = parent.y + (parent.h - totalKidH) / 2; // center within parent's vertical extent
    kids.forEach((k) => {
      k.h = k.value * baseScale;
      k.y = y;
      k.x = padX + 2 * (nodeW + colW);
      y += k.h + minGap;
    });
  };
  layoutCol2(outbound, [outCalls, sales]);
  layoutCol2(inbound, [inCalls, aiAgent]);

  // Col 3: 9 outcomes — group by parent, align with each parent's vertical extent
  const col3X = padX + 3 * (nodeW + colW);
  const layoutCol3 = (parent, kids) => {
    const sum = kids.reduce((s, k) => s + k.value, 0);
    const gapsCount = kids.length - 1;
    const totalKidH = sum * baseScale + gapsCount * minGap;
    let y = parent.y + (parent.h - totalKidH) / 2;
    kids.forEach((k) => {
      k.h = k.value * baseScale;
      k.y = y;
      k.x = col3X;
      y += k.h + minGap;
    });
  };
  layoutCol3(outCalls, [connected, notConnected1]);
  layoutCol3(sales, [connectedHuman, connectedMachine, notConnected2]);
  layoutCol3(inCalls, [answered, missed]);
  layoutCol3(aiAgent, [aiAnswered, handover]);

  const flows = [
  { from: root, to: outbound, value: 600, color: COL.blue },
  { from: root, to: inbound, value: 600, color: COL.purple },
  { from: outbound, to: outCalls, value: 300, color: COL.blue },
  { from: outbound, to: sales, value: 300, color: COL.blueLight },
  { from: inbound, to: inCalls, value: 350, color: COL.purple },
  { from: inbound, to: aiAgent, value: 250, color: COL.purpleLight },
  { from: outCalls, to: connected, value: 200, color: COL.teal },
  { from: outCalls, to: notConnected1, value: 100, color: COL.coral },
  { from: sales, to: connectedHuman, value: 150, color: COL.teal },
  { from: sales, to: connectedMachine, value: 100, color: COL.amber },
  { from: sales, to: notConnected2, value: 50, color: COL.coral },
  { from: inCalls, to: answered, value: 250, color: COL.teal },
  { from: inCalls, to: missed, value: 100, color: COL.coral },
  { from: aiAgent, to: aiAnswered, value: 50, color: COL.teal },
  { from: aiAgent, to: handover, value: 200, color: COL.amber }];


  const outOff = {};
  const inOff = {};
  cols.flat().forEach((n) => {outOff[n.id] = 0;inOff[n.id] = 0;});

  const paths = flows.map((f, i) => {
    const thickness = f.value * baseScale;
    const x0 = f.from.x + nodeW;
    const x1 = f.to.x;
    let y0;
    if (f.from.id === "total") {
      // Anchor outflows at root's vertical extent split into branches with branchGap
      if (f.to.id === "out") {
        y0 = root.y + outbound.h / 2;
      } else {
        y0 = root.y + outbound.h + branchGap + inbound.h / 2;
      }
    } else {
      y0 = f.from.y + outOff[f.from.id] + thickness / 2;
      outOff[f.from.id] += thickness;
    }
    const y1 = f.to.y + inOff[f.to.id] + thickness / 2;
    inOff[f.to.id] += thickness;
    const cx = (x0 + x1) / 2;
    // Add tiny y-offset to avoid Chromium degenerate-bbox bug on perfectly-flat horizontal flows
    const y0adj = y0 + (y0 === y1 ? 0.01 : 0);
    const d = `M ${x0} ${y0adj} C ${cx} ${y0adj}, ${cx} ${y1}, ${x1} ${y1}`;
    return { d, color: f.color, thickness, key: i, flow: f, midX: cx, midY: (y0 + y1) / 2 };
  });

  const fmt = (v) => `${v.toLocaleString()} (${Math.round(v / 1200 * 100)}%)`;
  const colorKeyOf = (c) => Object.entries(COL).find(([k, v]) => v === c)[0];

  const colNodes = cols.map((arr) => arr.slice().sort((a, b) => a.y - b.y));
  const labelMinSpacing = 32;
  const labelPositions = {};
  colNodes.forEach((nodes) => {
    let prevBottom = -Infinity;
    nodes.forEach((n) => {
      let cy = n.y + n.h / 2;
      if (cy - labelMinSpacing / 2 < prevBottom) cy = prevBottom + labelMinSpacing / 2;
      labelPositions[n.id] = cy;
      prevBottom = cy + labelMinSpacing / 2;
    });
  });

  const isHi = (f) => {
    if (!hover) return null;
    if (hover.kind === "flow" && hover.id === f.key) return true;
    if (hover.kind === "node" && (f.flow.from.id === hover.id || f.flow.to.id === hover.id)) return true;
    return false;
  };

  return (
    <div className="sankey-wrap" ref={wrapRef} onMouseLeave={() => setHover(null)}>
      <svg viewBox={`0 0 ${w} ${h}`} width="100%" height={h} style={{ display: "block", overflow: "visible" }}>
        <defs>
          {Object.entries(COL).map(([k, c]) =>
          <linearGradient key={k} id={`sk-${k}`} x1="0" x2="1" y1="0" y2="0">
              <stop offset="0%" stopColor={c} stopOpacity="0.32" />
              <stop offset="100%" stopColor={c} stopOpacity="0.18" />
            </linearGradient>
          )}
          {Object.entries(COL).map(([k, c]) =>
          <linearGradient key={"hi-" + k} id={`sk-hi-${k}`} x1="0" x2="1" y1="0" y2="0">
              <stop offset="0%" stopColor={c} stopOpacity="0.65" />
              <stop offset="100%" stopColor={c} stopOpacity="0.45" />
            </linearGradient>
          )}
        </defs>
        {paths.map((p) => {
          const ck = colorKeyOf(p.color);
          const hi = isHi(p);
          const opacity = hover ? hi ? 1 : 0.1 : 1;
          const grad = hi ? `url(#sk-hi-${ck})` : `url(#sk-${ck})`;
          return (
            <path key={p.key} d={p.d} stroke={grad} strokeWidth={p.thickness} fill="none" strokeLinecap="butt"
            style={{ opacity, transition: "opacity .22s ease" }}
            onMouseEnter={() => setHover({ kind: "flow", id: p.key, x: p.midX, y: p.midY, label: `${p.flow.from.label} → ${p.flow.to.label}`, value: p.flow.value })} />);


        })}
        {cols.flat().map((n) => {
          const active = hover && (hover.kind === "node" ? hover.id === n.id :
          paths.find((p) => p.key === hover.id)?.flow.from.id === n.id ||
          paths.find((p) => p.key === hover.id)?.flow.to.id === n.id);
          return (
            <g key={n.id}
            onMouseEnter={() => setHover({ kind: "node", id: n.id, x: n.x + nodeW / 2, y: n.y + n.h / 2, label: n.label, value: n.value })}
            style={{ cursor: "pointer" }}>
              <rect x={n.x - 2} y={n.y} width={nodeW + 4} height={n.h} rx="1" fill={n.color}
              style={{ opacity: hover && !active ? 0.35 : 1, transition: "opacity .22s ease" }} />
            </g>);

        })}
      </svg>
      <div className="sankey-labels">
        {cols.flat().map((n) => {
          const cy = labelPositions[n.id];
          // Per-column label placement
          let left, transformExtra = "";
          if (n.col === 0) {
            // Total Calls — sit just to the right of the bar (inside the chart)
            left = `calc(${(n.x + nodeW) / w * 100}% + 8px)`;
          } else if (n.col === 1) {
            // Outbound / Inbound — 12px to the right of the bar
            left = `calc(${(n.x + nodeW) / w * 100}% + 12px)`;
          } else if (n.col === 3) {
            // End column — pull labels closer to the bars
            left = `calc(${(n.x + nodeW) / w * 100}% + 8px)`;
          } else {
            left = `calc(${(n.x + nodeW) / w * 100}% + 10px)`;
          }
          const top = `${cy / h * 100}%`;
          const active = hover && (hover.kind === "node" ? hover.id === n.id :
          (() => {
            const p = paths.find((pp) => pp.key === hover.id);
            return p && (p.flow.from.id === n.id || p.flow.to.id === n.id);
          })());
          return (
            <div key={n.id} className="sk-label" style={{ left, top, transform: "translateY(-50%)", opacity: hover && !active ? 0.35 : 1 }}>
              <div className="sk-label-name">{n.label}</div>
              <div className="sk-label-val">{fmt(n.value)}</div>
            </div>);

        })}
        {hover &&
        <div className="sk-tip" style={{ left: `${hover.x / w * 100}%`, top: `${hover.y / h * 100}%` }}>
            <div className="sk-tip-label">{hover.label}</div>
            <div className="sk-tip-val">{hover.value.toLocaleString()} calls · {Math.round(hover.value / 1200 * 100)}% of total</div>
          </div>
        }
      </div>
    </div>);

}

function CallActivity() {
  return (
    <section className="section">
      <SectionLabel>Call Activity</SectionLabel>
      <div className="row-3 row-3-sankey">
        <div className="card sankey-card">
          <div className="mc-head">
            <div className="mc-label t-label-xs label-with-tip" style={{ color: "#667085" }}>
              Call type distribution<InfoTip text="How total calls split across outbound vs inbound, dialer vs AI agent paths, and final outcomes." />
            </div>
            <div className="t-label-xs" style={{ color: "#98A2B3" }}>Total <b style={{ color: "#101828" }}>1,200</b> calls · this week</div>
          </div>
          <Sankey h={440} />
        </div>

      </div>
    </section>);

}

function ConversionTeam() {
  return (
    <section className="section">
      <SectionLabel>Operations & Team</SectionLabel>
      <div className="row-3">
        <MetricCard
          title="Service level detail"
          tip="Detailed view of how quickly inbound calls are being answered, broken out by day."
          value="67"
          suffix="%"
          delta={{ dir: "down", text: "3% vs prior" }}
          status="below"
          footer={<>Target <b>≥ 70%</b></>}>
          
          <LineChart data={[72, 70, 68, 71, 69, 68, 67]} labels={DAY_LABELS} h={140} target={70} valueSuffix="%" />
        </MetricCard>
        <MetricCard
          title="Team performance"
          tip="Distribution of agents across performance tiers based on quota attainment, call quality, and CSAT."
          value="14"
          delta={{ dir: "neutral", text: "agents this week" }}
          status="on"
          footer={<>Distribution by quota attainment</>}>
          
          <TeamTiers />
        </MetricCard>

      </div>
    </section>);

}

function TeamTiers() {
  const tiers = [
  { tier: "Top performers", count: 4, share: 0.34, color: "#004CE6", note: "≥ 110% of quota" },
  { tier: "On track", count: 7, share: 0.52, color: "#9DB9F5", note: "85–110% of quota" },
  { tier: "Needs coaching", count: 3, share: 0.14, color: "#E4E7EC", note: "< 85% of quota" }];

  return (
    <div className="tier-list">
      {tiers.map((t, i) =>
      <div key={i} className="tier-row">
          <div className="tier-head">
            <span className="tier-name">{t.tier}</span>
            <span className="tier-count">{t.count} <span className="tier-of">of 14</span></span>
          </div>
          <div className="tier-bar">
            <div className="tier-fill" style={{ width: `${t.share * 100}%`, background: t.color }} />
          </div>
          <div className="tier-note">{t.note}</div>
        </div>
      )}
    </div>);

}

function Incentives() {
  const reps = [
  { name: "Priya S.", pct: 1.18, payout: "$2,400", color: "#004CE6" },
  { name: "Marcus T.", pct: 1.04, payout: "$1,650", color: "#004CE6" },
  { name: "Jamie L.", pct: 0.92, payout: "$900", color: "#9DB9F5" },
  { name: "Devon K.", pct: 0.71, payout: "—", color: "#E4E7EC" }];
  return (
    <div className="tier-list">
      {reps.map((r, i) =>
      <div key={i} className="tier-row">
          <div className="tier-head">
            <span className="tier-name">{r.name}</span>
            <span className="tier-count">{r.payout}</span>
          </div>
          <div className="tier-bar">
            <div className="tier-fill" style={{ width: `${Math.min(r.pct, 1.2) / 1.2 * 100}%`, background: r.color }} />
          </div>
          <div className="tier-note">{Math.round(r.pct * 100)}% of quota</div>
        </div>
      )}
    </div>);
}

function Revenue() {
  return (
    <section className="section">
      <SectionLabel>Revenue</SectionLabel>
      <div className="row-3">
        <MetricCard
          title="Incentives"
          tip="Quarterly bonus tracker. Sums per-rep payouts based on quota attainment and other accelerators."
          value="$4,950"
          delta={{ dir: "up", text: "tracking to payout" }}
          status="on"
          footer={<>Q2 payout · <b>3 of 4</b> on pace</>}>
          
          <Incentives />
        </MetricCard>
        <MetricCard
          title="CSAT trend"
          tip="7-day rolling CSAT average from post-call surveys. Helps spot quality issues before they impact revenue."
          value="4.6"
          suffix="/5"
          delta={{ dir: "up", text: "0.3 vs prior" }}
          status="on"
          footer={<><b>1,142</b> responses</>}>
          
          <LineChart data={[4.2, 4.3, 4.3, 4.4, 4.5, 4.5, 4.6]} labels={["W-3", "W-2", "W-1", "Mon", "Tue", "Wed", "Thu"]} h={140} target={4.5} valueSuffix="/5" />
        </MetricCard>

      </div>
    </section>);

}

/* ────────────────────────────────────────────────────────────
   App
   ──────────────────────────────────────────────────────────── */

function RangeFilter({ value, onChange }) {
  const opts = ["Today", "Week", "Month"];
  return (
    <div className="range-filter" role="tablist" aria-label="Date range">
      {opts.map(o => (
        <button
          key={o}
          type="button"
          role="tab"
          aria-selected={o === value}
          className={"range-filter-seg" + (o === value ? " is-active" : "")}
          onClick={() => onChange(o)}
        >
          {o}
        </button>
      ))}
    </div>
  );
}

function App() {
  return (
    <div className="content">
      <AttentionRail />
      <div className="hero">
        <GlanceGrid />
        <NarrativeDigest />
      </div>
      <CallActivity />
      <ConversionTeam />
      <Revenue />
      <div className="page-foot">End of overview \u00b7 Updated every 15 seconds</div>
    </div>);
}

// Mounted on demand by renderAnalyticsSub() when the Overview tab is opened.
// The surrounding sidebar and topbar come from the app shell in index.html —
// the original standalone version rendered its own copy, which is not used here.
window.mountAnalyticsOverview = function (el) {
  if (!el || el.__mounted) return;
  el.__mounted = true;
  ReactDOM.createRoot(el).render(<App />);
};
})();
