/* global React, C, Screen, Header, Tabs, Avatar, Pill, Chevron, Plus, Bolt, Lock */
// screens-8.jsx — Clubhouse: per-pool message board / chat

// Reaction shorthand → emoji lookup.
const REACTION_EMOJI = { fire: '🔥', salute: '🤝', laugh: '😂', skull: '💀',
  eyeroll: '🙄', golf: '🏌️', eyes: '👀', eagle: '🦅', clap: '👏', heart: '❤️' };

function ClubhouseScreen() {
  const me = window.useStore((s) => s.me);
  const [tournament, setTournament] = React.useState(null);
  const [messages, setMessages] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const feedRef = React.useRef(null);

  const fetchMessages = React.useCallback(async (tournamentId) => {
    const api = window.cambamApi;
    if (!api || !api.isConfigured?.() || !tournamentId) return;
    try {
      const data = await api.loadClubhouseMessages(tournamentId);
      // Map Supabase row shape → screen shape.
      const mapped = (data || []).map((row) => {
        const isMe = row.member?.handle === me?.handle;
        const createdAt = new Date(row.created_at);
        return {
          id: row.id,
          author: row.member?.display_name || row.member?.handle || '—',
          handle: row.member?.handle,
          tone: row.member?.avatar_tone || 1,
          champion: !!row.member?.champion,
          time: createdAt.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' }).toLowerCase().replace(' ', ''),
          day: createdAt.toLocaleDateString('en-US', { weekday: 'long', month: 'short', day: 'numeric' }),
          text: row.body,
          reactions: row.reactions || {},
          you: isMe,
          kind: row.is_event ? 'event' : 'message',
        };
      });
      setMessages(mapped);
    } catch (e) {
      console.warn('clubhouse load failed', e);
    }
  }, [me?.handle]);

  // Initial load + poll every 30s.
  React.useEffect(() => {
    const api = window.cambamApi;
    if (!api || !api.isConfigured?.()) { setLoading(false); return; }
    let cancelled = false;
    (async () => {
      try {
        const t = await api.currentTournament?.();
        if (cancelled) return;
        setTournament(t || null);
        if (!t) { setLoading(false); return; }
        await fetchMessages(t.id);
        setLoading(false);
      } catch (e) { console.warn('clubhouse init failed', e); if (!cancelled) setLoading(false); }
    })();
    return () => { cancelled = true; };
  }, [fetchMessages]);

  React.useEffect(() => {
    if (!tournament?.id) return;
    const handle = setInterval(() => { fetchMessages(tournament.id); }, 30_000);
    return () => clearInterval(handle);
  }, [tournament?.id, fetchMessages]);

  // Auto-scroll on new messages.
  React.useEffect(() => {
    if (feedRef.current) feedRef.current.scrollTop = feedRef.current.scrollHeight;
  }, [messages.length]);

  const groupedByDay = React.useMemo(() => {
    const byDay = [];
    let lastDay = null;
    for (const m of messages) {
      const day = m.day || 'Today';
      if (day !== lastDay) { byDay.push({ day, items: [] }); lastDay = day; }
      byDay[byDay.length - 1].items.push(m);
    }
    return byDay;
  }, [messages]);

  const send = async (text) => {
    const trimmed = (text || '').trim();
    if (!trimmed || !tournament) return;
    const tmpId = 'tmp-' + Date.now();
    const now = new Date();
    const optimistic = {
      id: tmpId, author: me?.displayName || 'You', handle: me?.handle,
      tone: me?.tone || 6, time: now.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' }).toLowerCase().replace(' ', ''),
      day: now.toLocaleDateString('en-US', { weekday: 'long', month: 'short', day: 'numeric' }),
      text: trimmed, reactions: {}, you: true, kind: 'message',
    };
    setMessages((prev) => [...prev, optimistic]);
    if (window.cambamApi?.postClubhouseMessage) {
      try { await window.cambamApi.postClubhouseMessage(tournament.id, trimmed); }
      catch (e) { console.warn('post failed', e); window.STORE.toast('Post failed'); }
      // Re-fetch to swap optimistic for real.
      fetchMessages(tournament.id);
    }
  };

  const react = async (msgId, key) => {
    // Optimistic toggle: bump count locally then call RPC.
    setMessages((prev) => prev.map((m) => {
      if (m.id !== msgId) return m;
      const r = { ...(m.reactions || {}) };
      const users = Array.isArray(r[key]) ? r[key].slice() : [];
      const idx = users.indexOf(me?.handle);
      if (idx === -1) users.push(me?.handle);
      else users.splice(idx, 1);
      r[key] = users;
      return { ...m, reactions: r };
    }));
    if (window.cambamApi?.reactToMessage) {
      try { await window.cambamApi.reactToMessage(msgId, key); }
      catch (e) { console.warn('react failed', e); }
    }
  };

  return (
    <Screen label="07 Clubhouse" bottomNav="pools" scroll={false}>
      <Header
        title={tournament?.name || (loading ? 'Loading…' : 'Clubhouse')}
        subtitle="Clubhouse"
        onBack
      />

      <Tabs items={['Lineup', 'Standings', 'Matchup', 'Clubhouse']} active="Clubhouse" onChange={poolTab} />

      <div ref={feedRef} style={{
        height: 'calc(100% - 110px - 50px)', overflow: 'auto',
        padding: '12px 0 8px',
      }}>
        {!tournament && !loading && (
          <div style={{ padding: '32px 24px', color: C.text2, font: '400 14px/22px Inter', textAlign: 'center' }}>
            No active tournament.
          </div>
        )}

        {tournament && messages.length === 0 && !loading && (
          <div style={{ padding: '32px 24px', color: C.text2, font: '400 14px/22px Inter', textAlign: 'center' }}>
            No messages yet. Say something.
          </div>
        )}

        {groupedByDay.map((group, i) => (
          <React.Fragment key={i}>
            <DayDivider>{group.day}</DayDivider>
            {group.items.map((m) => (
              m.kind === 'event' ? (
                <EventCard key={m.id} kind="lineup" name={m.author} tone={m.tone} champion={m.champion} time={m.time} text={m.text} />
              ) : (
                <Message key={m.id} id={m.id}
                  name={m.you ? null : m.author} tone={m.tone} champion={m.champion}
                  you={m.you} time={m.time} body={m.text}
                  reactions={Object.entries(m.reactions || {}).map(([k, users]) => ({
                    e: REACTION_EMOJI[k] || '·', k, n: Array.isArray(users) ? users.length : Number(users) || 0,
                  })).filter((r) => r.n > 0)}
                  onReact={(k) => react(m.id, k)}
                />
              )
            ))}
          </React.Fragment>
        ))}
      </div>

      <Composer onSend={send} disabled={!tournament} />
    </Screen>
  );
}

