// Shared UI primitives for soko demo + app

const { motion, AnimatePresence } = window;

// --- Window size hook ---
function useWindowSize() {
  const [sz, setSz] = React.useState({ w: window.innerWidth, h: window.innerHeight });
  React.useEffect(() => {
    const fn = () => {
      const w = window.innerWidth, h = window.innerHeight;
      setSz(prev => (prev.w === w && prev.h === h) ? prev : { w, h });
    };
    window.addEventListener("resize", fn);
    return () => window.removeEventListener("resize", fn);
  }, []);
  return sz;
}

// --- Phone frame ---
// chromeH: estimated height of surrounding UI (topbar + padding + scrubber)
function PhoneFrame({ children, statusTime = "9:41", chromeH = 160 }) {
  const { w: vw, h: vh } = useWindowSize();
  const NW = 414, NH = 868;
  const scaleW = (vw - 32) / NW;
  const scaleH = (vh - chromeH) / NH;
  const scale = Math.max(0.5, Math.min(1, scaleW, scaleH));
  const W = Math.round(NW * scale);
  const H = Math.round(NH * scale);

  return (
    <div style={{ width: W, height: H, position: "relative", flexShrink: 0 }}>
      <div style={{
        position: "absolute", top: 0, left: 0,
        width: NW, height: NH,
        borderRadius: 56, padding: 12,
        background: "linear-gradient(180deg, #1c1917 0%, #0c0a09 100%)",
        boxShadow: "0 60px 120px -30px rgba(0,0,0,0.55), 0 30px 60px -30px rgba(0,0,0,0.4), inset 0 0 0 1px rgba(255,255,255,0.04)",
        transform: `scale(${scale})`,
        transformOrigin: "top left",
      }}>
        <div style={{
          width: "100%", height: "100%", borderRadius: 44,
          background: "#fafaf9", overflow: "hidden", position: "relative",
          display: "flex", flexDirection: "column",
        }}>
          <StatusBar time={statusTime} />
          <div style={{ flex: 1, position: "relative", overflow: "hidden" }}>
            {children}
          </div>
        </div>
        <div style={{
          position: "absolute", top: 22, left: "50%", transform: "translateX(-50%)",
          width: 110, height: 32, borderRadius: 18, background: "#000", zIndex: 10,
        }} />
      </div>
    </div>
  );
}

function StatusBar({ time }) {
  return (
    <div style={{
      height: 50, padding: "0 28px",
      display: "flex", alignItems: "flex-end", justifyContent: "space-between",
      paddingBottom: 6,
      fontSize: 14, fontWeight: 600, color: "#1c1917",
      flexShrink: 0,
    }}>
      <span style={{ fontVariantNumeric: "tabular-nums" }}>{time}</span>
      <div style={{ display: "flex", gap: 6, alignItems: "center" }}>
        {/* signal */}
        <svg width="16" height="10" viewBox="0 0 16 10" fill="none">
          <rect x="0" y="7" width="2.5" height="3" rx="0.5" fill="#1c1917" />
          <rect x="3.5" y="5" width="2.5" height="5" rx="0.5" fill="#1c1917" />
          <rect x="7" y="3" width="2.5" height="7" rx="0.5" fill="#1c1917" />
          <rect x="10.5" y="0" width="2.5" height="10" rx="0.5" fill="#1c1917" />
        </svg>
        {/* wifi */}
        <svg width="14" height="10" viewBox="0 0 14 10" fill="none">
          <path d="M7 8.5a1 1 0 100-2 1 1 0 000 2z" fill="#1c1917" />
          <path d="M3.5 5.5a5 5 0 017 0" stroke="#1c1917" strokeWidth="1.2" strokeLinecap="round" fill="none" />
          <path d="M1.5 3.5a8 8 0 0111 0" stroke="#1c1917" strokeWidth="1.2" strokeLinecap="round" fill="none" />
        </svg>
        {/* battery */}
        <svg width="24" height="11" viewBox="0 0 24 11" fill="none">
          <rect x="0.5" y="0.5" width="20" height="10" rx="2.5" stroke="#1c1917" strokeOpacity="0.4" fill="none" />
          <rect x="2" y="2" width="17" height="7" rx="1.5" fill="#1c1917" />
          <rect x="21.5" y="3.5" width="1.5" height="4" rx="0.5" fill="#1c1917" fillOpacity="0.4" />
        </svg>
      </div>
    </div>
  );
}

