/* eslint-disable */
/* Shared UI components for Игра в слова */

const { useState, useEffect, useRef, useCallback, useMemo } = React;

// ===== Star (decorative) =====
function StarIcon({ size = 24, style = {}, ...rest }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="currentColor" style={style} {...rest}>
      <path d="M12 2l2.92 6.91L22 10l-5.5 4.77L18.18 22 12 18.27 5.82 22l1.68-7.23L2 10l7.08-1.09z"/>
    </svg>
  );
}

function formatDuration(ms) {
  if (!Number.isFinite(Number(ms))) return "—";
  const total = Math.max(0, Math.round(Number(ms) / 1000));
  const minutes = Math.floor(total / 60);
  const seconds = String(total % 60).padStart(2, "0");
  return `${minutes}:${seconds}`;
}

// ===== Brand =====
function Brand({ onClick }) {
  return (
    <a href="#" onClick={e => { e.preventDefault(); onClick && onClick(); }} className="brand">
      <span style={{
        width: 38, height: 38, borderRadius: 12,
        display: "inline-flex", alignItems: "center", justifyContent: "center",
        background: "linear-gradient(135deg, var(--gold) 0%, var(--gold-deep) 100%)",
        color: "var(--ink-1)",
        boxShadow: "0 4px 14px rgba(255,217,61,0.4)",
      }}>
        <StarIcon size={22}/>
      </span>
      <span>Игра <span style={{ color: "var(--gold)" }}>в слова</span></span>
    </a>
  );
}

// ===== Avatar =====
function Avatar({ player, size = "md", ring = false }) {
  if (!player) return null;
  const cls = size === "sm" ? "avatar avatar-sm" : size === "lg" ? "avatar avatar-lg" : "avatar";
  const initial = (player.name || "?").trim().slice(0, 1).toUpperCase() || "?";
  return (
    <span className={cls} style={{
      background: player.color || "var(--violet)",
      color: "white",
      borderColor: ring ? "var(--gold)" : "white",
    }}>
      {player.isBot ? "🤖" : initial}
    </span>
  );
}

function BellButton({ player, onRing, disabled = false }) {
  if (!onRing || !player || player.isBot) return null;
  return (
    <button
      type="button"
      onClick={e => { e.stopPropagation(); onRing(); }}
      disabled={disabled}
      title={`Позвать ${player.name}`}
      aria-label={`Позвать ${player.name}`}
      style={{
        width: 28,
        height: 28,
        border: "1px solid rgba(255,217,61,0.35)",
        background: disabled ? "rgba(255,255,255,0.04)" : "rgba(255,217,61,0.12)",
        color: "var(--gold)",
        borderRadius: 8,
        cursor: disabled ? "default" : "pointer",
        display: "inline-flex",
        alignItems: "center",
        justifyContent: "center",
        fontSize: 15,
        lineHeight: 1,
      }}
    >
      🔔
    </button>
  );
}

function OnlineDot({ online, size = 9 }) {
  return (
    <span
      title={online ? "Онлайн" : "Офлайн"}
      style={{
        width: size,
        height: size,
        borderRadius: "50%",
        display: "inline-block",
        background: online ? "var(--green)" : "rgba(255,255,255,0.28)",
        boxShadow: online ? "0 0 0 3px rgba(94,234,160,0.14)" : "none",
        flex: "0 0 auto",
      }}
    />
  );
}

