'use client';

import { LeagueMemberRow } from '@/components/leagues/LeagueMemberRow';
import { LeagueMemberTable } from '@/components/leagues/LeagueMemberTable';
import { EmptyState } from '@/ui/EmptyState';
import { LoadingWrapper } from '@/ui/LoadingWrapper';
import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId';
import { useInject } from '@/lib/di/hooks/useInject';
import { DRIVER_SERVICE_TOKEN, LEAGUE_MEMBERSHIP_SERVICE_TOKEN } from '@/lib/di/tokens';
import { routes } from '@/lib/routing/RouteConfig';
import type { LeagueMembership } from '@/lib/types/LeagueMembership';
import type { MembershipRole } from '@/lib/types/MembershipRole';
import { DriverViewModel } from '@/lib/view-models/DriverViewModel';
import { Button } from '@/ui/Button';
import { Select } from '@/ui/Select';
import { Text } from '@/ui/Text';
import { Box } from '@/ui/Box';
import { Group } from '@/ui/Group';
import { ControlBar } from '@/ui/ControlBar';
import React, { useCallback, useEffect, useState } from 'react';

interface LeagueMembersProps {
  leagueId: string;
  onRemoveMember?: (driverId: string) => void;
  onUpdateRole?: (driverId: string, role: MembershipRole) => void;
  showActions?: boolean;
}

