// Shared primitives used across the dashboard.
// Lucide icons attached as window.Lucide via UMD CDN.

const { useState, useEffect, useRef } = React;

function Icon({ name, size = 16, color, strokeWidth = 1.5, style }) {
  const lib = window.lucide;
  if (!lib) return null;
  // Lucide UMD 0.378 exposes icons as PascalCase keys (e.g. lucide.LayoutDashboard).
  // Format: [tagName, attrs, [[childTag, childAttrs], ...]]
  const icon = lib[name];
  if (!icon || !Array.isArray(icon)) return null;
  const children = Array.isArray(icon[2]) ? icon[2] : [];
  function renderNode(node, key) {
    if (!Array.isArray(node)) return null;
    const [tag, attrs, kids] = node;
    const kidEls = Array.isArray(kids) ? kids.map((c, i) => renderNode(c, i)) : null;
    return React.createElement(tag, { key, ...attrs }, kidEls);
  }
  return (
    <svg
      width={size} height={size} viewBox="0 0 24 24"
      fill="none" stroke={color || 'currentColor'}
      strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round"
      style={style}
    >
      {children.map((c, i) => renderNode(c, i))}
    </svg>
  );
}
window.Icon = Icon;

function Pill({ variant = 'outline', size, onClick, children, type, disabled, style, className = '' }) {
  return (
    <button
      type={type || 'button'}
      onClick={onClick}
      disabled={disabled}
      style={style}
      className={`pill ${variant} ${size === 'sm' ? 'sm' : ''} ${className}`}
    >
      <span className="lbl">{children}</span>
    </button>
  );
}
window.Pill = Pill;

function Card({ title, sub, eyebrow, actions, children, pad, lift, style, className = '', onClick }) {
  return (
    <div
      className={`card ${pad === 'lg' ? 'card-pad-lg' : ''} ${pad === 'tight' ? 'card-tight' : ''} ${lift ? 'lift' : ''} ${className}`}
      style={style}
      onClick={onClick}
    >
      {(title || actions || eyebrow) && (
        <div className="card-head">
          <div>
            {eyebrow && <div className="card-eyebrow">{eyebrow}</div>}
            {title && <h3 className="card-title">{title}</h3>}
            {sub && <div className="card-sub">{sub}</div>}
          </div>
          {actions && <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexShrink: 0 }}>{actions}</div>}
        </div>
      )}
      {children}
    </div>
  );
}
window.Card = Card;

function StatusChip({ status }) {
  const map = {
    healthy: { cls: 'healthy', label: 'Healthy' },
    risk: { cls: 'risk', label: 'At risk' },
    churn: { cls: 'churn', label: 'Churn risk' },
    active: { cls: 'healthy', label: 'Active' },
    paused: { cls: 'risk', label: 'Paused' },
    review: { cls: 'risk', label: 'Needs review' },
    connected: { cls: 'connected', label: 'Connected' },
    disconnected: { cls: 'disconnected', label: 'Not connected' },
    new: { cls: '', label: 'New' },
    researching: { cls: 'risk', label: 'Researching' },
    pursuing: { cls: 'healthy', label: 'Pursuing' },
    passed: { cls: 'disconnected', label: 'Passed' },
  };
  const v = map[String(status).toLowerCase()] || { cls: '', label: status };
  return (
    <span className={`chip ${v.cls}`}>
      {v.cls && <span className="chip-dot" />}
      {v.label}
    </span>
  );
}
window.StatusChip = StatusChip;

function ScorePill({ score }) {
  let cls = 'lo';
  if (score >= 70) cls = 'hi';
  else if (score >= 40) cls = 'mid';
  return <span className={`score-pill ${cls}`}>{score}</span>;
}
window.ScorePill = ScorePill;

function Delta({ value }) {
  if (value == null || isNaN(value)) return null;
  const pos = value >= 0;
  return (
    <span className={`kpi-delta ${pos ? 'pos' : 'neg'}`}>
      <Icon name={pos ? 'ArrowUpRight' : 'ArrowDownRight'} size={12} />
      <span>{window.fmtDelta(value)}</span>
    </span>
  );
}
window.Delta = Delta;