function HeaderProfileBadge() {
  const [user, setUser] = useState(window.Auth.getUser());
  const [notifications, setNotifications] = useState(window.ProfileStore?.loadNotifications ? window.ProfileStore.loadNotifications() : { total: 0 });

  useEffect(() => {
    const off = window.Auth.onChange(next => setUser(next));
    return off;
  }, []);

  useEffect(() => {
    if (!user || !window.ProfileStore?.refreshNotifications) return;
    let alive = true;
    function refresh() {
      window.ProfileStore.refreshNotifications()
        .then(next => { if (alive) setNotifications(next); })
        .catch(() => {});
    }
    refresh();
    const interval = setInterval(refresh, 20000);
    return () => { alive = false; clearInterval(interval); };
  }, [user?.id]);

  if (!user) return null;
  const total = notifications?.total || 0;
  return (
    <a href="#profile" className="btn btn-ghost btn-sm" title={user.name ? `Профиль: ${user.name}` : "Профиль"} style={{
      display: "inline-flex",
      alignItems: "center",
      gap: 8,
      maxWidth: 210,
      position: "relative",
    }}>
      <Avatar player={user} size="sm"/>
      <span style={{ overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{user.name || user.username || "Игрок"}</span>
      <span style={{
        minWidth: 18,
        height: 18,
        borderRadius: 9,
        display: "inline-flex",
        alignItems: "center",
        justifyContent: "center",
        padding: "0 5px",
        background: total > 0 ? "var(--magenta)" : "rgba(255,255,255,0.08)",
        color: total > 0 ? "white" : "var(--ink-on-dark-3)",
        fontSize: 11,
        fontWeight: 800,
      }}>
        {total > 0 ? total : "0"}
      </span>
    </a>
  );
}

// ===== Player chip (lobby & results) =====
function PlayerChip({ player, isMe, isYou, right, onRing, statusText, statusColor }) {
  const cls = ["player-chip"];
  if (player.ready) cls.push("player-chip--ready");
  if (isMe || isYou) cls.push("player-chip--me");
  return (
    <div className={cls.join(" ")}>
      <Avatar player={player} />
      <div style={{ display: "flex", flexDirection: "column", lineHeight: 1.2 }}>
        <div className="row" style={{ gap: 6, alignItems: "center" }}>
          {!player.isBot && <OnlineDot online={player.online} />}
          <strong style={{ fontSize: 15 }}>
            {player.name || "Игрок"}
            {(isMe || isYou) && <span className="text-muted" style={{ fontSize: 12, marginLeft: 6 }}>(вы)</span>}
            {player.isBot && <span className="text-muted" style={{ fontSize: 12, marginLeft: 6 }}>(бот)</span>}
          </strong>
          {!isMe && !isYou && <BellButton player={player} onRing={onRing} />}
        </div>
        <span style={{ fontSize: 12, color: statusColor || (player.ready ? "var(--green)" : "var(--ink-on-dark-3)") }}>
          {statusText || (player.ready ? "Готов!" : "Не готов")}
        </span>
      </div>
      {right}
    </div>
  );
}

// ===== Toast system =====
const ToastCtx = React.createContext(null);
function ToastProvider({ children }) {
  const [toasts, setToasts] = useState([]);
  const push = useCallback((msg) => {
    const id = Math.random();
    setToasts(t => [...t, { id, msg }]);
    setTimeout(() => setToasts(t => t.filter(x => x.id !== id)), 3000);
  }, []);
  return (
    <ToastCtx.Provider value={push}>
      {children}
      <div className="toast-stack">
        {toasts.map(t => <div key={t.id} className="toast">{t.msg}</div>)}
      </div>
    </ToastCtx.Provider>
  );
}
function useToast() { return React.useContext(ToastCtx); }

// ===== Timer ring =====
function TimerRing({ secondsLeft, total }) {
  const r = 44;
  const c = 2 * Math.PI * r;
  const pct = Math.max(0, secondsLeft / total);
  const offset = c * (1 - pct);
  const color = secondsLeft <= 10 ? "var(--coral)" : secondsLeft <= 20 ? "var(--gold)" : "var(--cyan)";
  return (
    <div className="timer-ring">
      <svg width="100" height="100">
        <circle cx="50" cy="50" r={r} strokeWidth="8" className="timer-ring__track"/>
        <circle cx="50" cy="50" r={r} strokeWidth="8" className="timer-ring__bar"
          stroke={color}
          strokeDasharray={c}
          strokeDashoffset={offset}
          style={{ transition: "stroke-dashoffset 1s linear, stroke 300ms" }}/>
      </svg>
      <div className="timer-ring__label" style={{ color }}>{secondsLeft}</div>
    </div>
  );
}

// ===== Confetti =====
function Confetti({ count = 80 }) {
  const items = useMemo(() => Array.from({ length: count }, (_, i) => ({
    id: i,
    left: Math.random() * 100,
    delay: Math.random() * 1.2,
    duration: 2 + Math.random() * 2,
    color: ["#FFD93D","#FF3D8C","#4ECDC4","#8B5CF6","#5EEAA0","#FF6B6B"][Math.floor(Math.random()*6)],
    size: 8 + Math.random() * 8,
    shape: Math.random() > 0.5 ? "0" : "50%",
  })), [count]);
  return (
    <div style={{ position: "fixed", inset: 0, pointerEvents: "none", zIndex: 50, overflow: "hidden" }}>
      {items.map(it => (
        <div key={it.id} style={{
          position: "absolute",
          top: -20,
          left: `${it.left}%`,
          width: it.size, height: it.size,
          background: it.color,
          borderRadius: it.shape,
          animation: `confetti-fall ${it.duration}s ${it.delay}s linear forwards`,
        }}/>
      ))}
    </div>
  );
}

// ===== Letter tile =====
function LetterTile({ letter, used, inWord, onClick, size, dropDelay, animateDrop, big }) {
  const cls = ["tile"];
  if (used) cls.push("tile--used");
  if (inWord) cls.push("tile--in-word");
  const isStar = letter === "★";
  if (isStar) cls.push("tile--star");
  if (animateDrop) cls.push("drop-in");
  const style = { "--tile-size": (size || (big ? "104px" : "84px")) };
  if (dropDelay != null) style.animationDelay = `${dropDelay}ms`;
  return (
    <button className={cls.join(" ")} style={style} onClick={onClick} disabled={used}>
      {isStar ? <StarIcon size={parseInt(size || 60) * 0.6}/> : letter}
    </button>
  );
}

// ===== Modal =====
function Modal({ open, onClose, title, children, width = 520 }) {
  if (!open) return null;
  return (
    <div onClick={onClose} style={{
      position: "fixed", inset: 0, zIndex: 80,
      background: "rgba(8,4,40,0.6)", backdropFilter: "blur(8px)",
      display: "flex", alignItems: "center", justifyContent: "center",
      padding: "max(12px, env(safe-area-inset-top)) 12px max(12px, env(safe-area-inset-bottom))",
      animation: "toast-in 200ms ease-out",
    }}>
      <div onClick={e => e.stopPropagation()} className="card" style={{
        background: "var(--surface-dark)", color: "white",
        border: "1.5px solid rgba(255,255,255,0.1)",
        maxWidth: width, width: "100%",
        maxHeight: "calc(100vh - 32px)",
        overflowY: "auto",
        animation: "pop-in 280ms cubic-bezier(.2,.8,.2,1.4)",
      }}>
        {title && <h3 className="display-2" style={{ marginBottom: 18 }}>{title}</h3>}
        {children}
      </div>
    </div>
  );
}

function MobileNav({ user, route }) {
  const head = (route || "home").split("/")[0] || "home";
  const activeKey = ["join", "room", "game", "results", "final"].includes(head)
    ? "rooms"
    : head === "auth" ? "profile" : head;
  const items = [
    { key: "home", href: "#home", icon: "⌂", label: "Главная" },
    { key: "rooms", href: "#rooms", icon: "□", label: "Комнаты" },
    { key: "create", href: user ? "#create" : "#auth/register", icon: "+", label: "Создать" },
    { key: "stats", href: "#stats", icon: "≡", label: "Лидеры" },
    { key: "profile", href: user ? "#profile" : "#auth", icon: user ? "◎" : "↪", label: user ? "Профиль" : "Войти" },
  ];
  return (
    <nav className="mobile-bottom-nav" aria-label="Быстрая навигация">
      {items.map(item => (
        <a
          key={item.key}
          href={item.href}
          className={"mobile-bottom-nav__item " + (activeKey === item.key ? "is-active" : "")}
        >
          <span className="mobile-bottom-nav__icon">{item.icon}</span>
          <span className="mobile-bottom-nav__label">{item.label}</span>
        </a>
      ))}
    </nav>
  );
}

// ===== Topbar (with sound toggle, stats) =====
function Topbar({ onHome, right }) {
  const [muted, setMuted] = useState(!window.Sound.enabled);
  function toggleSound() {
    window.Sound.enabled = !window.Sound.enabled;
    setMuted(!window.Sound.enabled);
    if (window.Sound.enabled) window.Sound.pick();
  }
  return (
    <div className="topbar">
      <Brand onClick={onHome}/>
      <div className="topbar-actions">
        <nav className="topbar-nav" aria-label="Главное меню">
          <a className="btn btn-ghost btn-sm" href="#rooms">Комнаты</a>
          <a className="btn btn-ghost btn-sm" href="#stats">Лидеры</a>
        </nav>
        <HeaderProfileBadge />
        {right}
        <button className="btn btn-ghost btn-sm" onClick={toggleSound} title="Звук" aria-label="Звук" style={{ padding: 12, minWidth: 44 }}>
          {muted ? "🔇" : "🔊"}
        </button>
      </div>
    </div>
  );
}

// ===== Starfield wrapper =====
function Starfield() {
  return <div className="starfield" aria-hidden="true"/>;
}

// ===== ChatPanel: reusable chat + emoji reactions =====
const PRESET_EMOJI = ["🎉","😂","🔥","👏","🤯","💪","🤔","😱","🥳","👍","🤝","💯","💩"];

function ChatPanel({ roomId, me, title = "Чат", style }) {
  const [room, setRoom] = useState(window.RoomOps.getRoom(roomId));
  const [input, setInput] = useState("");
  const scrollRef = useRef(null);
  const lastSeenAtRef = useRef(Date.now());
  const [floats, setFloats] = useState([]);
  const panelRef = useRef(null);

  useEffect(() => {
    return window.RoomOps.subscribe(roomId, r => {
      if (r) setRoom(r);
    });
  }, [roomId]);

  useEffect(() => {
    if (scrollRef.current) scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
  }, [room?.chat?.length]);

  // Detect new emoji reactions → bubble float
  useEffect(() => {
    if (!room?.chat) return;
    const since = lastSeenAtRef.current;
    const newReacts = room.chat.filter(m => m.kind === "emoji" && m.at > since);
    if (newReacts.length === 0) return;
    lastSeenAtRef.current = Math.max(since, ...newReacts.map(m => m.at));
    newReacts.forEach((r, i) => {
      setTimeout(() => {
        const id = Math.random();
        setFloats(f => [...f, { id, emoji: r.emoji, left: 10 + Math.random() * 70 }]);
        setTimeout(() => setFloats(f => f.filter(x => x.id !== id)), 2400);
      }, i * 140);
    });
  }, [room?.chat?.length]);

  if (!room) return null;

  async function send(e) {
    if (e) e.preventDefault();
    if (!input.trim()) return;
    await window.RoomOps.sendChat(roomId, input.trim()).catch(() => {});
    setInput("");
  }

  async function react(emoji) {
    await window.RoomOps.sendEmoji(roomId, emoji).catch(() => {});
    if (window.Sound.enabled) window.Sound.pick();
  }

  return (
    <div ref={panelRef} className="card-dark" style={{
      display: "flex", flexDirection: "column", padding: 0, overflow: "hidden",
      minHeight: 380, position: "relative", ...style
    }}>
      {/* Floating emoji bubbles */}
      <div style={{ position: "absolute", inset: 0, pointerEvents: "none", overflow: "hidden" }}>
        {floats.map(f => (
          <div key={f.id} className="float-emoji" style={{ left: `${f.left}%`, bottom: 80 }}>{f.emoji}</div>
        ))}
      </div>

      <div className="between" style={{ padding: "16px 20px 12px", borderBottom: "1px solid rgba(255,255,255,0.08)" }}>
        <h3 className="h-section">{title}</h3>
        <span className="text-muted" style={{ fontSize: 12 }}>{room.players.length} в комнате</span>
      </div>

      <div ref={scrollRef} style={{ flex: 1, overflowY: "auto", padding: "12px 20px", display: "flex", flexDirection: "column", gap: 10, minHeight: 200 }}>
        {room.chat.length === 0 && (
          <div className="text-muted text-center" style={{ fontSize: 13, padding: 20, fontStyle: "italic" }}>
            Пока тихо… бросьте эмоджи или напишите что-нибудь
          </div>
        )}
        {room.chat.map(m => {
          if (m.kind === "system") {
            return <div key={m.id} className="text-muted text-center" style={{ fontSize: 12, fontStyle: "italic" }}>{m.text}</div>;
          }
          if (m.kind === "ring") {
            const isTarget = m.targetPlayerId === me.id;
            return (
              <div key={m.id} className="text-center" style={{
                fontSize: 12,
                color: isTarget ? "var(--gold)" : "var(--ink-on-dark-2)",
                fontWeight: isTarget ? 700 : 500,
                fontStyle: "italic",
              }}>
                🔔 {m.name} зовёт {isTarget ? "вас" : (m.text || "игрока")} в игру
              </div>
            );
          }
          if (m.kind === "emoji") {
            const isMine = m.playerId === me.id;
            return (
              <div key={m.id} className="row" style={{ alignItems: "center", gap: 8, justifyContent: isMine ? "flex-end" : "flex-start" }}>
                {!isMine && <Avatar player={{ name: m.name, color: m.color }} size="sm"/>}
                <div style={{ fontSize: 32, lineHeight: 1 }}>{m.emoji}</div>
                <span className="text-muted" style={{ fontSize: 12 }}>{isMine ? "вы" : m.name}</span>
                {isMine && <Avatar player={{ name: m.name, color: m.color }} size="sm"/>}
              </div>
            );
          }
          // text message
          const isMine = m.playerId === me.id;
          return (
            <div key={m.id} className="row" style={{ alignItems: "flex-start", gap: 8 }}>
              <Avatar player={{ name: m.name, color: m.color }} size="sm"/>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 12, color: "var(--ink-on-dark-2)", fontWeight: 600 }}>{m.name}{isMine && <span className="text-muted" style={{ fontWeight: 400 }}> · вы</span>}</div>
                <div style={{ fontSize: 14, wordWrap: "break-word", color: "white" }}>{m.text}</div>
              </div>
            </div>
          );
        })}
      </div>

      {/* Quick reaction bar */}
      <div className="row" style={{
        padding: "8px 12px", gap: 6, borderTop: "1px solid rgba(255,255,255,0.08)",
        overflowX: "auto", scrollbarWidth: "none",
      }}>
        {PRESET_EMOJI.map(e => (
          <button key={e} onClick={() => react(e)} style={{
            width: 40, height: 40, flexShrink: 0,
            border: "none", background: "rgba(255,255,255,0.06)",
            borderRadius: 10, cursor: "pointer",
            fontSize: 22, lineHeight: 1,
            transition: "transform 100ms, background 100ms",
          }} onMouseEnter={e => e.currentTarget.style.background = "rgba(255,217,61,0.18)"}
             onMouseLeave={e => e.currentTarget.style.background = "rgba(255,255,255,0.06)"}>
            {e}
          </button>
        ))}
      </div>

      <form onSubmit={send} className="row" style={{ padding: "10px 14px 14px", gap: 8, borderTop: "1px solid rgba(255,255,255,0.08)" }}>
        <input className="field" placeholder="написать…" value={input} onChange={e => setInput(e.target.value)} style={{ padding: "12px 14px", fontSize: 14 }} maxLength={140}/>
        <button className="btn btn-primary btn-sm" type="submit" disabled={!input.trim()}>↑</button>
      </form>
    </div>
  );
}

// ===== Exports =====
Object.assign(window, {
  StarIcon, Brand, Avatar, PlayerChip, BellButton, OnlineDot, HeaderProfileBadge,
  ToastProvider, useToast, ToastCtx,
  TimerRing, Confetti, LetterTile, Modal, MobileNav, Topbar, Starfield,
  ChatPanel, PRESET_EMOJI,
});