export function LeagueMembers({
  leagueId,
  onRemoveMember,
  onUpdateRole,
  showActions = false
}: LeagueMembersProps) {
  const [members, setMembers] = useState<LeagueMembership[]>([]);
  const [driversById, setDriversById] = useState<Record<string, DriverViewModel>>({});
  const [loading, setLoading] = useState(true);
  const [sortBy, setSortBy] = useState<'role' | 'name' | 'date' | 'rating' | 'points' | 'wins'>('rating');
  const currentDriverId = useEffectiveDriverId();
  const leagueMembershipService = useInject(LEAGUE_MEMBERSHIP_SERVICE_TOKEN);
  const driverService = useInject(DRIVER_SERVICE_TOKEN);

  const loadMembers = useCallback(async () => {
    setLoading(true);
    try {
      await leagueMembershipService.fetchLeagueMemberships(leagueId);
      const membershipData = leagueMembershipService.getLeagueMembers(leagueId);
      setMembers(membershipData);

      const uniqueDriverIds = Array.from(new Set(membershipData.map((m: LeagueMembership) => m.driverId)));
      if (uniqueDriverIds.length > 0) {
        const result = await driverService.findByIds(uniqueDriverIds);
        if (result.isOk()) {
          const driverDtos = result.unwrap();
          const byId: Record<string, DriverViewModel> = {};
          for (const dto of driverDtos) {
            byId[dto.id] = new DriverViewModel({ ...dto, avatarUrl: dto.avatarUrl ?? null });
          }
          setDriversById(byId);
        }
      } else {
        setDriversById({});
      }
    } catch (error) {
      console.error('Failed to load members:', error);
    } finally {
      setLoading(false);
    }
  }, [leagueId, leagueMembershipService, driverService]);

  useEffect(() => {
    loadMembers();
  }, [loadMembers]);

  const getDriverName = (driverId: string): string => {
    const driver = driversById[driverId];
    return driver?.name || 'Unknown Driver';
  };

  const getRoleOrder = (role: MembershipRole): number => {
    const order: Record<MembershipRole, number> = { owner: 0, admin: 1, steward: 2, member: 3 };
    return order[role];
  };

  const getDriverStats = (): { rating: number; wins: number; overallRank: number } | null => {
    return null;
  };

  const sortedMembers = [...members].sort((a, b) => {
    switch (sortBy) {
      case 'role':
        return getRoleOrder(a.role) - getRoleOrder(b.role);
      case 'name':
        return getDriverName(a.driverId).localeCompare(getDriverName(b.driverId));
      case 'date':
        return new Date(b.joinedAt).getTime() - new Date(a.joinedAt).getTime();
      case 'rating': {
        const statsA = getDriverStats();
        const statsB = getDriverStats();
        return (statsB?.rating || 0) - (statsA?.rating || 0);
      }
      case 'points':
        return 0;
      case 'wins': {
        const statsA = getDriverStats();
        const statsB = getDriverStats();
        return (statsB?.wins || 0) - (statsA?.wins || 0);
      }
      default:
        return 0;
    }
  });

  const getRoleVariant = (role: MembershipRole): 'default' | 'primary' | 'success' | 'warning' | 'danger' | 'info' => {
    switch (role) {
      case 'owner': return 'warning';
      case 'admin': return 'primary';
      case 'steward': return 'info';
      case 'member': return 'primary';
      default: return 'default';
    }
  };

  if (loading) {
    return <LoadingWrapper variant="spinner" message="Loading members..." />;
  }

  if (members.length === 0) {
    return (
      <EmptyState
        title="No members found"
        description="This league doesn't have any members yet."
        variant="minimal"
      />
    );
  }

  return (
    <Box>
      <ControlBar
        leftContent={
          <Text size="sm" variant="low">
            {members.length} {members.length === 1 ? 'member' : 'members'}
          </Text>
        }
      >
        <Group gap={2}>
          <Text size="sm" variant="low">Sort by:</Text>
          <Select
            value={sortBy}
            onChange={(e: React.ChangeEvent<HTMLSelectElement>) => setSortBy(e.target.value as typeof sortBy)}
            options={[
              { value: 'rating', label: 'Rating' },
              { value: 'points', label: 'Points' },
              { value: 'wins', label: 'Wins' },
              { value: 'role', label: 'Role' },
              { value: 'name', label: 'Name' },
              { value: 'date', label: 'Join Date' },
            ]}
            fullWidth={false}
          />
        </Group>
      </ControlBar>

      <Box overflowX="auto" marginTop={4}>
        <LeagueMemberTable showActions={showActions}>
          {sortedMembers.map((member, index) => {
            const isCurrentUser = member.driverId === currentDriverId;
            const cannotModify = member.role === 'owner';
            const driverStats = getDriverStats();
            const isTopPerformer = index < 3 && sortBy === 'rating';
            const driver = driversById[member.driverId];
            const ratingAndWinsMeta =
              driverStats && typeof driverStats.rating === 'number'
                ? `Rating ${driverStats.rating} • ${driverStats.wins ?? 0} wins`
                : null;

            return (
              <LeagueMemberRow
                key={member.driverId}
                driver={driver}
                driverId={member.driverId}
                isCurrentUser={isCurrentUser}
                isTopPerformer={isTopPerformer}
                role={member.role}
                roleVariant={getRoleVariant(member.role)}
                joinedAt={member.joinedAt}
                rating={driverStats?.rating}
                rank={driverStats?.overallRank}
                wins={driverStats?.wins}
                href={routes.driver.detail(member.driverId)}
                meta={ratingAndWinsMeta}
                actions={showActions && !cannotModify && !isCurrentUser ? (
                  <Group gap={2} justify="end">
                    {onUpdateRole && (
                      <Select
                        value={member.role}
                        onChange={(e: React.ChangeEvent<HTMLSelectElement>) => onUpdateRole(member.driverId, e.target.value as MembershipRole)}
                        options={[
                          { value: 'member', label: 'Member' },
                          { value: 'steward', label: 'Steward' },
                          { value: 'admin', label: 'Admin' },
                        ]}
                        fullWidth={false}
                      />
                    )}
                    {onRemoveMember && (
                      <Button
                        variant="ghost"
                        onClick={() => onRemoveMember(member.driverId)}
                        size="sm"
                      >
                        <Text variant="critical">Remove</Text>
                      </Button>
                    )}
                  </Group>
                ) : (showActions && cannotModify ? <Text size="xs" variant="low">—</Text> : undefined)}
              />
            );
          })}
        </LeagueMemberTable>
      </Box>
    </Box>
  );
}
