import { useEffect, useState, useMemo } from 'react';
import { useParams } from 'react-router-dom';
import { Avatar } from '@/components/channel/Avatar';
import { useRoom } from '@/contexts/room';
import { projectMembersGrouped, projectInfo, projectPresence } from '@/client/api';
import type { MemberGroup } from '@/client/model';
import type { PresenceStatus } from '@/client/model';

const STATUS_COLORS: Record<string, string> = {
  online: 'var(--status-online)',
  idle: 'var(--status-idle)',
  dnd: 'var(--status-dnd)',
  offline: 'var(--status-offline)',
};

const ROLE_COLORS: Record<string, string> = {
  owner: 'var(--role-red)',
  admin: 'var(--role-orange)',
  member: 'var(--role-blue)',
};

function useRoomSafe() {
  try {
    return useRoom();
  } catch {
    return null;
  }
}

export function MemberList() {
  const { projectName } = useParams<{ projectName: string }>();
  const room = useRoomSafe();

  const [groups, setGroups] = useState<MemberGroup[]>([]);
  const [total, setTotal] = useState(0);
  const [loading, setLoading] = useState(true);
  const [apiPresence, setApiPresence] = useState<Map<string, PresenceStatus>>(new Map());

  // Fetch project presence from API
  useEffect(() => {
    if (!projectName) {
      setApiPresence(new Map());
      return;
    }

    let cancelled = false;

    // First get project info to get project_id, then fetch presence
    projectInfo(projectName)
      .then((infoRes) => {
        if (cancelled) return;
        const projectId = infoRes.data?.data?.uid;
        if (!projectId) return;
        return projectPresence(projectId);
      })
      .then((presenceRes) => {
        if (cancelled || !presenceRes) return;
        const presenceMap = new Map<string, PresenceStatus>();
        for (const p of presenceRes.data?.data || []) {
          presenceMap.set(p.user_id, p.status);
        }
        setApiPresence(presenceMap);
      })
      .catch((err) => {
        if (cancelled) return;
        console.error('[MemberList] failed to load project presence:', err);
        setApiPresence(new Map());
      });

    return () => { cancelled = true; };
  }, [projectName]);

  // Build a map of uid -> presence from room context + API presence
  const presenceMap = useMemo(() => {
    const map = new Map<string, string>();

    // First, add presence from room context (from WebSocket real-time updates)
    if (room) {
      for (const m of room.members) {
        map.set(m.uid, m.presence);
      }
    }

    // Then, override with API-fetched presence (authoritative data)
    for (const [userId, status] of apiPresence) {
      map.set(userId, status);
    }

    return map;
  }, [room, apiPresence]);

  useEffect(() => {
    if (!projectName) {
      setGroups([]);
      setTotal(0);
      setLoading(false);
      return;
    }

    let cancelled = false;
    setLoading(true);

    projectMembersGrouped(projectName)
      .then((res) => {
        if (cancelled) return;
        const data = res.data.data;
        setGroups(data?.groups ?? []);
        setTotal(data?.total ?? 0);
      })
      .catch((err) => {
        if (cancelled) return;
        console.error('[MemberList] failed to load project members:', err);
        setGroups([]);
        setTotal(0);
      })
      .finally(() => {
        if (!cancelled) setLoading(false);
      });

    return () => { cancelled = true; };
  }, [projectName]);

  // Loading state
  if (loading) {
    return (
      <div
        className="flex flex-col items-center justify-center h-full w-[240px]"
        style={{ backgroundColor: 'var(--surface-sidebar)' }}
      >
        <div className="w-5 h-5 rounded-full border-2 border-t-transparent animate-spin" style={{ borderColor: 'var(--text-muted)', borderTopColor: 'transparent' }} />
      </div>
    );
  }

  // No project selected or no members
  if (groups.length === 0) {
    return (
      <div
        className="flex flex-col items-center justify-center h-full w-[240px]"
        style={{ backgroundColor: 'var(--surface-sidebar)' }}
      >
        <p className="text-[12px]" style={{ color: 'var(--text-muted)' }}>
          {projectName ? 'No members' : 'Select a project'}
        </p>
      </div>
    );
  }

  // Real project members
  return (
    <div
      className="flex flex-col h-full w-[240px] pt-4 px-2 overflow-y-auto"
      style={{ backgroundColor: 'var(--surface-sidebar)' }}
    >
      <div
        className="px-2 py-2 text-[11px] font-semibold uppercase tracking-wider"
        style={{ color: 'var(--text-muted)' }}
      >
        Members — {total}
      </div>

      {groups.map((g) => {
        const color = ROLE_COLORS[g.role.toLowerCase()] || 'var(--role-gray)';
        return (
          <div key={g.role} className="mb-2">
            <div
              className="flex items-center px-2 py-1 text-[11px] font-semibold uppercase tracking-wider"
              style={{ color: 'var(--text-muted)' }}
            >
              <span style={{ color }}>{g.role}</span>
              <span className="ml-1">— {g.members.length}</span>
            </div>

            {g.members.map((m) => {
              const presence = presenceMap.get(m.user_id) || 'offline';
              const isOffline = presence === 'offline';
              return (
                <button
                  key={m.user_id}
                  className={`flex items-center gap-3 px-2 py-1.5 rounded-[4px] transition-colors cursor-pointer w-full text-left ${
                    isOffline ? 'opacity-40' : ''
                  }`}
                  style={{ color: 'var(--text-primary)' }}
                >
                  <div style={{ position: 'relative', flexShrink: 0 }}>
                    <Avatar
                      senderType="user"
                      displayName={m.username}
                      avatarUrl={m.avatar_url}
                      roleColor={color}
                      size={32}
                    />
                    <div
                      className="absolute -bottom-0.5 -right-0.5 w-3.5 h-3.5 rounded-full border-[3px]"
                      style={{
                        backgroundColor: STATUS_COLORS[presence] || STATUS_COLORS.offline,
                        borderColor: 'var(--surface-sidebar)',
                      }}
                    />
                  </div>

                  <div className="min-w-0">
                    <p className="text-[13px] font-medium truncate" style={{ color }}>
                      {m.username}
                    </p>
                    {m.display_name && (
                      <p className="text-[11px] truncate" style={{ color: 'var(--text-muted)' }}>
                        {m.display_name}
                      </p>
                    )}
                  </div>
                </button>
              );
            })}
          </div>
        );
      })}
    </div>
  );
}
