import { useCallback, useState } from 'react';
import {
  ActivityIndicator,
  FlatList,
  Pressable,
  RefreshControl,
  Text,
  View,
} from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { Plus } from 'lucide-react-native';
import { toast } from 'sonner-native';
import type { Invitation, Network } from '@/api/types';
import { useNetworks } from '@/hooks/use-networks';
import { useAcceptInvitation, useMyInvitations } from '@/hooks/use-invitations';
import { useAuthStore } from '@/stores/auth-store';
import { toUserMessage } from '@/lib/errors';
import type { RootStackScreenProps } from '@/navigation/types';
import { FlowyLogo } from '@/components/FlowyLogo';
import { ListSeparator } from '@/components/ListSeparator';
import { Drawer } from './Drawer';
import { CreateNetworkSheet } from './CreateNetworkSheet';

export function NetworkListScreen({
  navigation,
}: RootStackScreenProps<'NetworkList'>) {
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [createOpen, setCreateOpen] = useState(false);
  const { data, isLoading, refetch, error } = useNetworks();
  const { data: invitations, refetch: refetchInvitations } = useMyInvitations();
  const user = useAuthStore((s) => s.user);
  const initials = user?.email_prefix.slice(0, 2).toUpperCase() ?? '??';

  // Local refreshing state — driving RefreshControl from react-query's
  // isRefetching can leave the native spinner visually stuck after the
  // screen is detached/reattached by native-stack.
  const [refreshing, setRefreshing] = useState(false);
  const onRefresh = useCallback(async () => {
    setRefreshing(true);
    try {
      await Promise.all([refetch(), refetchInvitations()]);
    } finally {
      setRefreshing(false);
    }
  }, [refetch, refetchInvitations]);

  const pendingInvitations = invitations ?? [];

  return (
    <SafeAreaView className="flex-1 bg-background" edges={['top']}>
      <View className="flex-row items-center justify-between px-4 py-3 border-b border-border">
        <Pressable
          onPress={() => setDrawerOpen(true)}
          accessibilityLabel="Open menu"
          className="bg-muted h-9 w-9 items-center justify-center rounded-full"
        >
          <Text className="text-muted-foreground text-xs font-semibold">
            {initials}
          </Text>
        </Pressable>
        <FlowyLogo />
        <Pressable
          onPress={() => setCreateOpen(true)}
          accessibilityLabel="Create network"
          className="bg-muted h-9 w-9 items-center justify-center rounded-full"
        >
          <Plus size={18} color="#fafafa" />
        </Pressable>
      </View>

      {isLoading ? (
        <View className="flex-1 items-center justify-center">
          <ActivityIndicator />
        </View>
      ) : error ? (
        <View className="flex-1 items-center justify-center px-6">
          <Text className="text-destructive text-center">
            {toUserMessage(error)}
          </Text>
          <Pressable onPress={() => refetch()} className="mt-3 px-4 py-2">
            <Text className="text-foreground font-medium">Retry</Text>
          </Pressable>
        </View>
      ) : (!data || data.length === 0) && pendingInvitations.length === 0 ? (
        <EmptyState onCreate={() => setCreateOpen(true)} />
      ) : (
        <FlatList
          data={data ?? []}
          keyExtractor={(item) => item.id}
          refreshControl={
            <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
          }
          ItemSeparatorComponent={ListSeparator}
          ListHeaderComponent={
            pendingInvitations.length > 0 ? (
              <InvitationsSection invitations={pendingInvitations} />
            ) : null
          }
          renderItem={({ item }) => (
            <NetworkCard
              network={item}
              onPress={() =>
                navigation.navigate('StreamList', { networkId: item.id })
              }
            />
          )}
        />
      )}

      <Drawer
        open={drawerOpen}
        onClose={() => setDrawerOpen(false)}
        onNavigateAccount={() => navigation.navigate('Account')}
        onNavigateSettings={() => navigation.navigate('Settings')}
      />

      <CreateNetworkSheet
        open={createOpen}
        onClose={() => setCreateOpen(false)}
        onCreated={(networkId) =>
          navigation.navigate('StreamList', { networkId })
        }
      />
    </SafeAreaView>
  );
}

function InvitationsSection({ invitations }: { invitations: Invitation[] }) {
  return (
    <View className="border-b border-border">
      <Text className="text-muted-foreground text-xs uppercase tracking-wide px-4 pt-4 pb-1">
        Invitations
      </Text>
      {invitations.map((invitation) => (
        <InvitationCard key={invitation.network_id} invitation={invitation} />
      ))}
    </View>
  );
}

function InvitationCard({ invitation }: { invitation: Invitation }) {
  const acceptInvitation = useAcceptInvitation();

  const handleAccept = async () => {
    try {
      await acceptInvitation.mutateAsync(invitation.network_id);
    } catch (err) {
      toast.error(toUserMessage(err));
    }
  };

  return (
    <View className="flex-row items-center justify-between px-4 py-4">
      <View className="flex-1 pr-3">
        <Text className="text-foreground text-base font-semibold">
          {invitation.network_name}
        </Text>
        <Text className="text-muted-foreground text-sm">
          You’ve been invited to join
        </Text>
      </View>
      <Pressable
        onPress={handleAccept}
        disabled={acceptInvitation.isPending}
        className="bg-primary rounded-full px-4 py-2"
      >
        <Text className="text-primary-foreground text-sm font-semibold">
          {acceptInvitation.isPending ? 'Joining…' : 'Accept'}
        </Text>
      </Pressable>
    </View>
  );
}

function NetworkCard({
  network,
  onPress,
}: {
  network: Network;
  onPress: () => void;
}) {
  return (
    <Pressable
      onPress={onPress}
      className="active:bg-accent flex-row items-center justify-between px-4 py-4"
    >
      <View className="flex-1">
        <Text className="text-foreground text-base font-semibold">
          {network.name}
        </Text>
        <Text className="text-muted-foreground text-sm">
          {network.humans.length}{' '}
          {network.humans.length === 1 ? 'member' : 'members'}
        </Text>
      </View>
      <Text className="text-muted-foreground text-xl">›</Text>
    </Pressable>
  );
}

function EmptyState({ onCreate }: { onCreate: () => void }) {
  return (
    <View className="flex-1 items-center justify-center px-6">
      <Text className="text-foreground text-lg font-medium text-center">
        You aren’t in any networks yet.
      </Text>
      <Text className="text-muted-foreground mt-2 text-center">
        Create one to get started, or ask a friend for an invite.
      </Text>
      <Pressable
        onPress={onCreate}
        className="bg-primary rounded-full px-5 py-3 mt-6"
      >
        <Text className="text-primary-foreground font-semibold">
          Create a network
        </Text>
      </Pressable>
    </View>
  );
}
