import React, { useCallback, useEffect, useState } from 'react';
import {
  View,
  Text,
  FlatList,
  StyleSheet,
  ActivityIndicator,
  RefreshControl,
  TouchableOpacity,
  Linking,
} from 'react-native';
import type { NativeStackScreenProps } from '@react-navigation/native-stack';
import { colors } from '../../theme/colors';
import { typography } from '../../theme/typography';
import { spacing } from '../../theme/spacing';
import { Card, Input } from '../../components/ui';
import { clientsService } from '../../services/clients';
import type { Client } from '../../types/client';
import type { ClientsStackParamList } from './types';

type Props = NativeStackScreenProps<ClientsStackParamList, 'ClientsList'>;

const PAGE_LIMIT = 20;

function formatDate(iso?: string): string {
  if (!iso) return '-';
  return new Date(iso).toLocaleDateString('ru-RU', {
    day: 'numeric',
    month: 'short',
    year: 'numeric',
  });
}

export function ClientsScreen({ navigation }: Props): React.JSX.Element {
  const styles = createStyles();
  const [clients, setClients] = useState<Client[]>([]);
  const [cursor, setCursor] = useState<string | null>(null);
  const [hasMore, setHasMore] = useState(false);
  const [isLoading, setIsLoading] = useState(true);
  const [isRefreshing, setIsRefreshing] = useState(false);
  const [isLoadingMore, setIsLoadingMore] = useState(false);
  const [searchQuery, setSearchQuery] = useState('');
  const [searchTimeout, setSearchTimeoutId] = useState<ReturnType<typeof setTimeout> | null>(null);

  const fetchClients = useCallback(async (query?: string, nextCursor?: string) => {
    const params: { query?: string; cursor?: string; limit: number } = { limit: PAGE_LIMIT };
    if (query && query.length >= 2) params.query = query;
    if (nextCursor) params.cursor = nextCursor;
    return clientsService.getClients(params);
  }, []);

  const loadInitial = useCallback(
    async (query?: string) => {
      setIsLoading(true);
      try {
        const response = await fetchClients(query);
        setClients(response.data);
        setCursor(response.cursor);
        setHasMore(response.hasMore);
      } catch {
        setClients([]);
        setCursor(null);
        setHasMore(false);
      } finally {
        setIsLoading(false);
      }
    },
    [fetchClients],
  );

  useEffect(() => {
    void loadInitial();
  }, [loadInitial]);

  const handleSearch = useCallback(
    (text: string) => {
      setSearchQuery(text);
      if (searchTimeout) clearTimeout(searchTimeout);
      const timeout = setTimeout(() => {
        void loadInitial(text);
      }, 400);
      setSearchTimeoutId(timeout);
    },
    [searchTimeout, loadInitial],
  );

  const handleRefresh = useCallback(async () => {
    setIsRefreshing(true);
    try {
      const response = await fetchClients(searchQuery);
      setClients(response.data);
      setCursor(response.cursor);
      setHasMore(response.hasMore);
    } catch {
      // Keep existing data
    } finally {
      setIsRefreshing(false);
    }
  }, [fetchClients, searchQuery]);

  const handleLoadMore = useCallback(async () => {
    if (!hasMore || isLoadingMore || !cursor) return;
    setIsLoadingMore(true);
    try {
      const response = await fetchClients(searchQuery, cursor);
      setClients((prev) => [...prev, ...response.data]);
      setCursor(response.cursor);
      setHasMore(response.hasMore);
    } catch {
      // User can scroll again
    } finally {
      setIsLoadingMore(false);
    }
  }, [hasMore, isLoadingMore, cursor, fetchClients, searchQuery]);

  const handlePhonePress = useCallback((phone: string) => {
    void Linking.openURL(`tel:${phone}`);
  }, []);

  const renderItem = useCallback(
    ({ item }: { item: Client }) => {
      const initials = `${item.firstName[0] || ''}${item.lastName[0] || ''}`;

      return (
        <TouchableOpacity
          activeOpacity={0.7}
          onPress={() => navigation.navigate('ClientDetail', { clientId: item.id })}
        >
          <Card style={styles.card}>
            <View style={styles.cardRow}>
              <View style={styles.avatar}>
                <Text style={styles.avatarText}>{initials}</Text>
              </View>
              <View style={styles.clientInfo}>
                <Text style={styles.clientName} numberOfLines={1}>
                  {item.lastName} {item.firstName}
                  {item.patronymic ? ` ${item.patronymic}` : ''}
                </Text>
                <TouchableOpacity onPress={() => handlePhonePress(item.phone)}>
                  <Text style={styles.phoneText}>{item.phone}</Text>
                </TouchableOpacity>
                {item.email && (
                  <Text style={styles.emailText} numberOfLines={1}>
                    {item.email}
                  </Text>
                )}
              </View>
              {item.lastActivityAt && (
                <View style={styles.activityBadge}>
                  <Text style={styles.activityText}>{formatDate(item.lastActivityAt)}</Text>
                </View>
              )}
            </View>
          </Card>
        </TouchableOpacity>
      );
    },
    [handlePhonePress, navigation],
  );

  const renderFooter = useCallback(() => {
    if (!isLoadingMore) return null;
    return (
      <View style={styles.footer}>
        <ActivityIndicator size="small" color={colors.primary} />
      </View>
    );
  }, [isLoadingMore]);

  const renderEmpty = useCallback(() => {
    if (isLoading) return null;
    return (
      <View style={styles.emptyContainer}>
        <Text style={styles.emptyTitle}>
          {searchQuery.length >= 2 ? 'Ничего не найдено' : 'Нет клиентов'}
        </Text>
        <Text style={styles.emptySubtitle}>
          {searchQuery.length >= 2
            ? 'Попробуйте изменить поисковый запрос'
            : 'Клиенты появятся здесь после распределения'}
        </Text>
      </View>
    );
  }, [isLoading, searchQuery]);

  return (
    <View style={styles.container}>
      <View style={styles.searchContainer}>
        <Input
          placeholder="Поиск по имени или телефону"
          value={searchQuery}
          onChangeText={handleSearch}
        />
      </View>
      {isLoading && clients.length === 0 ? (
        <View style={styles.loadingContainer}>
          <ActivityIndicator size="large" color={colors.primary} />
        </View>
      ) : (
        <FlatList
          data={clients}
          keyExtractor={(item) => item.id}
          renderItem={renderItem}
          contentContainerStyle={styles.listContent}
          ListEmptyComponent={renderEmpty}
          ListFooterComponent={renderFooter}
          onEndReached={() => void handleLoadMore()}
          onEndReachedThreshold={0.3}
          refreshControl={
            <RefreshControl
              refreshing={isRefreshing}
              onRefresh={() => void handleRefresh()}
              colors={[colors.primary]}
              tintColor={colors.primary}
            />
          }
        />
      )}
    </View>
  );
}

