/* Primitive components: buttons, badges, cards, chips, status dots */

const Card = ({ children, style, className = "", padded = true, ...props }) => (
  <div
    className={`af-card ${className}`}
    style={{
      background: "var(--bg-1)",
      border: "1px solid var(--line)",
      borderRadius: "var(--r-3)",
      padding: padded ? "var(--card-pad, 18px)" : 0,
      ...style,
    }}
    {...props}
  >
    {children}
  </div>
);

const Btn = ({ children, variant = "default", size = "md", icon, style, ...props }) => {
  const sizes = {
    sm: { padding: "5px 10px", fontSize: 12, height: 28 },
    md: { padding: "7px 14px", fontSize: 13, height: 34 },
    lg: { padding: "10px 18px", fontSize: 14, height: 40 },
  };
  const variants = {
    default: { background: "var(--bg-2)", color: "var(--text)", border: "1px solid var(--line)" },
    primary: { background: "var(--accent)", color: "var(--accent-fg)", border: "1px solid var(--accent)" },
    ghost: { background: "transparent", color: "var(--text-2)", border: "1px solid transparent" },
    danger: { background: "transparent", color: "var(--bad)", border: "1px solid var(--bad-soft)" },
  };
  return (
    <button
      style={{
        display: "inline-flex",
        alignItems: "center",
        gap: 6,
        borderRadius: "var(--r-2)",
        fontWeight: 500,
        letterSpacing: "-0.005em",
        transition: "all 0.15s",
        ...sizes[size],
        ...variants[variant],
        ...style,
      }}
      onMouseEnter={(e) => {
        if (variant === "ghost") e.currentTarget.style.background = "var(--bg-2)";
        if (variant === "default") e.currentTarget.style.borderColor = "var(--text-3)";
      }}
      onMouseLeave={(e) => {
        if (variant === "ghost") e.currentTarget.style.background = "transparent";
        if (variant === "default") e.currentTarget.style.borderColor = "var(--line)";
      }}
      {...props}
    >
      {icon}
      {children}
    </button>
  );
};

const Badge = ({ children, tone = "default", style, ...props }) => {
  const tones = {
    default: { background: "var(--bg-2)", color: "var(--text-2)", border: "1px solid var(--line)" },
    good: { background: "var(--good-soft)", color: "var(--good)", border: "1px solid transparent" },
    warn: { background: "var(--warn-soft)", color: "var(--warn)", border: "1px solid transparent" },
    bad: { background: "var(--bad-soft)", color: "var(--bad)", border: "1px solid transparent" },
    info: { background: "var(--info-soft)", color: "var(--info)", border: "1px solid transparent" },
    accent: { background: "var(--accent-soft)", color: "var(--accent)", border: "1px solid transparent" },
    solid: { background: "var(--text)", color: "var(--bg)", border: "1px solid var(--text)" },
  };
  return (
    <span
      style={{
        display: "inline-flex",
        alignItems: "center",
        gap: 5,
        padding: "2px 8px",
        borderRadius: 999,
        fontSize: 11,
        fontWeight: 500,
        letterSpacing: 0,
        fontFamily: "var(--font-mono)",
        ...tones[tone],
        ...style,
      }}
      {...props}
    >
      {children}
    </span>
  );
};

const Dot = ({ tone = "good", pulse = false, size = 6 }) => (
  <span
    style={{
      display: "inline-block",
      width: size,
      height: size,
      borderRadius: "50%",
      background: `var(--${tone})`,
      animation: pulse ? "pulse-soft 2s ease-in-out infinite" : "none",
      flexShrink: 0,
    }}
  />
);

const Chip = ({ children, active = false, onClick, icon }) => (
  <button
    onClick={onClick}
    style={{
      display: "inline-flex",
      alignItems: "center",
      gap: 6,
      padding: "5px 10px",
      borderRadius: "var(--r-2)",
      fontSize: 12,
      fontWeight: 500,
      background: active ? "var(--text)" : "transparent",
      color: active ? "var(--bg)" : "var(--text-2)",
      border: `1px solid ${active ? "var(--text)" : "var(--line)"}`,
      transition: "all 0.15s",
    }}
  >
    {icon}
    {children}
  </button>
);

/* Source attribution: 📊 Garmin · ⚖ Eufy etc */
const Source = ({ sources = [] }) => (
  <div style={{ display: "inline-flex", alignItems: "center", gap: 6, fontFamily: "var(--font-mono)", fontSize: 10, color: "var(--text-3)" }}>
    <span style={{ letterSpacing: 0.08, textTransform: "uppercase", fontSize: 9.5 }}>fuente</span>
    {sources.map((s, i) => (
      <React.Fragment key={i}>
        {i > 0 && <span style={{ color: "var(--text-4)" }}>·</span>}
        <span style={{ color: "var(--text-2)" }}>{s}</span>
      </React.Fragment>
    ))}
  </div>
);