function Sparkline({ data, color = 'var(--brand-red)', width = 72, height = 28 }) {
  if (!data || !data.length) return null;
  const min = Math.min(...data);
  const max = Math.max(...data);
  const range = max - min || 1;
  const stepX = width / (data.length - 1);
  const pts = data.map((v, i) => {
    const x = i * stepX;
    const y = height - ((v - min) / range) * (height - 2) - 1;
    return [x, y];
  });
  // Smooth curve via Catmull-Rom-ish quadratic interpolation between points.
  // Gives the sparkline a softer, less jagged feel without a full cubic curve.
  let path = `M${pts[0][0]},${pts[0][1]}`;
  for (let i = 0; i < pts.length - 1; i++) {
    const [x0, y0] = pts[i];
    const [x1, y1] = pts[i + 1];
    const mx = (x0 + x1) / 2;
    const my = (y0 + y1) / 2;
    path += ` Q${x0},${y0} ${mx},${my}`;
  }
  // Snap to the final point so the line ends precisely on the last value.
  const last = pts[pts.length - 1];
  path += ` T${last[0]},${last[1]}`;
  const areaPath = `${path} L${last[0]},${height} L0,${height} Z`;
  // Unique gradient id per render so multiple sparklines coexist.
  const gradId = 'spkg_' + Math.random().toString(36).slice(2, 8);
  return (
    <svg className="kpi-spark" viewBox={`0 0 ${width} ${height}`} preserveAspectRatio="none">
      <defs>
        <linearGradient id={gradId} x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor={color} stopOpacity="0.22" />
          <stop offset="100%" stopColor={color} stopOpacity="0" />
        </linearGradient>
      </defs>
      <path d={areaPath} fill={`url(#${gradId})`} />
      <path d={path} fill="none" stroke={color} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
      {/* End-point marker — small white-bordered dot anchoring the line. */}
      <circle cx={last[0]} cy={last[1]} r="2.2" fill={color} stroke="#fff" strokeWidth="1" />
    </svg>
  );
}
window.Sparkline = Sparkline;

function KpiCell({ label, value, delta, sparkData, sparkColor }) {
  return (
    <div className="kpi-cell">
      <div className="kpi-label">{label}</div>
      <div className="kpi-value tnum">{value}</div>
      {delta != null && <Delta value={delta} />}
      {sparkData && <Sparkline data={sparkData} color={sparkColor} />}
    </div>
  );
}
window.KpiCell = KpiCell;

function Toast({ toasts }) {
  return (
    <div className="toast-stack">
      {toasts.map((t) => (
        <div key={t.id} className={`toast ${t.kind || ''}`}>
          {t.kind === 'success' && <Icon name="Check" size={14} />}
          <span>{t.msg}</span>
        </div>
      ))}
    </div>
  );
}
window.Toast = Toast;

// Dropdown
function Dropdown({ trigger, children, align = 'right', direction = 'down' }) {
  const [open, setOpen] = useState(false);
  const ref = useRef(null);
  useEffect(() => {
    function onDoc(e) {
      if (ref.current && !ref.current.contains(e.target)) setOpen(false);
    }
    document.addEventListener('mousedown', onDoc);
    return () => document.removeEventListener('mousedown', onDoc);
  }, []);
  const menuClass = `dd-menu${direction === 'up' ? ' dd-menu-up' : ''}`;
  return (
    <div className="dropdown" ref={ref}>
      <div onClick={() => setOpen((v) => !v)}>{trigger}</div>
      {open && (
        <div className={menuClass} style={align === 'left' ? { left: 0, right: 'auto' } : null} onClick={() => setOpen(false)}>
          {children}
        </div>
      )}
    </div>
  );
}
window.Dropdown = Dropdown;

function SectionHeader({ title, desc, right }) {
  return (
    <div className="section-header">
      <div>
        <h1>{title}</h1>
      </div>
      <div style={{ display: 'flex', alignItems: 'flex-end', gap: 24 }}>
        {desc && <p className="desc">{desc}</p>}
        {right}
      </div>
    </div>
  );
}
window.SectionHeader = SectionHeader;

function Modal({ children, onClose }) {
  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()}>{children}</div>
    </div>
  );
}
window.Modal = Modal;