function DayDivider({ children }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 12,
      padding: '12px 16px 16px',
    }}>
      <div style={{ flex: 1, height: 1, background: C.hairline }} />
      <span style={{
        font: '500 11px/16px Inter', textTransform: 'uppercase', letterSpacing: 0.04 * 11,
        color: C.text3,
      }}>{children}</span>
      <div style={{ flex: 1, height: 1, background: C.hairline }} />
    </div>
  );
}

function Message({ id, name, tone, champion, you, time, body, reactions, attachment, onReact }) {
  if (you) {
    return (
      <div style={{
        padding: '6px 16px', display: 'flex', flexDirection: 'column',
        alignItems: 'flex-end', gap: 4,
      }}>
        {attachment}
        <div style={{
          maxWidth: '78%', background: 'rgba(31, 138, 91, 0.16)',
          padding: '8px 12px', borderRadius: '14px 14px 4px 14px',
          font: '400 15px/22px Inter', color: C.text,
        }}>{body}</div>
        <ReactionsRow reactions={reactions} you time={time} onReact={onReact} />
      </div>
    );
  }
  return (
    <div style={{ padding: '6px 16px', display: 'flex', gap: 10 }}>
      <Avatar name={name} size={32} tone={tone} champion={champion} />
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ display: 'flex', alignItems: 'baseline', gap: 8 }}>
          <span style={{ font: '600 14px/20px Inter', color: C.text }}>{name}</span>
          <span style={{ font: '400 12px/16px Inter', color: C.text3 }}>{time}</span>
        </div>
        <div style={{
          marginTop: 2, padding: '8px 12px', background: C.surface,
          borderRadius: '4px 14px 14px 14px',
          font: '400 15px/22px Inter', color: C.text,
          display: 'inline-block', maxWidth: '92%',
        }}>{body}</div>
        {attachment}
        <ReactionsRow reactions={reactions} onReact={onReact} />
      </div>
    </div>
  );
}

const REACTION_KEYS = ['fire', 'salute', 'laugh', 'skull', 'eyes', 'eagle', 'clap', 'heart'];