/* Trend arrow with delta */
const Trend = ({ delta, unit = "", goodDirection = "up", size = "md" }) => {
  const isUp = delta > 0;
  const isGood = (goodDirection === "up" && isUp) || (goodDirection === "down" && !isUp);
  const isFlat = Math.abs(delta) < 0.5;
  const tone = isFlat ? "var(--text-3)" : isGood ? "var(--good)" : "var(--bad)";
  const arrow = isFlat ? "→" : isUp ? "↗" : "↘";
  const fontSize = size === "lg" ? 14 : size === "sm" ? 10 : 12;
  return (
    <span style={{ color: tone, fontFamily: "var(--font-mono)", fontSize, fontWeight: 500, display: "inline-flex", gap: 3 }}>
      <span>{arrow}</span>
      <span>{isFlat ? "0" : (isUp ? "+" : "") + delta.toFixed(1)}{unit}</span>
    </span>
  );
};

/* Capability badge: ✅ available / ⚠ partial / ❌ unavailable */
const CapBadge = ({ status, label, hint }) => {
  const map = {
    ok: { dot: "good", text: "var(--text-2)", icon: "✓" },
    partial: { dot: "warn", text: "var(--warn)", icon: "≈" },
    none: { dot: "text-3", text: "var(--text-3)", icon: "—" },
  };
  const s = map[status] || map.none;
  return (
    <span title={hint} style={{
      display: "inline-flex", alignItems: "center", gap: 6,
      padding: "3px 8px", borderRadius: "var(--r-2)",
      fontSize: 11, fontFamily: "var(--font-mono)",
      background: "var(--bg-2)", border: "1px solid var(--line)",
      color: s.text,
    }}>
      <span style={{ color: `var(--${s.dot})` }}>{s.icon}</span>
      {label}
    </span>
  );
};

