// components.jsx — shared UI primitives + Sidebar + Topbar
const { useState, useEffect, useRef } = React;

/* ---------- Avatar ---------- */
function Avatar({ person, size = 28, ring = false }) {
  if (!person) {
    return (
      <div className="flex items-center justify-center rounded-full bg-zinc-100 text-zinc-400 border border-dashed border-zinc-300"
        style={{ width: size, height: size }} title="Unassigned">
        <Icon name="user" size={size * 0.5} />
      </div>
    );
  }
  return (
    <div className="flex items-center justify-center rounded-full text-white font-semibold shrink-0"
      style={{ width: size, height: size, background: person.color, fontSize: size * 0.4,
               boxShadow: ring ? "0 0 0 2px #fff, 0 0 0 3.5px " + person.color : "none" }}
      title={person.name}>
      {person.initials}
    </div>
  );
}

/* ---------- Priority badge ---------- */
function PriorityBadge({ level }) {
  const p = PRIORITY[level];
  return (
    <span className="inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-[11px] font-semibold border"
      style={{ background: p.bg, color: p.text, borderColor: p.border }}>
      <span className="w-1.5 h-1.5 rounded-full" style={{ background: p.dot }} />
      {p.label}
    </span>
  );
}

/* ---------- Status chip ---------- */
function StatusChip({ status }) {
  const s = STATUS[status];
  return (
    <span className="inline-flex items-center gap-1.5 rounded-md px-2 py-0.5 text-[11px] font-medium"
      style={{ background: s.bg, color: s.text }}>
      <span className="w-1.5 h-1.5 rounded-full" style={{ background: s.dot }} />
      {s.label}
    </span>
  );
}

/* ---------- Generic pill / tag ---------- */
function Tag({ children, className = "" }) {
  return <span className={"inline-flex items-center rounded-md bg-zinc-100 px-2 py-0.5 text-[11px] font-medium text-zinc-600 " + className}>{children}</span>;
}

/* ---------- Button ---------- */
function Button({ children, variant = "default", size = "md", icon, iconRight, onClick, className = "", disabled, full }) {
  const base = "inline-flex items-center justify-center gap-2 font-medium rounded-lg transition-all duration-150 select-none disabled:opacity-50 disabled:pointer-events-none";
  const sizes = { sm: "text-[12.5px] px-2.5 py-1.5", md: "text-[13px] px-3.5 py-2", lg: "text-sm px-4 py-2.5" };
  const variants = {
    primary: "text-white shadow-sm hover:brightness-110 active:brightness-95",
    default: "bg-white text-zinc-700 border border-zinc-200 hover:bg-zinc-50 hover:border-zinc-300 shadow-[0_1px_2px_rgba(0,0,0,0.04)]",
    ghost:   "text-zinc-600 hover:bg-zinc-100",
    danger:  "bg-white text-red-600 border border-red-200 hover:bg-red-50",
    subtle:  "text-zinc-700 hover:bg-zinc-100 border border-transparent",
  };
  const style = variant === "primary" ? { background: "var(--accent)" } : undefined;
  return (
    <button onClick={onClick} disabled={disabled} style={style}
      className={`${base} ${sizes[size]} ${variants[variant]} ${full ? "w-full" : ""} ${className}`}>
      {icon && <Icon name={icon} size={size === "sm" ? 14 : 15} />}
      {children}
      {iconRight && <Icon name={iconRight} size={size === "sm" ? 14 : 15} />}
    </button>
  );
}

/* ---------- Sparkline ---------- */
function Sparkline({ data, color = "var(--accent)", w = 96, h = 30 }) {
  const min = Math.min(...data), max = Math.max(...data);
  const rng = max - min || 1;
  const pts = data.map((v, i) => [ (i / (data.length - 1)) * w, h - ((v - min) / rng) * (h - 4) - 2 ]);
  const d = pts.map((p, i) => (i === 0 ? "M" : "L") + p[0].toFixed(1) + " " + p[1].toFixed(1)).join(" ");
  const area = d + ` L ${w} ${h} L 0 ${h} Z`;
  const gid = "sg" + Math.random().toString(36).slice(2, 8);
  return (
    <svg width={w} height={h} className="overflow-visible">
      <defs><linearGradient id={gid} x1="0" y1="0" x2="0" y2="1">
        <stop offset="0%" stopColor={color} stopOpacity="0.18" />
        <stop offset="100%" stopColor={color} stopOpacity="0" />
      </linearGradient></defs>
      <path d={area} fill={`url(#${gid})`} />
      <path d={d} fill="none" stroke={color} strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round" />
      <circle cx={pts[pts.length-1][0]} cy={pts[pts.length-1][1]} r="2.5" fill={color} />
    </svg>
  );
}