// --- Soko mark ---
function SokoMark({ size = 28, pulsing = false }) {
  return (
    <motion.div
      animate={pulsing ? { scale: [1, 1.06, 1], opacity: [1, 0.85, 1] } : {}}
      transition={pulsing ? { duration: 1.6, repeat: Infinity, ease: "easeInOut" } : {}}
      style={{
        width: size, height: size,
        display: "inline-flex", alignItems: "center", justifyContent: "center",
        position: "relative",
      }}
    >
      <svg width={size} height={size} viewBox="0 0 28 28" fill="none">
        <circle cx="14" cy="14" r="13" fill="oklch(0.55 0.16 40)" />
        <path d="M9 14 L13 18 L19 10" stroke="#fafaf9" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" fill="none" />
        <circle cx="14" cy="14" r="13" stroke="oklch(0.42 0.18 35)" strokeWidth="0.5" fill="none" />
      </svg>
    </motion.div>
  );
}

function SokoWordmark({ size = 32, color = "#1c1917" }) {
  return (
    <div style={{
      display: "inline-flex", alignItems: "center", gap: 10,
      fontFamily: "'Inter', -apple-system, sans-serif",
      fontSize: size, lineHeight: 1, color, letterSpacing: -0.5, fontWeight: 400,
    }}>
      <SokoMark size={size * 0.7} />
      <span>soko</span>
    </div>
  );
}

// --- Language / currency / measure toggles ---
function LangToggle({ value = "EN" }) {
  return (
    <div style={{
      display: "inline-flex", gap: 0, fontSize: 11,
      fontFamily: "ui-monospace, Menlo, monospace",
      letterSpacing: 0.5,
      color: "#78716c",
    }}>
      <span style={{ padding: "4px 8px", color: "#1c1917", fontWeight: 700 }}>EN</span>
      <span style={{ padding: "4px 0", color: "#d6d3d1" }}>|</span>
      <span style={{ padding: "4px 8px", color: "#a8a29e" }}>ES</span>
    </div>
  );
}

function CurrencyToggle({ value = "USD" }) {
  return (
    <div style={{
      display: "inline-flex", fontSize: 10,
      fontFamily: "ui-monospace, Menlo, monospace",
      border: "1px solid #e7e5e4", borderRadius: 6,
      overflow: "hidden",
    }}>
      <span style={{ padding: "3px 8px", background: "#1c1917", color: "#fafaf9", fontWeight: 600 }}>USD $</span>
      <span style={{ padding: "3px 8px", background: "#fafaf9", color: "#78716c" }}>MXN $</span>
    </div>
  );
}

function UnitToggle({ value = "cm" }) {
  return (
    <div style={{
      display: "inline-flex", fontSize: 10,
      fontFamily: "ui-monospace, Menlo, monospace",
      border: "1px solid #e7e5e4", borderRadius: 6, overflow: "hidden",
    }}>
      {["cm", "inch"].map(o => (
        <span key={o} style={{
          padding: "3px 10px",
          background: value === o ? "#1c1917" : "#fafaf9",
          color: value === o ? "#fafaf9" : "#78716c",
          fontWeight: value === o ? 600 : 400,
        }}>{o}</span>
      ))}
    </div>
  );
}

// --- Striped product placeholder (per spec aesthetic default) ---
function ProductPlaceholder({ product, height = 140, label }) {
  const a = product?.hueA || "oklch(0.78 0.04 50)";
  const b = product?.hueB || "oklch(0.55 0.04 30)";
  const tag = label || product?.tag || "PRODUCT";
  const stripeId = `stripe-${product?.id || Math.random().toString(36).slice(2)}`;
  return (
    <div style={{
      width: "100%", height, position: "relative",
      borderRadius: 8, overflow: "hidden",
      background: `linear-gradient(135deg, ${a} 0%, ${b} 100%)`,
    }}>
      <svg width="100%" height="100%" style={{ position: "absolute", inset: 0 }}>
        <defs>
          <pattern id={stripeId} patternUnits="userSpaceOnUse" width="14" height="14" patternTransform="rotate(45)">
            <line x1="0" y1="0" x2="0" y2="14" stroke="rgba(255,255,255,0.10)" strokeWidth="6" />
          </pattern>
        </defs>
        <rect width="100%" height="100%" fill={`url(#${stripeId})`} />
      </svg>
      <div style={{
        position: "absolute", bottom: 6, left: 8,
        fontFamily: "ui-monospace, Menlo, monospace",
        fontSize: 8, letterSpacing: 1.2,
        color: "rgba(255,255,255,0.85)",
        textShadow: "0 1px 2px rgba(0,0,0,0.2)",
      }}>{tag}</div>
    </div>
  );
}

// --- Trust / vetted badge ---
function VettedBadge({ date, compact = false }) {
  return (
    <span title={`Vetted by soko team · ${date}`} style={{
      display: "inline-flex", alignItems: "center", gap: 4,
      fontSize: compact ? 9 : 10,
      fontFamily: "ui-monospace, Menlo, monospace",
      color: "oklch(0.42 0.08 180)",
      background: "oklch(0.96 0.02 180)",
      border: "1px solid oklch(0.88 0.04 180)",
      padding: compact ? "2px 6px" : "3px 8px",
      borderRadius: 4,
      letterSpacing: 0.3,
    }}>
      <svg width="10" height="10" viewBox="0 0 12 12" fill="none">
        <path d="M2.5 6L5 8.5L9.5 3.5" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
      </svg>
      Vetted · {date}
    </span>
  );
}