/* IconBox: simple geometric icon containers (we avoid emoji in product UI) */
const Icon = ({ name, size = 16, color = "currentColor", strokeWidth = 1.5 }) => {
  const paths = {
    home: <><path d="M3 11L12 4l9 7" /><path d="M5 10v9h14v-9" /></>,
    activity: <path d="M3 12h4l3-8 4 16 3-8h4" />,
    metrics: <><path d="M3 20V10" /><path d="M9 20V4" /><path d="M15 20v-7" /><path d="M21 20v-12" /></>,
    chat: <path d="M21 12a8 8 0 11-3.5-6.6L21 4l-1 4.5A8 8 0 0121 12z" />,
    plan: <><rect x="3" y="4" width="18" height="17" rx="2" /><path d="M3 9h18M8 2v4M16 2v4" /></>,
    settings: <><circle cx="12" cy="12" r="3" /><path d="M19.4 15a1.7 1.7 0 00.3 1.8l.1.1a2 2 0 01-2.8 2.8l-.1-.1a1.7 1.7 0 00-1.8-.3 1.7 1.7 0 00-1 1.5V21a2 2 0 01-4 0v-.1a1.7 1.7 0 00-1-1.5 1.7 1.7 0 00-1.8.3l-.1.1a2 2 0 01-2.8-2.8l.1-.1a1.7 1.7 0 00.3-1.8 1.7 1.7 0 00-1.5-1H3a2 2 0 010-4h.1a1.7 1.7 0 001.5-1 1.7 1.7 0 00-.3-1.8l-.1-.1a2 2 0 012.8-2.8l.1.1a1.7 1.7 0 001.8.3h0a1.7 1.7 0 001-1.5V3a2 2 0 014 0v.1a1.7 1.7 0 001 1.5 1.7 1.7 0 001.8-.3l.1-.1a2 2 0 012.8 2.8l-.1.1a1.7 1.7 0 00-.3 1.8v0a1.7 1.7 0 001.5 1H21a2 2 0 010 4h-.1a1.7 1.7 0 00-1.5 1z" /></>,
    heart: <path d="M20.8 5.6a5.5 5.5 0 00-7.8 0L12 6.6l-1-1a5.5 5.5 0 10-7.8 7.8l1 1L12 22l7.8-7.8 1-1a5.5 5.5 0 000-7.6z" />,
    moon: <path d="M21 12.8A9 9 0 1111.2 3a7 7 0 009.8 9.8z" />,
    flame: <path d="M8.5 14.5A2.5 2.5 0 0011 17c1.4 0 2.5-1.1 2.5-2.5 0-1.5-1-2.5-3-4.5C12 7 12.5 4 12.5 4S15 7 16 9s2 4.5 2 6a6 6 0 11-12 0c0-1.5.5-3 2-5 .5 2 1.5 3 1.5 4.5z" />,
    weight: <><rect x="4" y="6" width="16" height="14" rx="2" /><path d="M9 6V4a3 3 0 016 0v2" /><path d="M12 11v4" /></>,
    plus: <><path d="M12 5v14M5 12h14" /></>,
    check: <path d="M5 12l5 5L20 7" />,
    arrow: <><path d="M5 12h14" /><path d="M13 5l7 7-7 7" /></>,
    sync: <><path d="M21 12a9 9 0 11-3-6.7" /><path d="M21 4v5h-5" /></>,
    zap: <path d="M13 2L4 14h7l-1 8 9-12h-7l1-8z" />,
    lock: <><rect x="4" y="11" width="16" height="10" rx="2" /><path d="M8 11V7a4 4 0 118 0v4" /></>,
    cloud: <path d="M17 18a4 4 0 100-8 6 6 0 00-11.7 1.8A4 4 0 006 18h11z" />,
    info: <><circle cx="12" cy="12" r="9" /><path d="M12 16v-4M12 8h.01" /></>,
    alert: <><path d="M12 3l10 17H2L12 3z" /><path d="M12 10v4M12 17h.01" /></>,
    bluetooth: <path d="M7 7l10 10-5 5V2l5 5L7 17" />,
    chevR: <path d="M9 6l6 6-6 6" />,
    chevD: <path d="M6 9l6 6 6-6" />,
    close: <path d="M18 6L6 18M6 6l12 12" />,
    search: <><circle cx="11" cy="11" r="7" /><path d="M21 21l-4.3-4.3" /></>,
    map: <><path d="M9 4l-6 2v14l6-2 6 2 6-2V4l-6 2-6-2z" /><path d="M9 4v14M15 6v14" /></>,
    bolt: <path d="M13 2L4 14h7l-1 8 9-12h-7l1-8z" />,
    target: <><circle cx="12" cy="12" r="9" /><circle cx="12" cy="12" r="5" /><circle cx="12" cy="12" r="1" fill={color} /></>,
    droplet: <path d="M12 3l5 7a6 6 0 11-10 0l5-7z" />,
    user: <><circle cx="12" cy="8" r="4" /><path d="M4 21v-1a8 8 0 0116 0v1" /></>,
    bot: <><rect x="4" y="6" width="16" height="14" rx="3" /><path d="M12 6V2M9 12h.01M15 12h.01M9 17c.5.5 1.5 1 3 1s2.5-.5 3-1" /></>,
    medical: <path d="M12 3v18M3 12h18" />,
    coach: <><circle cx="12" cy="6" r="3" /><path d="M5 22v-4l3-4 4 2 4-2 3 4v4" /></>,
    apple: <><path d="M12 7c0-2 1.5-4 4-4 0 2-1.5 4-4 4z" /><path d="M16.5 11c-1.5-2-4.5-2-4.5 0 0-2-3-2-4.5 0-2 2.5 0 9 2 10 1 .5 1.5 0 2.5 0s1.5.5 2.5 0c2-1 4-7.5 2-10z" /></>,
    refresh: <><path d="M21 12a9 9 0 11-3-6.7" /><path d="M21 4v5h-5" /></>,
    merge: <><path d="M8 3v6c0 4 8 4 8 8v4" /><path d="M8 3v6c0 4-4 4-4 8" /><path d="M5 6l3-3 3 3" /></>,
    clock: <><circle cx="12" cy="12" r="9" /><path d="M12 7v5l3 2" /></>,
    spinner: <path d="M12 3a9 9 0 109 9" />,
    agents: <><circle cx="8" cy="9" r="3" /><circle cx="16" cy="9" r="3" /><path d="M3 20c0-3 2-5 5-5s5 2 5 5M11 20c0-3 2-5 5-5s5 2 5 5" /></>,
    book: <><path d="M4 4h12a4 4 0 014 4v12a4 4 0 00-4-4H4z" /><path d="M4 4v16" /></>,
    x: <path d="M18 6L6 18M6 6l12 12" />,
  };
  const spinning = name === "spinner";
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round"
      style={spinning ? { animation: "af-spin 0.9s linear infinite" } : null}>
      {paths[name]}
    </svg>
  );
};

if (typeof document !== "undefined" && !document.getElementById("af-spin-style")) {
  const s = document.createElement("style");
  s.id = "af-spin-style";
  s.textContent = "@keyframes af-spin { to { transform: rotate(360deg); } }";
  document.head.appendChild(s);
}

