// Shared UI primitives: Sidebar, Topbar, Modal, Avatar, Button, Card, etc.

const { motion, AnimatePresence } = window.Motion || window.framerMotion || window;

// Avatar — colored monogram
function Avatar({ name, color = "#A6F84A", size = 32, status, ring }) {
  const initials = name && name.split ? name.split(" ").map(p => p[0]).slice(0,2).join("") : (name || "?");
  return (
    <div className="relative inline-block" style={{ width: size, height: size }}>
      <div
        className={`flex items-center justify-center rounded-full font-medium ${ring ? "ring-2 ring-offset-2 ring-offset-ink-900" : ""}`}
        style={{
          width: size, height: size,
          background: `linear-gradient(135deg, ${color}, ${color}99)`,
          color: "#0a0b0f",
          fontSize: size * 0.38,
        }}
      >{initials}</div>
      {status && (
        <span
          className={`absolute right-0 bottom-0 rounded-full ring-2 ring-ink-900 ${status === "online" ? "bg-lime dot-online" : status === "away" ? "bg-yellow-300" : "bg-zinc-500"}`}
          style={{ width: Math.max(8, size*0.28), height: Math.max(8, size*0.28) }}
        />
      )}
    </div>
  );
}

// Mini brand mark — Loop
function LoopMark({ size = 28 }) {
  return (
    <div className="flex items-center gap-2">
      <div
        className="grid place-items-center rounded-xl"
        style={{
          width: size, height: size,
          background: "linear-gradient(180deg, #C7FB7C 0%, #A6F84A 60%, #74D31C 100%)",
          boxShadow: "0 6px 18px -6px rgba(166,248,74,0.6), inset 0 1px 0 rgba(255,255,255,0.5)",
        }}
      >
        <svg width={size * 0.55} height={size * 0.55} viewBox="0 0 24 24" fill="none" stroke="#0a0b0f" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
          <path d="M5 9v6a4 4 0 0 0 8 0v-2" />
          <path d="M19 15V9a4 4 0 0 0-8 0v2" />
        </svg>
      </div>
    </div>
  );
}

// Glass card
function Card({ className = "", children, padded = true, as: As = "div", ...rest }) {
  return (
    <As className={`glass rounded-2xl ${padded ? "p-5" : ""} ${className}`} {...rest}>{children}</As>
  );
}

// Pill / Badge
function Pill({ children, tone = "default", className = "" }) {
  const tones = {
    default: "bg-white/[0.04] text-white/70 border-white/[0.06]",
    lime: "bg-lime/10 text-lime border-lime/30",
    blue: "bg-sky-400/10 text-sky-300 border-sky-400/30",
    pink: "bg-fuchsia-400/10 text-fuchsia-300 border-fuchsia-400/30",
    yellow: "bg-yellow-300/10 text-yellow-200 border-yellow-300/30",
    purple: "bg-violet-400/10 text-violet-300 border-violet-400/30",
    red: "bg-rose-400/10 text-rose-300 border-rose-400/30",
  };
  return (
    <span className={`inline-flex items-center gap-1.5 rounded-full border px-2.5 py-0.5 text-[11px] font-medium tracking-tight ${tones[tone]} ${className}`}>{children}</span>
  );
}

// Buttons
function Btn({ children, variant = "ghost", size = "md", className = "", ...rest }) {
  const sizes = {
    sm: "h-8 px-3 text-[12.5px]",
    md: "h-9 px-3.5 text-[13px]",
    lg: "h-11 px-5 text-sm",
  };
  const variants = {
    primary: "btn-lime font-medium",
    ghost: "bg-white/[0.04] hover:bg-white/[0.07] text-white/85 border border-white/[0.06]",
    quiet: "hover:bg-white/[0.05] text-white/70",
    outline: "bg-transparent hover:bg-white/[0.04] text-white/85 border border-white/[0.1]",
    danger: "bg-rose-500/15 hover:bg-rose-500/25 text-rose-300 border border-rose-500/30",
    dark: "bg-ink-800 hover:bg-ink-700 text-white/85 border border-white/[0.06]",
  };
  return (
    <button
      className={`inline-flex items-center justify-center gap-1.5 rounded-xl transition-all duration-150 ${sizes[size]} ${variants[variant]} ${className}`}
      {...rest}
    >{children}</button>
  );
}