function ReactionsRow({ reactions = [], you, onReact }) {
  const [pickerOpen, setPickerOpen] = React.useState(false);
  return (
    <div style={{
      position: 'relative',
      display: 'flex', gap: 4, marginTop: 6,
      justifyContent: you ? 'flex-end' : 'flex-start',
      flexWrap: 'wrap',
    }}>
      {reactions.map((r, i) => (
        <button key={i} onClick={() => onReact && onReact(r.k)} style={{
          display: 'inline-flex', alignItems: 'center', gap: 4,
          padding: '2px 8px', borderRadius: 999,
          background: C.surface2, border: `1px solid ${C.hairline}`,
          font: '500 12px/16px Inter', color: C.text2,
          cursor: 'pointer',
        }}>
          <span style={{ fontSize: 12, lineHeight: '14px' }}>{r.e}</span>
          <span className="tnum">{r.n}</span>
        </button>
      ))}
      <button onClick={() => setPickerOpen((v) => !v)} style={{
        width: 26, height: 22, padding: 0,
        background: C.surface2, border: `1px solid ${C.hairline}`, borderRadius: 999,
        color: C.text3, cursor: 'pointer',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
      }}>
        <Plus size={12} />
      </button>
      {pickerOpen && (
        <div onMouseLeave={() => setPickerOpen(false)} style={{
          position: 'absolute', [you ? 'right' : 'left']: 0, top: 28,
          background: C.surface, border: `1px solid ${C.hairline}`,
          borderRadius: 999, padding: '4px 6px', display: 'flex', gap: 2, zIndex: 20,
        }}>
          {REACTION_KEYS.map((k) => (
            <button key={k} onClick={() => { onReact && onReact(k); setPickerOpen(false); }} style={{
              width: 28, height: 28, borderRadius: 999, border: 'none', background: 'transparent',
              cursor: 'pointer', fontSize: 16,
            }}>{REACTION_EMOJI[k]}</button>
          ))}
        </div>
      )}
    </div>
  );
}

function EventCard({ kind, name, tone, champion, time, text, highlight }) {
  const icons = {
    lead:   <span style={{ fontSize: 14 }}>🏆</span>,
    lineup: <span style={{ fontSize: 14 }}>✏️</span>,
    lock:   <Lock size={13} />,
  };
  return (
    <div style={{
      margin: '8px 16px', padding: '10px 14px',
      background: 'rgba(31, 138, 91, 0.06)',
      border: `1px solid rgba(31, 138, 91, 0.18)`,
      borderRadius: 999,
      display: 'flex', alignItems: 'center', gap: 10,
      font: '500 13px/18px Inter', color: C.text2,
    }}>
      <span style={{ color: C.emerald, display: 'inline-flex', alignItems: 'center' }}>
        {icons[kind]}
      </span>
      {name && <>
        <Avatar name={name} size={20} tone={tone} champion={champion} />
        <span style={{ color: C.text, fontWeight: 600 }}>{name}</span>
      </>}
      <span>{text}</span>
      {highlight && (
        <span className="tnum" style={{ color: C.emerald, fontWeight: 700 }}>{highlight}</span>
      )}
      <span style={{ marginLeft: 'auto', color: C.text3, font: '400 12px/16px Inter' }}>{time}</span>
    </div>
  );
}

// LineupAttachment will be reimplemented to load the attached lineup_id
// from Supabase when a clubhouse message has an attachment payload.

function Composer({ onSend, disabled }) {
  const appMode = window.APP_MODE === true;
  const [text, setText] = React.useState('');
  const canSubmit = !!text.trim() && !disabled;
  const submit = () => {
    if (!canSubmit) return;
    onSend && onSend(text);
    setText('');
  };
  return (
    <form onSubmit={(e) => { e.preventDefault(); submit(); }} style={{
      position: 'absolute', left: 0, right: 0,
      bottom: appMode ? 'calc(72px + env(safe-area-inset-bottom))' : 90,
      background: C.bg, borderTop: `1px solid ${C.hairline}`,
      padding: '10px 12px',
      display: 'flex', alignItems: 'center', gap: 8,
      zIndex: 80,
    }}>
      <button type="button" style={{
        width: 36, height: 36, borderRadius: 999, background: C.surface2,
        border: 'none', cursor: 'pointer', color: C.text2,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
      }} aria-label="Add attachment">
        <Plus size={18} />
      </button>
      <input
        type="text" placeholder={disabled ? 'No tournament yet…' : 'Message the clubhouse…'}
        value={text} onChange={(e) => setText(e.target.value)} disabled={disabled}
        style={{
          flex: 1, minHeight: 36, padding: '8px 14px',
          background: C.surface2, borderRadius: 999,
          font: '400 15px/20px Inter', color: C.text,
          border: 'none', outline: 'none',
        }}
      />
      <button type="submit" disabled={!canSubmit} aria-label="Send" style={{
        width: 36, height: 36, borderRadius: 999,
        background: canSubmit ? C.emerald : C.surface2,
        border: 'none', cursor: canSubmit ? 'pointer' : 'not-allowed',
        color: canSubmit ? '#0a0a0a' : C.text3,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
      }}>
        <Bolt size={14} />
      </button>
    </form>
  );
}

Object.assign(window, { ClubhouseScreen });
