import { useEffect, useState } from "react";
import { useServerStore } from "../stores/server.ts";
import { useAuthStore } from "../stores/auth.ts";
import { useMemberStore, type Member } from "../stores/member.ts";
import { usePresenceStore } from "../stores/presence.ts";
import type { UserStatus } from "../stores/auth.ts";
import { MemberContextMenu } from "./MemberContextMenu.tsx";
import { useConversationStore } from "../stores/conversation.ts";
import { useLayoutStore } from "../stores/layout.ts";
import { useNavigate } from "react-router-dom";

function statusIcon(status: UserStatus): string {
  switch (status) {
    case "online":
      return "\u25cf";
    case "idle":
      return "\u25d0";
    case "dnd":
      return "\u26d5";
    default:
      return "\u25cb";
  }
}

function statusColor(status: UserStatus): string {
  switch (status) {
    case "online":
      return "text-gb-green";
    case "idle":
      return "text-gb-yellow";
    case "dnd":
      return "text-gb-red";
    default:
      return "text-gb-gray";
  }
}

function usernameColor(status: UserStatus): string {
  switch (status) {
    case "online":
      return "text-gb-aqua";
    case "idle":
      return "text-gb-yellow";
    case "dnd":
      return "text-gb-red";
    default:
      return "text-gb-fg-f";
  }
}

function MemberRow({ member }: { member: Member }) {
  const presence = usePresenceStore((s) => s.presences[member.id]);
  const status = presence?.status ?? member.status;
  const [menuOpen, setMenuOpen] = useState(false);
  const currentUser = useAuthStore((s) => s.user);
  const userPerms = useServerStore((s) => s.userPermissions);
  const activeServerId = useServerStore((s) => s.activeServerId);
  const setActiveServer = useServerStore((s) => s.setActiveServer);
  const createConversation = useConversationStore((s) => s.createConversation);
  const setDM = useLayoutStore((s) => s.setDM);
  const navigate = useNavigate();

  const canKick = userPerms?.kick_members ?? false;
  const canBan = userPerms?.ban_members ?? false;
  const canMute = userPerms?.mute_members ?? false;
  const isSelf = currentUser?.id === member.id;

  return (
    <div className="relative">
      <button
        onClick={() => setMenuOpen((v) => !v)}
        className="w-full flex items-center gap-2 px-2 py-1 text-left hover:bg-gb-bg-t"
      >
        <span className={statusColor(status)}>{statusIcon(status)}</span>
        <span className={`truncate ${usernameColor(status)}`}>
          {member.display_name || member.username}
        </span>
        <span className="ml-auto text-gb-fg-f text-xs">[...]</span>
      </button>
      {menuOpen && !isSelf && activeServerId && (
        <MemberContextMenu
          memberId={member.id}
          username={member.username}
          canKick={canKick}
          canBan={canBan}
          canMute={canMute}
          onMessage={async () => {
            try {
              const conv = await createConversation([member.id]);
              setMenuOpen(false);
              setActiveServer(null);
              setDM(true);
              navigate(`/dm/${conv.id}`);
            } catch (err) {
              console.error("Failed to start DM:", err);
            }
          }}
          onKick={(_reason) => {
            fetch(`/api/v1/servers/${activeServerId}/members/${member.id}`, { method: "DELETE", credentials: "include" })
              .then(() => setMenuOpen(false));
          }}
          onBan={(reason) => {
            fetch(`/api/v1/servers/${activeServerId}/bans`, {
              method: "POST",
              credentials: "include",
              headers: { "Content-Type": "application/json" },
              body: JSON.stringify({ user_id: member.id, reason }),
            }).then(() => setMenuOpen(false));
          }}
          onMute={(duration, reason) => {
            fetch(`/api/v1/servers/${activeServerId}/mutes`, {
              method: "POST",
              credentials: "include",
              headers: { "Content-Type": "application/json" },
              body: JSON.stringify({ user_id: member.id, duration, reason }),
            }).then(() => setMenuOpen(false));
          }}
          onClose={() => setMenuOpen(false)}
        />
      )}
    </div>
  );
}

export function MemberList() {
  const activeServerId = useServerStore((s) => s.activeServerId);
  const membersByServer = useMemberStore((s) => s.membersByServer);
  const fetchMembers = useMemberStore((s) => s.fetchMembers);
  const presences = usePresenceStore((s) => s.presences);

  const members = activeServerId
    ? membersByServer[activeServerId] || []
    : [];

  useEffect(() => {
    if (activeServerId) {
      fetchMembers(activeServerId);
    }
  }, [activeServerId, fetchMembers]);

  const online = members.filter((m) => {
    const status = presences[m.id]?.status ?? m.status;
    return status !== "offline";
  });
  const offline = members.filter((m) => {
    const status = presences[m.id]?.status ?? m.status;
    return status === "offline";
  });

  return (
    <div className="h-full w-52 bg-gb-bg-s border-l border-gb-bg-t flex flex-col">
      <div className="terminal-border border-t-0 border-x-0 px-3 py-2 text-gb-fg-s">
        [MEMBERS]
      </div>
      <div className="flex-1 overflow-y-auto p-2 font-mono text-sm">
        {!activeServerId && (
          <p className="text-gb-fg-f">[select a server]</p>
        )}
        {activeServerId && members.length === 0 && (
          <p className="text-gb-fg-f">[no members]</p>
        )}
        {online.length > 0 && (
          <div className="mb-3">
            <div className="text-gb-fg-t text-xs uppercase mb-1">ONLINE</div>
            <div className="text-gb-fg-f text-xs mb-1">---</div>
            {online.map((m) => (
              <MemberRow key={m.id} member={m} />
            ))}
          </div>
        )}
        {offline.length > 0 && (
          <div>
            <div className="text-gb-fg-t text-xs uppercase mb-1">OFFLINE</div>
            <div className="text-gb-fg-f text-xs mb-1">---</div>
            {offline.map((m) => (
              <MemberRow key={m.id} member={m} />
            ))}
          </div>
        )}
      </div>
    </div>
  );
}