// Concern icon
function ConcernIcon({ id, size = 16 }) {
  const c = window.Mock.concerns.find(x => x.id === id);
  if (!c) return null;
  const C = window.Icon[c.icon];
  return (
    <span className="inline-grid place-items-center rounded-md" style={{ width: size + 10, height: size + 10, background: `${c.tint}22`, color: c.tint }}>
      <C size={size} />
    </span>
  );
}

// Modal
function Modal({ open, onClose, children, title, subtitle, width = 560 }) {
  return (
    <AnimatePresence>
      {open && (
        <motion.div
          className="fixed inset-0 z-[80] grid place-items-center p-4"
          initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }}
        >
          <div className="absolute inset-0 bg-black/60 backdrop-blur-sm" onClick={onClose} />
          <motion.div
            initial={{ y: 16, opacity: 0, scale: 0.98 }}
            animate={{ y: 0, opacity: 1, scale: 1 }}
            exit={{ y: 8, opacity: 0, scale: 0.98 }}
            transition={{ type: "spring", stiffness: 260, damping: 26 }}
            className="relative glass-strong rounded-2xl overflow-hidden"
            style={{ width: "min(96vw," + width + "px)" }}
          >
            <div className="flex items-start justify-between p-5 border-b border-white/[0.06]">
              <div>
                <h3 className="text-white/90 text-[15px] font-medium">{title}</h3>
                {subtitle && <p className="text-white/50 text-xs mt-0.5">{subtitle}</p>}
              </div>
              <button onClick={onClose} className="rounded-lg p-1.5 hover:bg-white/[0.06] text-white/60">
                <Icon.Close size={16} />
              </button>
            </div>
            <div className="p-5">{children}</div>
          </motion.div>
        </motion.div>
      )}
    </AnimatePresence>
  );
}

// Field
function Field({ label, hint, children, className = "" }) {
  return (
    <label className={`block ${className}`}>
      {label && <div className="text-[11.5px] uppercase tracking-[0.08em] text-white/45 mb-1.5">{label}</div>}
      {children}
      {hint && <div className="text-[11.5px] text-white/40 mt-1">{hint}</div>}
    </label>
  );
}

function Input({ className = "", ...rest }) {
  return <input className={`w-full h-10 px-3 rounded-xl bg-white/[0.03] border border-white/[0.07] focus:border-lime/60 focus:bg-white/[0.05] outline-none text-[13.5px] text-white/90 placeholder:text-white/30 transition ${className}`} {...rest} />;
}
function Textarea({ className = "", rows = 3, ...rest }) {
  return <textarea rows={rows} className={`w-full px-3 py-2.5 rounded-xl bg-white/[0.03] border border-white/[0.07] focus:border-lime/60 focus:bg-white/[0.05] outline-none text-[13.5px] text-white/90 placeholder:text-white/30 transition resize-none ${className}`} {...rest} />;
}