/* ---------- Skeleton ---------- */
function Skeleton({ className = "", style }) {
  return <div className={"animate-pulse rounded-md bg-zinc-200/70 " + className} style={style} />;
}

/* ---------- Sidebar ---------- */
function Sidebar({ items, active, onNav, collapsed, onToggle, user, roleKey, onLogout }) {
  const role = roleKey ? ROLES[roleKey] : null;
  return (
    <aside className="flex flex-col h-full text-zinc-300 shrink-0 transition-all duration-200"
      style={{ width: collapsed ? 68 : 232, background: "var(--side-bg)" }}>
      {/* brand */}
      <div className="flex items-center gap-2.5 px-4 h-16 shrink-0 border-b border-white/[0.07]">
        <div className="flex items-center justify-center w-8 h-8 rounded-lg shrink-0 font-bold text-white text-[15px]"
          style={{ background: "var(--accent)" }}>T</div>
        {!collapsed && (
          <div className="leading-tight overflow-hidden">
            <div className="text-white font-semibold text-[14px] tracking-tight whitespace-nowrap">TRAPO <span className="text-zinc-500 font-normal">OpsPilot</span></div>
            <div className="text-[10.5px] text-zinc-500 whitespace-nowrap">Exception Management</div>
          </div>
        )}
      </div>

      {/* nav */}
      <nav className="flex-1 overflow-y-auto py-3 px-2.5 space-y-0.5">
        {!collapsed && <div className="px-2.5 pt-1 pb-1.5 text-[10px] font-semibold uppercase tracking-wider text-zinc-600">Operations</div>}
        {items.map(item => {
          const isActive = active === item.key;
          return (
            <button key={item.key} onClick={() => onNav(item.key)} title={collapsed ? item.label : undefined}
              className={`group relative flex items-center gap-3 w-full rounded-lg px-2.5 py-2 text-[13px] font-medium transition-colors
                ${isActive ? "text-white" : "text-zinc-400 hover:text-zinc-100 hover:bg-white/[0.04]"}`}
              style={isActive ? { background: "rgba(255,255,255,0.07)" } : undefined}>
              {isActive && <span className="absolute left-0 top-1.5 bottom-1.5 w-0.5 rounded-full" style={{ background: "var(--accent)" }} />}
              <Icon name={item.icon} size={18} className={isActive ? "" : "opacity-80"} style={isActive ? { color: "var(--accent-bright)" } : undefined} />
              {!collapsed && <span className="flex-1 text-left whitespace-nowrap">{item.label}</span>}
              {!collapsed && item.badge && (
                <span className="text-[10.5px] font-semibold px-1.5 py-0.5 rounded-md"
                  style={{ background: isActive ? "var(--accent)" : "rgba(255,255,255,0.08)", color: isActive ? "#fff" : "#a1a1aa" }}>
                  {item.badge}
                </span>
              )}
              {collapsed && item.badge && <span className="absolute top-1 right-1 w-1.5 h-1.5 rounded-full" style={{ background: "var(--accent)" }} />}
            </button>
          );
        })}
      </nav>

      {/* AI status card */}
      {!collapsed && (
        <div className="mx-2.5 mb-2 rounded-xl p-3 border border-white/[0.07]" style={{ background: "rgba(255,255,255,0.03)" }}>
          <div className="flex items-center gap-2 mb-1.5">
            <span className="relative flex w-2 h-2">
              <span className="absolute inline-flex h-full w-full rounded-full opacity-60 animate-ping" style={{ background: "var(--accent-bright)" }} />
              <span className="relative inline-flex rounded-full w-2 h-2" style={{ background: "var(--accent-bright)" }} />
            </span>
            <span className="text-[11.5px] font-semibold text-zinc-200">OpsPilot AI</span>
            <span className="ml-auto text-[10px] text-zinc-500">live</span>
          </div>
          <p className="text-[11px] text-zinc-500 leading-snug">Monitoring 1,284 active orders. 47 exceptions surfaced today.</p>
        </div>
      )}

      {/* user identity + logout */}
      {user && (
        <div className={`mx-2.5 mb-1.5 rounded-xl border border-white/[0.07] ${collapsed ? "p-1.5 flex justify-center" : "p-2.5"}`} style={{ background: "rgba(255,255,255,0.03)" }}>
          {collapsed ? (
            <Avatar person={user} size={30} />
          ) : (
            <div className="flex items-center gap-2.5">
              <Avatar person={user} size={32} />
              <div className="min-w-0 leading-tight flex-1">
                <div className="text-[12px] font-semibold text-zinc-100 truncate">{user.name}</div>
                {role && <div className="flex items-center gap-1 mt-0.5"><span className="w-1.5 h-1.5 rounded-full" style={{ background: role.color }} /><span className="text-[10.5px] text-zinc-400 truncate">{role.label}</span></div>}
              </div>
              <button onClick={onLogout} title="Sign out" className="w-7 h-7 rounded-md flex items-center justify-center text-zinc-500 hover:text-zinc-200 hover:bg-white/[0.06] transition-colors shrink-0"><Icon name="logout" size={16} /></button>
            </div>
          )}
        </div>
      )}

      {/* collapse toggle */}
      <button onClick={onToggle}
        className="flex items-center gap-3 px-4 h-11 shrink-0 border-t border-white/[0.07] text-zinc-500 hover:text-zinc-200 text-[12.5px] transition-colors">
        <Icon name={collapsed ? "chevright" : "chevleft"} size={18} />
        {!collapsed && <span>Collapse</span>}
      </button>
    </aside>
  );
}