function SidePanel({ open, onClose, title, children }) {
  if (!open) return null;
  return (
    <React.Fragment>
      <div className="side-panel-backdrop" onClick={onClose} />
      <aside className="side-panel">
        <div className="side-panel-head">
          <div>
            <div className="card-eyebrow" style={{ margin: 0 }}>Prospect detail</div>
            <h3 className="card-title" style={{ marginTop: 6 }}>{title}</h3>
          </div>
          <button className="tlink" onClick={onClose} style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
            Close <Icon name="X" size={14} />
          </button>
        </div>
        <div className="side-panel-body">{children}</div>
      </aside>
    </React.Fragment>
  );
}
window.SidePanel = SidePanel;

// Range toggle (Last 7 / 30 / 90 / YTD)
function RangeToggle({ value, onChange, options = ['7D', '30D', '90D', 'YTD'] }) {
  return (
    <div className="range-toggle">
      {options.map((o) => (
        <button key={o} className={value === o ? 'active' : ''} onClick={() => onChange(o)}>{o}</button>
      ))}
    </div>
  );
}
window.RangeToggle = RangeToggle;

// ── ChartControls ────────────────────────────────────────
//
// A compact row of three dropdowns that lets the operator customize a chart:
//   1. Date range  (Last 7d / 30d / 90d / 12 months / Custom)
//   2. Metrics     (multi-select from `availableMetrics`)
//   3. Chart type  (line / bar / area / combo — from `availableChartTypes`)
//
// All state is owned by the parent; this component is purely controlled.
// The dropdowns reuse the existing Dropdown primitive so the popovers
// behave identically to the user account menu, view-as picker, etc.
//
// Props:
//   dateRange:           '7D' | '30D' | '90D' | '12M' | {start,end} (custom)
//   onDateRangeChange:   (next) => void
//   metrics:             string[] — currently selected metric ids
//   onMetricsChange:     (next: string[]) => void
//   availableMetrics:    [{ id, label }]
//   chartType:           'line' | 'bar' | 'area' | 'combo'
//   onChartTypeChange:   (next) => void
//   availableChartTypes: string[]
const DATE_RANGE_PRESETS = [
  { id: '7D',  label: 'Last 7 days' },
  { id: '30D', label: 'Last 30 days' },
  { id: '90D', label: 'Last 90 days' },
  { id: '12M', label: 'Last 12 months' },
];
const CHART_TYPE_META = {
  combo: { label: 'Combo',   icon: 'BarChart3' },
  line:  { label: 'Line',    icon: 'TrendingUp' },
  bar:   { label: 'Bar',     icon: 'BarChart2' },
  area:  { label: 'Area',    icon: 'AreaChart' },
};

function dateRangeLabel(value) {
  if (typeof value === 'string') {
    const found = DATE_RANGE_PRESETS.find((p) => p.id === value);
    return found ? found.label : value;
  }
  if (value && value.start && value.end) {
    const fmt = (s) => {
      const d = new Date(s);
      return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
    };
    return `${fmt(value.start)} – ${fmt(value.end)}`;
  }
  return 'Range';
}