// Dropdown (simple)
function Dropdown({ value, options, onChange, placeholder = "Select", className = "" }) {
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    const fn = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", fn);
    return () => document.removeEventListener("mousedown", fn);
  }, []);
  const cur = options.find(o => o.value === value);
  return (
    <div className={`relative ${className}`} ref={ref}>
      <button
        type="button"
        onClick={() => setOpen(o => !o)}
        className="w-full h-10 px-3 rounded-xl bg-white/[0.03] border border-white/[0.07] hover:border-white/[0.12] flex items-center justify-between text-[13.5px] text-white/85"
      >
        <span className="flex items-center gap-2 truncate">
          {cur?.icon && <span className="text-lime">{cur.icon}</span>}
          <span className={cur ? "" : "text-white/40"}>{cur?.label || placeholder}</span>
        </span>
        <Icon.ChevronDown size={14} className={`text-white/50 transition-transform ${open ? "rotate-180" : ""}`} />
      </button>
      <AnimatePresence>
        {open && (
          <motion.div
            initial={{ opacity: 0, y: -4 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, y: -4 }}
            transition={{ duration: 0.12 }}
            className="absolute z-50 mt-1 w-full glass-strong rounded-xl overflow-hidden p-1"
          >
            {options.map(o => (
              <button
                key={o.value}
                onClick={() => { onChange(o.value); setOpen(false); }}
                className={`w-full text-left flex items-center gap-2 px-2.5 py-2 rounded-lg text-[13px] hover:bg-white/[0.05] ${o.value === value ? "text-lime" : "text-white/85"}`}
              >
                {o.icon}
                <span>{o.label}</span>
                {o.value === value && <Icon.Check size={14} className="ml-auto" />}
              </button>
            ))}
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
}

// Tabs (segmented)
function Tabs({ tabs, value, onChange }) {
  return (
    <div className="inline-flex p-1 rounded-xl bg-white/[0.04] border border-white/[0.06] relative">
      {tabs.map(t => {
        const active = t.value === value;
        return (
          <button
            key={t.value}
            onClick={() => onChange(t.value)}
            className={`relative px-3 h-8 rounded-lg text-[12.5px] font-medium transition ${active ? "text-ink-950" : "text-white/70 hover:text-white/90"}`}
          >
            {active && (
              <motion.span
                layoutId="tab-pill"
                className="absolute inset-0 rounded-lg bg-lime"
                transition={{ type: "spring", stiffness: 340, damping: 28 }}
              />
            )}
            <span className="relative z-10 flex items-center gap-1.5">
              {t.label}
              {t.count != null && (
                <span className={`text-[10.5px] px-1.5 rounded-full ${active ? "bg-ink-950/15 text-ink-950" : "bg-white/[0.08] text-white/60"}`}>{t.count}</span>
              )}
            </span>
          </button>
        );
      })}
    </div>
  );
}

// Sidebar
function Sidebar({ active, onChange, onOpenLanding, role, agent, onLogout, open, onClose }) {
  const { navItems } = window.Mock;
  // Live badge = real waiting conversations for this (already scoped) user.
  // No data → no badge, so we never show a stale hardcoded count.
  const waiting = (window.Mock.conversations || []).filter((c) => c.status === "waiting").length;
  const badgeFor = (id) => (id === "conversations" && waiting > 0 ? waiting : null);
  const items = navItems.filter((n) => n.id !== "admin" || role === "Admin" || role === "Manager");
  const close = () => onClose && onClose();
  const pick = (id) => { onChange(id); close(); };
  return (
    <aside className={`w-[260px] shrink-0 h-full flex flex-col p-4 border-r border-white/[0.05] backdrop-blur-xl bg-ink-950/95 md:bg-ink-950/40 fixed inset-y-0 left-0 z-[60] transition-transform duration-200 md:static md:z-auto md:translate-x-0 ${open ? "translate-x-0" : "-translate-x-full"}`}>
      <div className="flex items-center justify-between mb-6">
        <button onClick={() => { onOpenLanding(); close(); }} className="flex items-center gap-2.5 px-1.5 py-1 group">
          <LoopMark size={32} />
          <div className="text-left">
            <div className="text-white/95 text-[15px] font-semibold tracking-tight leading-none">Loop</div>
            <div className="text-white/40 text-[10.5px] tracking-wider mt-0.5 uppercase">Live chat OS</div>
          </div>
        </button>
        <button onClick={close} className="md:hidden h-9 w-9 grid place-items-center rounded-lg text-white/55 hover:bg-white/[0.06] hover:text-white"><Icon.Close size={18}/></button>
      </div>

      <div className="flex items-center gap-2 mb-5 p-2.5 rounded-xl glass">
        <Avatar name={agent ? agent.name : "Loop"} color={(agent && agent.color) || "#FF9DD2"} size={28} status="online" />
        <div className="flex-1 text-left min-w-0">
          <div className="text-[12.5px] text-white/90 font-medium leading-tight truncate">{agent ? agent.name : "Loop"}</div>
          <div className="text-[10.5px] text-white/45">{agent ? agent.role : "Workspace"}</div>
        </div>
        <button onClick={() => { onLogout(); close(); }} title="Sign out" className="rounded-lg p-1.5 hover:bg-white/[0.06] text-white/45 hover:text-white"><Icon.Power size={15}/></button>
      </div>

      <nav className="flex flex-col gap-0.5">
        {items.map(n => {
          const I = Icon[n.icon];
          const isActive = active === n.id;
          return (
            <button
              key={n.id}
              onClick={() => pick(n.id)}
              className={`relative flex items-center gap-3 px-3 h-10 rounded-xl text-[13px] transition group ${isActive ? "text-white bg-white/[0.06]" : "text-white/65 hover:text-white/90 hover:bg-white/[0.03]"}`}
            >
              {isActive && <span className="absolute left-0 top-2 bottom-2 w-[3px] rounded-r-full bg-lime" />}
              <I size={16} className={isActive ? "text-lime" : ""} />
              <span className="font-medium">{n.label}</span>
              {badgeFor(n.id) && (
                <span className="ml-auto text-[10.5px] font-medium px-1.5 py-0.5 rounded-full bg-lime/15 text-lime border border-lime/30">{badgeFor(n.id)}</span>
              )}
            </button>
          );
        })}
      </nav>

      <div className="mt-auto pt-4 border-t border-white/[0.05]">
        <div className="glass rounded-xl p-3.5">
          <div className="flex items-center gap-2 mb-1.5">
            <Icon.Sparkle size={14} className="text-lime" />
            <span className="text-[12px] font-medium text-white/85">Loop AI Copilot</span>
            <Pill tone="lime" className="ml-auto">Beta</Pill>
          </div>
          <p className="text-[11.5px] text-white/55 leading-snug">Auto-suggest replies and tag concerns from visitor language.</p>
          <Btn size="sm" variant="outline" className="mt-2.5 w-full">Enable for workspace</Btn>
        </div>
      </div>
    </aside>
  );
}

// Topbar
function Topbar({ title, subtitle, right }) {
  return (
    <header className="flex items-center justify-between px-4 md:px-7 pl-14 md:pl-7 py-4 border-b border-white/[0.05]">
      <div>
        <h1 className="text-[20px] tracking-tight text-white/95 font-semibold">{title}</h1>
        {subtitle && <p className="text-[12.5px] text-white/50 mt-0.5">{subtitle}</p>}
      </div>
      <div className="flex items-center gap-2">
        <div className="hidden md:flex items-center gap-2 h-9 px-3 rounded-xl bg-white/[0.03] border border-white/[0.06] text-[12.5px] text-white/55 w-[280px]">
          <Icon.Search size={14} />
          <span>Search visitors, sites, agents…</span>
          <span className="ml-auto text-[10.5px] font-mono px-1.5 py-0.5 rounded-md bg-white/[0.05] text-white/40">⌘K</span>
        </div>
        <button className="relative h-9 w-9 grid place-items-center rounded-xl bg-white/[0.03] border border-white/[0.06] hover:bg-white/[0.06]">
          <Icon.Bell size={16} className="text-white/70" />
          <span className="absolute top-1.5 right-1.5 w-1.5 h-1.5 rounded-full bg-lime" />
        </button>
        {right}
      </div>
    </header>
  );
}

// Empty state
function Empty({ icon = "ChatDots", title, body, action }) {
  const I = Icon[icon];
  return (
    <div className="flex flex-col items-center justify-center text-center py-16 px-6">
      <div className="grid place-items-center w-14 h-14 rounded-2xl bg-white/[0.04] border border-white/[0.06] mb-4">
        <I size={22} className="text-white/40" />
      </div>
      <div className="text-[14.5px] text-white/85 font-medium">{title}</div>
      {body && <p className="text-[12.5px] text-white/45 mt-1 max-w-xs">{body}</p>}
      {action && <div className="mt-4">{action}</div>}
    </div>
  );
}

// Skeleton shimmer
function Skeleton({ className = "" }) {
  return <div className={`bg-white/[0.04] rounded-md animate-pulse ${className}`} />;
}

// Channel badge — which channel a conversation lives on (web / email / messenger)
function ChannelBadge({ channel = "web", size = "sm", withLabel = false }) {
  const map = {
    web:       { icon: "Chat",      label: "Web chat",  cls: "bg-lime/10 text-lime border-lime/30" },
    email:     { icon: "Mail",      label: "Email",     cls: "bg-sky-400/10 text-sky-300 border-sky-400/30" },
    messenger: { icon: "Messenger", label: "Messenger", cls: "bg-violet-400/10 text-violet-300 border-violet-400/30" },
  };
  const c = map[channel] || map.web;
  const I = Icon[c.icon] || Icon.Chat;
  const px = size === "xs" ? 9 : size === "md" ? 13 : 11;
  return (
    <span role="img" aria-label={c.label} className={`inline-flex items-center gap-1 rounded-full border ${c.cls} ${withLabel ? "px-2 py-0.5" : "p-1"}`}>
      <I size={px} />
      {withLabel && <span className="text-[10.5px] font-medium leading-none">{c.label}</span>}
    </span>
  );
}

window.UI = { Avatar, LoopMark, Card, Pill, Btn, ConcernIcon, ChannelBadge, Modal, Field, Input, Textarea, Dropdown, Tabs, Sidebar, Topbar, Empty, Skeleton };
