/* ============================================================
   BridgeOS — Messages + Activity
   Real-time via Supabase when logged in; local-only in demo mode.
   ============================================================ */
const REACT_EMOJI = ["🔥", "💪", "👏", "😤", "👑", "🫡"];
const FRIEND_REPLIES = [
  "let's go 💪", "respect.", "I'm catching you this week 👀", "no days off",
  "how's the streak holding?", "saw your numbers — solid.", "gym at 6?", "earned it.",
  "🔥🔥", "keep stacking days", "we're not the same 😤",
];

function Messages({ state, setState, today, initialFriend, authUser }) {
  const P = window.PP;
  const [view, setView] = useState("chats");
  const [active, setActive] = useState(initialFriend || (state.friends[0] && state.friends[0].id));
  const [cloudMsgs, setCloudMsgs] = useState({}); // { [friendId]: Message[] }
  const [loadingCloud, setLoadingCloud] = useState(false);
  const [showAddFriend, setShowAddFriend] = useState(false);
  const [pendingRequests, setPendingRequests] = useState([]);
  const friends = state.friends;
  const messages = state.messages || {};
  const isDemoId = id => id && id.length < 20;
  const notifications = (state.notifications || [])
    .filter(n => !authUser || !n.friendId || !isDemoId(n.friendId))
    .slice().sort((a, b) => b.ts - a.ts);
  const isReal = active && authUser && active.length > 20; // UUID vs short demo id

  function friendById(id) { return friends.find((f) => f.id === id); }

  // Load cloud messages when switching to a real friend
  useEffect(() => {
    if (!authUser || !active || !isReal) return;
    if (cloudMsgs[active]) return; // already loaded
    setLoadingCloud(true);
    Bridge.getMessages(authUser.id, active).then(({ data }) => {
      setCloudMsgs(prev => ({ ...prev, [active]: data || [] }));
      setLoadingCloud(false);
      // mark as read
      Bridge.markMessagesRead(authUser.id, active);
    });
  }, [active, authUser]);

  // Merge incoming realtime message into cloudMsgs
  useEffect(() => {
    if (!authUser) return;
    // Messages come in via the subscription set up in app.jsx (state.messages).
    // Keep cloudMsgs in sync for the open thread.
    if (active && isReal && state.messages[active]) {
      const incoming = state.messages[active];
      setCloudMsgs(prev => {
        const existing = prev[active] || [];
        const merged = [...existing];
        incoming.forEach(m => {
          if (!merged.find(x => x.id === m.id)) merged.push(m);
        });
        return { ...prev, [active]: merged };
      });
    }
  }, [state.messages, active]);

  async function send(text) {
    if (!text.trim()) return;

    if (authUser && isReal) {
      // Real user — send via Supabase
      const { data, error } = await Bridge.sendMessage(authUser.id, active, text.trim());
      if (!error && data) {
        const msg = { id: data.id, from: authUser.id, from_id: authUser.id, text: data.text, ts: new Date(data.created_at).getTime(), read: true };
        setCloudMsgs(prev => ({ ...prev, [active]: [...(prev[active] || []), msg] }));
      }
    } else {
      // Demo mode — local only
      setState((s) => {
        const msgs = JSON.parse(JSON.stringify(s.messages || {}));
        msgs[active] = msgs[active] || [];
        msgs[active].push({ id: "m" + Date.now(), from: "me", text: text.trim(), ts: Date.now() });
        return { ...s, messages: msgs };
      });
      // Simulated reply
      const aId = active;
      setTimeout(() => {
        setState((s) => {
          const msgs = JSON.parse(JSON.stringify(s.messages || {}));
          msgs[aId] = msgs[aId] || [];
          msgs[aId].push({ id: "m" + Date.now() + "r", from: aId, text: FRIEND_REPLIES[Math.floor(Math.random() * FRIEND_REPLIES.length)], ts: Date.now() });
          return { ...s, messages: msgs };
        });
      }, 1100 + Math.random() * 1500);
    }
  }

  function react(notifId, emoji) {
    if (authUser) {
      Bridge.reactToNotification(notifId, emoji);
    }
    setState((s) => {
      const notifs = (s.notifications || []).map((n) => n.id === notifId ? { ...n, emoji, read: true } : n);
      const target = notifs.find((n) => n.id === notifId);
      const msgs = JSON.parse(JSON.stringify(s.messages || {}));
      if (target && target.friendId) {
        msgs[target.friendId] = msgs[target.friendId] || [];
        msgs[target.friendId].push({ id: "m" + Date.now(), from: "me", text: `${emoji} on "${target.text}"`, ts: Date.now() });
      }
      return { ...s, notifications: notifs, messages: msgs };
    });
  }

  function markRead(friendId) {
    if (authUser && friendId.length > 20) {
      Bridge.markMessagesRead(authUser.id, friendId);
    }
    setState((s) => {
      const msgs = JSON.parse(JSON.stringify(s.messages || {}));
      (msgs[friendId] || []).forEach((m) => { if (m.from !== "me") m.read = true; });
      return { ...s, messages: msgs };
    });
  }

  useEffect(() => { if (view === "chats" && active) markRead(active); }, [active, view]);

  // Load incoming friend requests
  useEffect(() => {
    if (!authUser) return;
    Bridge.getPendingRequests(authUser.id).then(({ data }) => {
      if (data) setPendingRequests(data);
    });
  }, [authUser]);

  async function acceptRequest(fromId) {
    await Bridge.acceptFriendRequest(fromId, authUser.id);
    setPendingRequests(prev => prev.filter(r => r.from_user_id !== fromId));
    Bridge.getFriends(authUser.id).then(({ data }) => {
      if (data) {
        const realFriends = data.map(Bridge.buildFriendProfile);
        setState(s => ({ ...s, realFriends }));
        setActive(fromId); // jump straight into their chat
      }
    });
  }

  async function declineRequest(fromId) {
    await Bridge.declineFriendRequest(fromId, authUser.id);
    setPendingRequests(prev => prev.filter(r => r.from_user_id !== fromId));
  }

  // Build thread for display
  const thread = (() => {
    if (authUser && isReal) {
      return (cloudMsgs[active] || []).map(m => ({
        ...m,
        from: m.from_id === authUser.id ? "me" : m.from_id,
      }));
    }
    return messages[active] || [];
  })();

  const af = friendById(active);

  return (
    <div className="msgs">
      <div className="ql-head">
        <div>
          <div className="ql-date">Messages</div>
          <div className="ql-quote">
            Talk trash, hype each other up, react to wins.
            {!authUser && <span className="dim"> (Demo mode — sign in for real messaging.)</span>}
          </div>
        </div>
        <div style={{ display: "flex", gap: 10, alignItems: "center", flexWrap: "wrap" }}>
          {authUser && <button className="btn btn-sm btn-accent" onClick={() => setShowAddFriend(true)}>+ Add friend</button>}
          <Seg options={[{ value: "chats", label: "Chats" }, { value: "activity", label: "Activity" }]} value={view} onChange={setView} />
        </div>
      </div>

      {authUser && pendingRequests.length > 0 && (
        <div className="friend-reqs">
          <div className="dd-section-label" style={{ marginBottom: 10 }}>FRIEND REQUESTS</div>
          {pendingRequests.map(req => {
            const p = req.profiles || {};
            const name = p.display_name || p.username || "Someone";
            const hue = name.charCodeAt(0) * 37 % 360;
            const miniProfile = { meta: { name, avatar: p.avatar_url || null } };
            return (
              <div key={req.from_user_id} className="friend-req-row">
                <Avatar profile={miniProfile} size={40} />
                <div className="friend-req-info">
                  <div className="friend-req-name">{name}</div>
                  <div className="friend-req-sub mono dim">@{p.username || "…"} · Lv {p.level || 1}</div>
                </div>
                <div className="friend-req-btns">
                  <button className="btn btn-sm btn-accent" onClick={() => acceptRequest(req.from_user_id)}>Accept</button>
                  <button className="btn btn-sm" onClick={() => declineRequest(req.from_user_id)}>✕</button>
                </div>
              </div>
            );
          })}
        </div>
      )}

      {view === "chats" ? (
        friends.length === 0 && pendingRequests.length === 0 ? (
          <div className="empty">No friends yet. {authUser ? <button className="link-btn" onClick={() => setShowAddFriend(true)}>Add someone</button> : "Sign in to add real friends."}</div>
        ) : friends.length === 0 ? null : (
          <div className="chat-wrap">
            <div className="chat-list">
              {friends.map((f) => {
                const t = authUser && f.id.length > 20 ? (cloudMsgs[f.id] || []) : (messages[f.id] || []);
                const last = t[t.length - 1];
                const unread = t.filter((m) => m.from !== "me" && !(authUser && m.from_id === authUser.id) && !m.read).length;
                return (
                  <button key={f.id} className={"chat-li" + (active === f.id ? " on" : "")} onClick={() => setActive(f.id)}>
                    <Avatar profile={f} size={40} />
                    <div className="chat-li-main">
                      <div className="chat-li-name">{f.meta.name}{unread > 0 && <span className="unread-dot">{unread}</span>}</div>
                      <div className="chat-li-last dim">{last ? (last.from === "me" || last.from_id === authUser?.id ? "You: " : "") + last.text : "Say hi"}</div>
                    </div>
                  </button>
                );
              })}
            </div>
            <div className="chat-pane">
              {af && (
                <div className="chat-head">
                  <Avatar profile={af} size={34} />
                  <div>
                    <div className="chat-head-name">{af.meta.name}</div>
                    <div className="mono dim chat-head-sub">
                      {af._isRealUser
                        ? `Lv ${af._level} · ⚡${af._power}`
                        : `Lv ${P.profileLevel(af).level} · ⚡${P.power(af, today)}`}
                    </div>
                  </div>
                  {af._isRealUser && (
                    <span className="me-tag" style={{ marginLeft: "auto" }}>REAL</span>
                  )}
                </div>
              )}
              <div className="chat-body">
                {loadingCloud && <div className="empty">Loading…</div>}
                {!loadingCloud && thread.length === 0 && <Empty>No messages yet — break the ice.</Empty>}
                {thread.map((m, i) => (
                  <div key={m.id || i} className={"bubble " + (m.from === "me" || (authUser && m.from_id === authUser.id) ? "mine" : "theirs")}>{m.text}</div>
                ))}
              </div>
              <ChatInput onSend={send} />
            </div>
          </div>
        )
      ) : (
        <div className="activity">
          {notifications.length === 0 && <Empty>No activity yet.</Empty>}
          {notifications.map((n) => {
            const f = friendById(n.friendId || n.from_user_id);
            return (
              <div className="act-row" key={n.id}>
                {f && <Avatar profile={f} size={38} />}
                <div className="act-main">
                  <div className="act-text"><b>{f ? f.meta.name : "Someone"}</b> {n.text} {n.icon && <span className="act-ico">{n.icon}</span>}</div>
                  <div className="act-time mono dim">{timeAgo(n.ts || (n.created_at ? new Date(n.created_at).getTime() : Date.now()), today)}</div>
                </div>
                <div className="act-react">
                  {n.emoji ? <span className="react-given">{n.emoji}</span> : REACT_EMOJI.map((e) => <button key={e} className="react-btn" onClick={() => react(n.id, e)}>{e}</button>)}
                </div>
              </div>
            );
          })}
        </div>
      )}

      {showAddFriend && authUser && (
        <AddFriendModal
          myId={authUser.id}
          onClose={() => setShowAddFriend(false)}
          onAdded={() => {
            Bridge.getFriends(authUser.id).then(({ data }) => {
              if (data) {
                const realFriends = data.map(Bridge.buildFriendProfile);
                setState(s => ({ ...s, realFriends }));
              }
            });
          }}
        />
      )}
    </div>
  );
}

function ChatInput({ onSend }) {
  const [v, setV] = useState("");
  return (
    <form className="chat-input" onSubmit={(e) => { e.preventDefault(); onSend(v); setV(""); }}>
      <input className="inp" value={v} placeholder="Message…" onChange={(e) => setV(e.target.value)} />
      <button className="btn btn-accent" type="submit">Send</button>
    </form>
  );
}

function timeAgo(ts, today) {
  const diff = Date.now() - ts;
  const h = Math.floor(diff / 3600000);
  if (h < 1) return Math.max(1, Math.floor(diff / 60000)) + "m ago";
  if (h < 24) return h + "h ago";
  return Math.floor(h / 24) + "d ago";
}

Object.assign(window, { Messages, REACT_EMOJI, timeAgo });