function ChartControls({
  dateRange, onDateRangeChange,
  metrics, onMetricsChange, availableMetrics,
  chartType, onChartTypeChange, availableChartTypes,
}) {
  const [customOpen, setCustomOpen] = useState(false);
  const [customStart, setCustomStart] = useState(typeof dateRange === 'object' ? dateRange.start : '');
  const [customEnd, setCustomEnd] = useState(typeof dateRange === 'object' ? dateRange.end : '');

  function toggleMetric(id) {
    if (!metrics) return;
    if (metrics.includes(id)) onMetricsChange(metrics.filter((m) => m !== id));
    else onMetricsChange([...metrics, id]);
  }

  function applyCustom() {
    if (customStart && customEnd) {
      onDateRangeChange({ start: customStart, end: customEnd });
      setCustomOpen(false);
    }
  }

  const metricsLabel = (metrics || []).length === 0
    ? 'Metrics'
    : metrics.length === (availableMetrics || []).length
      ? 'All metrics'
      : (metrics.length === 1
          ? (availableMetrics.find((m) => m.id === metrics[0])?.label || metrics[0])
          : `${metrics.length} metrics`);

  return (
    <div className="chart-controls">
      {/* Date range */}
      <Dropdown
        align="right"
        trigger={
          <button className="dd-trigger dd-trigger-sm">
            <Icon name="Calendar" size={12} />
            <span>{dateRangeLabel(dateRange)}</span>
            <Icon name="ChevronDown" size={11} />
          </button>
        }
      >
        <div className="dd-section">Date range</div>
        {DATE_RANGE_PRESETS.map((p) => (
          <button key={p.id} className={`dd-item ${dateRange === p.id ? 'active' : ''}`} onClick={() => { onDateRangeChange(p.id); setCustomOpen(false); }}>
            <Icon name={dateRange === p.id ? 'Check' : 'Circle'} size={12} /> {p.label}
          </button>
        ))}
        <div className="dd-rule" />
        <button className={`dd-item ${typeof dateRange === 'object' ? 'active' : ''}`} onClick={(e) => { e.stopPropagation(); setCustomOpen((v) => !v); }}>
          <Icon name="CalendarRange" size={12} /> Custom range…
        </button>
        {customOpen && (
          <div style={{ padding: '8px 14px 12px', display: 'flex', flexDirection: 'column', gap: 6 }} onClick={(e) => e.stopPropagation()}>
            <label style={{ fontSize: 10.5, letterSpacing: '0.06em', color: 'var(--ink-stone)', textTransform: 'uppercase' }}>From</label>
            <input type="date" value={customStart} onChange={(e) => setCustomStart(e.target.value)} style={customInputStyle} />
            <label style={{ fontSize: 10.5, letterSpacing: '0.06em', color: 'var(--ink-stone)', textTransform: 'uppercase' }}>To</label>
            <input type="date" value={customEnd} onChange={(e) => setCustomEnd(e.target.value)} style={customInputStyle} />
            <button className="dd-item" onClick={applyCustom} disabled={!customStart || !customEnd}
              style={{ marginTop: 4, padding: '6px 10px', justifyContent: 'center', background: 'var(--rich-black)', color: 'var(--white)' }}>
              Apply
            </button>
          </div>
        )}
      </Dropdown>

      {/* Metrics multi-select */}
      <Dropdown
        align="right"
        trigger={
          <button className="dd-trigger dd-trigger-sm">
            <Icon name="SlidersHorizontal" size={12} />
            <span>{metricsLabel}</span>
            <Icon name="ChevronDown" size={11} />
          </button>
        }
      >
        <div className="dd-section">Metrics</div>
        {(availableMetrics || []).map((m) => {
          const selected = (metrics || []).includes(m.id);
          return (
            <button key={m.id} className={`dd-item ${selected ? 'active' : ''}`}
              onClick={(e) => { e.stopPropagation(); toggleMetric(m.id); }}>
              <Icon name={selected ? 'CheckSquare' : 'Square'} size={12} /> {m.label}
            </button>
          );
        })}
      </Dropdown>

      {/* Chart type */}
      <Dropdown
        align="right"
        trigger={
          <button className="dd-trigger dd-trigger-sm">
            <Icon name={(CHART_TYPE_META[chartType] || CHART_TYPE_META.combo).icon} size={12} />
            <span>{(CHART_TYPE_META[chartType] || CHART_TYPE_META.combo).label}</span>
            <Icon name="ChevronDown" size={11} />
          </button>
        }
      >
        <div className="dd-section">Chart type</div>
        {(availableChartTypes || ['combo', 'line', 'bar', 'area']).map((t) => {
          const meta = CHART_TYPE_META[t] || { label: t, icon: 'BarChart3' };
          return (
            <button key={t} className={`dd-item ${chartType === t ? 'active' : ''}`} onClick={() => onChartTypeChange(t)}>
              <Icon name={meta.icon} size={12} /> {meta.label}
            </button>
          );
        })}
      </Dropdown>
    </div>
  );
}
const customInputStyle = {
  border: '1px solid var(--soft-rule)', padding: '6px 8px',
  fontFamily: 'var(--sans)', fontSize: 12, borderRadius: 0,
  background: 'var(--white)', color: 'var(--rich-black)',
};
window.ChartControls = ChartControls;

// Two-column section title for a tab (serif uppercase + small descriptor).
function TabHeader({ title, desc, right }) {
  return (
    <div className="section-header">
      <h1>{title}</h1>
      <div style={{ display: 'flex', alignItems: 'flex-end', gap: 20 }}>
        {desc && <p className="desc">{desc}</p>}
        {right}
      </div>
    </div>
  );
}
window.TabHeader = TabHeader;

Object.assign(window, {
  Icon, Pill, Card, StatusChip, ScorePill, Delta, Sparkline, KpiCell,
  Toast, Dropdown, SectionHeader, Modal, SidePanel, RangeToggle, TabHeader,
});