const createStyles = () =>
  StyleSheet.create({
    container: { flex: 1, backgroundColor: colors.background },
    title: {
      ...typography.h2,
      color: colors.text,
      paddingHorizontal: spacing.lg,
      paddingTop: spacing.lg,
      paddingBottom: spacing.sm,
    },
    searchContainer: {
      paddingHorizontal: spacing.lg,
      paddingTop: spacing.md,
      paddingBottom: spacing.md,
    },
    listContent: { padding: spacing.lg, paddingTop: spacing.sm, flexGrow: 1 },
    loadingContainer: { flex: 1, alignItems: 'center', justifyContent: 'center' },
    card: { marginBottom: spacing.md },
    cardRow: {
      flexDirection: 'row',
      alignItems: 'center',
    },
    avatar: {
      width: 48,
      height: 48,
      borderRadius: 24,
      backgroundColor: colors.primaryLight,
      alignItems: 'center',
      justifyContent: 'center',
      marginRight: spacing.md,
    },
    avatarText: {
      ...typography.bodySmall,
      color: colors.white,
      fontWeight: '700',
    },
    clientInfo: {
      flex: 1,
    },
    clientName: {
      ...typography.subtitle,
      color: colors.text,
      marginBottom: 2,
    },
    phoneText: {
      ...typography.bodySmall,
      color: colors.primary,
    },
    emailText: {
      ...typography.caption,
      color: colors.textMuted,
      marginTop: 2,
    },
    activityBadge: {
      marginLeft: spacing.sm,
    },
    activityText: {
      ...typography.caption,
      color: colors.textMuted,
    },
    emptyContainer: {
      flex: 1,
      alignItems: 'center',
      justifyContent: 'center',
      paddingTop: spacing.xxxl * 2,
      paddingHorizontal: spacing.xl,
    },
    emptyTitle: { ...typography.subtitle, color: colors.textSecondary, marginBottom: spacing.sm },
    emptySubtitle: { ...typography.body, color: colors.textMuted, textAlign: 'center' },
    footer: { paddingVertical: spacing.lg, alignItems: 'center' },
  });