/* ---------- Topbar ---------- */
function Topbar({ title, subtitle, user, roleKey, onSearch }) {
  const [now, setNow] = useState(new Date());
  useEffect(() => { const t = setInterval(() => setNow(new Date()), 30000); return () => clearInterval(t); }, []);
  const time = now.toLocaleTimeString("en-GB", { hour: "2-digit", minute: "2-digit" });
  const role = roleKey ? ROLES[roleKey] : null;
  const u = user || CURRENT_USER;
  useEffect(() => {
    function onKey(e) { if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") { e.preventDefault(); onSearch && onSearch(); } }
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [onSearch]);
  return (
    <header className="flex items-center gap-4 h-16 px-6 bg-white border-b border-zinc-200 shrink-0">
      <div className="min-w-0">
        <h1 className="text-[16px] font-semibold text-zinc-900 tracking-tight leading-tight truncate">{title}</h1>
        {subtitle && <p className="text-[12px] text-zinc-500 leading-tight truncate">{subtitle}</p>}
      </div>

      <div className="ml-auto flex items-center gap-2.5">
        {role && (
          <span className="hidden md:inline-flex items-center gap-1.5 rounded-lg px-2.5 py-1.5 text-[12px] font-medium" style={{ background: role.color + "12", color: role.color }}>
            <Icon name="shieldcheck" size={14} /> {role.label}
          </span>
        )}
        <button onClick={() => onSearch && onSearch()} className="hidden md:flex items-center gap-2 w-60 h-9 px-3 rounded-lg bg-zinc-100/80 border border-transparent hover:bg-white hover:border-zinc-300 transition-colors text-left group">
          <Icon name="sparkles" size={15} style={{ color: "var(--accent)" }} />
          <span className="text-[13px] text-zinc-400 flex-1">Ask AI or search…</span>
          <kbd className="text-[10px] text-zinc-400 border border-zinc-300 rounded px-1 py-0.5 font-sans">⌘K</kbd>
        </button>
        <button className="relative flex items-center justify-center w-9 h-9 rounded-lg text-zinc-500 hover:bg-zinc-100 hover:text-zinc-700 transition-colors">
          <Icon name="bell" size={18} />
          <span className="absolute top-2 right-2 w-1.5 h-1.5 rounded-full bg-red-500 ring-2 ring-white" />
        </button>
        <div className="hidden lg:flex flex-col items-end leading-tight pl-1">
          <span className="text-[11px] text-zinc-400">{time} · Shah Alam</span>
        </div>
        <div className="flex items-center gap-2 pl-1.5 pr-1 py-1 rounded-lg hover:bg-zinc-100 transition-colors cursor-pointer">
          <Avatar person={u} size={30} />
          <div className="hidden lg:block leading-tight pr-1">
            <div className="text-[12.5px] font-semibold text-zinc-800">{u.name}</div>
            <div className="text-[10.5px] text-zinc-500">{u.role}</div>
          </div>
          <Icon name="chevdown" size={14} className="text-zinc-400 hidden lg:block" />
        </div>
      </div>
    </header>
  );
}

Object.assign(window, { Avatar, PriorityBadge, StatusChip, Tag, Button, Sparkline, Skeleton, Sidebar, Topbar });