/* Empty state */
const Empty = ({ icon = "info", title, body, action }) => (
  <div style={{
    padding: "60px 40px", textAlign: "center",
    border: "1px dashed var(--line)", borderRadius: "var(--r-3)",
    background: "var(--bg-1)", maxWidth: 480, margin: "0 auto",
    display: "flex", flexDirection: "column", alignItems: "center", gap: 14,
  }}>
    <div style={{
      width: 44, height: 44, borderRadius: 10,
      background: "var(--bg-2)", color: "var(--text-3)",
      display: "grid", placeItems: "center",
    }}><Icon name={icon} size={20} /></div>
    <div style={{ fontSize: 15, fontWeight: 500, color: "var(--text)" }}>{title}</div>
    {body && <div style={{ fontSize: 12.5, color: "var(--text-3)", lineHeight: 1.5, maxWidth: 380 }}>{body}</div>}
    {action && <div style={{ marginTop: 4 }}>{action}</div>}
  </div>
);

/* Segmented tabs */
const SegTabs = ({ value, onChange, options }) => (
  <div style={{
    display: "inline-flex", gap: 2, padding: 3,
    background: "var(--bg-2)", border: "1px solid var(--line)",
    borderRadius: "var(--r-2)",
  }}>
    {options.map((o) => (
      <button key={o.value} onClick={() => onChange(o.value)} style={{
        padding: "5px 12px", fontSize: 12, fontWeight: 500,
        border: "none", borderRadius: 5,
        background: value === o.value ? "var(--bg-3)" : "transparent",
        color: value === o.value ? "var(--text)" : "var(--text-3)",
      }}>{o.label}</button>
    ))}
  </div>
);

/* Tab bar */
const Tabs = ({ tabs, value, onChange }) => (
  <div style={{
    display: "inline-flex",
    background: "var(--bg-2)",
    border: "1px solid var(--line)",
    borderRadius: "var(--r-2)",
    padding: 3,
    gap: 2,
  }}>
    {tabs.map((t) => (
      <button
        key={t.value}
        onClick={() => onChange(t.value)}
        style={{
          padding: "5px 12px",
          fontSize: 12,
          fontWeight: 500,
          border: "none",
          background: value === t.value ? "var(--bg-3)" : "transparent",
          color: value === t.value ? "var(--text)" : "var(--text-3)",
          borderRadius: 5,
          transition: "all 0.15s",
        }}
      >
        {t.label}
      </button>
    ))}
  </div>
);

/* Pill nav (range selector) */
const RangePicker = ({ value, onChange, options = ["7d", "30d", "90d", "1a"] }) => (
  <div style={{ display: "inline-flex", gap: 0, fontFamily: "var(--font-mono)", fontSize: 11 }}>
    {options.map((o) => (
      <button
        key={o}
        onClick={() => onChange(o)}
        style={{
          padding: "4px 10px",
          background: value === o ? "var(--bg-3)" : "transparent",
          color: value === o ? "var(--text)" : "var(--text-3)",
          border: "1px solid var(--line)",
          borderLeftWidth: o === options[0] ? 1 : 0,
          fontWeight: 500,
        }}
      >
        {o}
      </button>
    ))}
  </div>
);

/* Insight card — small "good/bad/improve" tile */
const InsightTile = ({ kind = "good", title, body }) => {
  const map = {
    good: { color: "var(--good)", label: "BIEN", bg: "var(--good-soft)", icon: "✓" },
    bad: { color: "var(--bad)", label: "ATENCIÓN", bg: "var(--bad-soft)", icon: "!" },
    improve: { color: "var(--accent)", label: "MEJORA", bg: "var(--accent-soft)", icon: "↗" },
    info: { color: "var(--info)", label: "DATO", bg: "var(--info-soft)", icon: "i" },
  }[kind];
  return (
    <div style={{
      padding: "12px 14px",
      borderRadius: "var(--r-2)",
      border: "1px solid var(--line)",
      background: "var(--bg-1)",
      display: "flex", gap: 12,
    }}>
      <div style={{
        width: 22, height: 22, borderRadius: 4,
        background: map.bg, color: map.color,
        display: "grid", placeItems: "center",
        fontFamily: "var(--font-mono)", fontSize: 12, fontWeight: 600,
        flexShrink: 0,
      }}>{map.icon}</div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 9.5, letterSpacing: 0.12, color: map.color, fontFamily: "var(--font-mono)", fontWeight: 600, marginBottom: 2 }}>
          {map.label}
        </div>
        <div style={{ fontSize: 13, lineHeight: 1.4, color: "var(--text)" }}>
          <strong style={{ fontWeight: 500 }}>{title}</strong>
          {body && <span style={{ color: "var(--text-2)" }}> — {body}</span>}
        </div>
      </div>
    </div>
  );
};

Object.assign(window, {
  Card, Btn, Badge, Dot, Chip, Source, Trend, CapBadge, Icon, Tabs, RangePicker, InsightTile,
  Empty, SegTabs,
});