function TrustPassBadge({ kind = "TrustPass" }) {
  const isAudit = kind.includes("Audit");
  return (
    <span style={{
      display: "inline-flex", alignItems: "center", gap: 3,
      fontSize: 9, fontFamily: "ui-monospace, Menlo, monospace",
      color: isAudit ? "oklch(0.42 0.08 180)" : "#78716c",
      background: "transparent",
      border: `1px solid ${isAudit ? "oklch(0.85 0.05 180)" : "#e7e5e4"}`,
      padding: "2px 5px", borderRadius: 3,
      letterSpacing: 0.3,
    }}>
      {isAudit && (
        <svg width="8" height="8" viewBox="0 0 12 12" fill="none">
          <path d="M2.5 6L5 8.5L9.5 3.5" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" />
        </svg>
      )}
      {kind}
    </span>
  );
}

// --- Title (single-line) ---
function BilingualTitle({ en, size = 14, weight = 600, primaryColor = "#1c1917" }) {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 2, position: "relative" }}>
      <div style={{ fontSize: size, fontWeight: weight, color: primaryColor, lineHeight: 1.25 }}>{en}</div>
    </div>
  );
}

// --- Tiny chips ---
function Chip({ children, tone = "neutral", icon }) {
  const tones = {
    neutral: { bg: "#f5f5f4", fg: "#57534e", bd: "#e7e5e4" },
    primary: { bg: "oklch(0.96 0.04 50)", fg: "oklch(0.42 0.16 40)", bd: "oklch(0.88 0.06 50)" },
    teal: { bg: "oklch(0.96 0.02 180)", fg: "oklch(0.42 0.08 180)", bd: "oklch(0.88 0.04 180)" },
    navy: { bg: "oklch(0.96 0.01 250)", fg: "oklch(0.30 0.04 250)", bd: "oklch(0.88 0.02 250)" },
  };
  const t = tones[tone] || tones.neutral;
  return (
    <span style={{
      display: "inline-flex", alignItems: "center", gap: 4,
      fontSize: 10, fontFamily: "ui-monospace, Menlo, monospace",
      padding: "3px 7px", borderRadius: 4,
      background: t.bg, color: t.fg, border: `1px solid ${t.bd}`,
      letterSpacing: 0.3, whiteSpace: "nowrap",
    }}>
      {icon}
      {children}
    </span>
  );
}

// --- Sentiment dot ---
function SentimentDot({ polarity }) {
  const c = polarity === "positive" ? "oklch(0.55 0.12 150)"
    : polarity === "neutral" ? "oklch(0.65 0.05 80)"
    : "oklch(0.55 0.15 25)";
  return <span style={{ display: "inline-block", width: 6, height: 6, borderRadius: 3, background: c }} />;
}

// --- Typewriter hook ---
function useTypewriter(text, charsPerSec = 30, start = true) {
  const [i, setI] = React.useState(0);
  React.useEffect(() => {
    if (!start) { setI(0); return; }
    setI(0);
    if (!text) return;
    const interval = 1000 / charsPerSec;
    const id = setInterval(() => {
      setI(prev => {
        if (prev >= text.length) { clearInterval(id); return prev; }
        return prev + 1;
      });
    }, interval);
    return () => clearInterval(id);
  }, [text, charsPerSec, start]);
  return text ? text.slice(0, i) : "";
}

// --- Three-dot loader ---
function ThreeDots() {
  return (
    <span style={{ display: "inline-flex", gap: 3, alignItems: "center", height: 8 }}>
      {[0, 1, 2].map(i => (
        <motion.span key={i}
          animate={{ opacity: [0.2, 1, 0.2], y: [0, -2, 0] }}
          transition={{ duration: 1, repeat: Infinity, delay: i * 0.15 }}
          style={{ display: "block", width: 5, height: 5, borderRadius: 3, background: "oklch(0.55 0.16 40)" }}
        />
      ))}
    </span>
  );
}

// --- FadeUp wrapper ---
function FadeUp({ children, delay = 0, y = 12, duration = 0.4 }) {
  return (
    <motion.div
      initial={{ opacity: 0, y }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ duration, delay, ease: [0.22, 1, 0.36, 1] }}
    >
      {children}
    </motion.div>
  );
}

Object.assign(window, {
  PhoneFrame, StatusBar, SokoMark, SokoWordmark,
  LangToggle, CurrencyToggle, UnitToggle,
  ProductPlaceholder, VettedBadge, TrustPassBadge,
  BilingualTitle, Chip, SentimentDot,
  useTypewriter, ThreeDots, FadeUp, useWindowSize,
});
