import React, { useCallback, useEffect, useState } from 'react';
import {
  View, Text, FlatList, StyleSheet,
  ActivityIndicator, RefreshControl,
} from 'react-native';
import { colors } from '../../theme/colors';
import { typography } from '../../theme/typography';
import { spacing } from '../../theme/spacing';
import { Card } from '../../components/ui';
import { api } from '../../services/api';

type CallStatus = 'COMPLETED' | 'ANSWERED' | 'FAILED' | 'NO_ANSWER' | 'BUSY';

interface CallClient {
  id: string;
  firstName: string;
  lastName: string;
  phone: string;
}

interface CallCaller {
  id: string;
  firstName: string;
  lastName: string;
}

interface CallEntry {
  id: string;
  callerNumber: string;
  calleeNumber: string;
  status: CallStatus;
  startedAt: string;
  duration: number;
  client: CallClient | null;
  caller: CallCaller | null;
}

interface CallLogResponse {
  data: CallEntry[];
  nextCursor: string | null;
  hasMore: boolean;
}

interface CallStats {
  totalCalls: number;
  answeredCalls: number;
  missedCalls: number;
  averageDuration: number;
  answeredRate: number;
}

function getCallStatusColor(status: CallStatus): string {
  const map: Record<CallStatus, string> = {
    COMPLETED: colors.success,
    ANSWERED: colors.success,
    FAILED: colors.error,
    NO_ANSWER: colors.warning,
    BUSY: '#FBC02D',
  };
  return map[status];
}

const STATUS_LABELS: Record<CallStatus, string> = {
  COMPLETED: 'Завершён',
  ANSWERED: 'Отвечен',
  FAILED: 'Ошибка',
  NO_ANSWER: 'Нет ответа',
  BUSY: 'Занято',
};

function formatDuration(seconds: number): string {
  if (seconds <= 0) return '0 сек';
  const minutes = Math.floor(seconds / 60);
  const secs = seconds % 60;
  if (minutes === 0) return `${secs} сек`;
  if (secs === 0) return `${minutes} мин`;
  return `${minutes} мин ${secs} сек`;
}

function formatTime(iso: string): string {
  return new Date(iso).toLocaleString('ru-RU', {
    day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit',
  });
}

const PAGE_LIMIT = 20;

export function CallLogScreen(): React.JSX.Element {
  const styles = createStyles();
  const [calls, setCalls] = useState<CallEntry[]>([]);
  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 [stats, setStats] = useState<CallStats | null>(null);

  const fetchCalls = useCallback(async (nextCursor?: string) => {
    const params: Record<string, string | number> = { limit: PAGE_LIMIT };
    if (nextCursor) params.cursor = nextCursor;
    return api.get<CallLogResponse>('/sip/calls', { params });
  }, []);

  const fetchStats = useCallback(async () => {
    try {
      const data = await api.get<CallStats>('/sip/calls/stats');
      setStats(data);
    } catch {
      // Stats are non-critical, keep null
    }
  }, []);

  const applyResponse = (response: CallLogResponse) => {
    setCursor(response.nextCursor);
    setHasMore(response.hasMore);
  };

  const loadInitial = useCallback(async () => {
    setIsLoading(true);
    try {
      const response = await fetchCalls();
      setCalls(response.data);
      applyResponse(response);
    } catch {
      setCalls([]);
      setCursor(null);
      setHasMore(false);
    } finally {
      setIsLoading(false);
    }
  }, [fetchCalls]);

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

  const handleRefresh = useCallback(async () => {
    setIsRefreshing(true);
    try {
      const [response] = await Promise.all([fetchCalls(), fetchStats()]);
      setCalls(response.data);
      applyResponse(response);
    } catch {
      // Keep existing data on refresh failure
    } finally {
      setIsRefreshing(false);
    }
  }, [fetchCalls, fetchStats]);

  const handleLoadMore = useCallback(async () => {
    if (!hasMore || isLoadingMore || !cursor) return;
    setIsLoadingMore(true);
    try {
      const response = await fetchCalls(cursor);
      setCalls((prev) => [...prev, ...response.data]);
      applyResponse(response);
    } catch {
      // User can scroll again to retry
    } finally {
      setIsLoadingMore(false);
    }
  }, [hasMore, isLoadingMore, cursor, fetchCalls]);

  const renderStatsBanner = () => {
    if (!stats) return null;
    return (
      <View style={styles.statsBanner}>
        <View style={styles.statItem}>
          <Text style={styles.statValue}>{stats.totalCalls}</Text>
          <Text style={styles.statLabel}>Всего</Text>
        </View>
        <View style={styles.statDivider} />
        <View style={styles.statItem}>
          <Text style={[styles.statValue, { color: colors.success }]}>
            {stats.answeredRate.toFixed(0)}%
          </Text>
          <Text style={styles.statLabel}>Отвечено</Text>
        </View>
        <View style={styles.statDivider} />
        <View style={styles.statItem}>
          <Text style={styles.statValue}>{formatDuration(stats.averageDuration)}</Text>
          <Text style={styles.statLabel}>Средняя</Text>
        </View>
      </View>
    );
  };

  const getClientDisplay = (item: CallEntry): string => {
    if (item.client) return `${item.client.lastName} ${item.client.firstName}`;
    return item.calleeNumber;
  };

  const renderItem = useCallback(
    ({ item }: { item: CallEntry }) => {
      const statusColor = getCallStatusColor(item.status) ?? colors.textMuted;
      const statusLabel = STATUS_LABELS[item.status] ?? item.status;

      return (
        <Card style={styles.card}>
          <View style={styles.cardHeader}>
            <Text style={styles.clientName} numberOfLines={1}>
              {getClientDisplay(item)}
            </Text>
            <View style={[styles.statusBadge, { backgroundColor: statusColor }]}>
              <Text style={styles.statusText}>{statusLabel}</Text>
            </View>
          </View>
          <View style={styles.cardFooter}>
            <Text style={styles.timeText}>{formatTime(item.startedAt)}</Text>
            <Text style={styles.durationText}>{formatDuration(item.duration)}</Text>
          </View>
        </Card>
      );
    },
    [],
  );

  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}>Нет звонков</Text>
        <Text style={styles.emptySubtitle}>
          История звонков появится здесь после первого вызова
        </Text>
      </View>
    );
  }, [isLoading]);

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Журнал звонков</Text>
      {renderStatsBanner()}
      {isLoading && calls.length === 0 ? (
        <View style={styles.loadingContainer}>
          <ActivityIndicator size="large" color={colors.primary} />
        </View>
      ) : (
        <FlatList
          data={calls}
          keyExtractor={(item) => item.id}
          renderItem={renderItem}
          contentContainerStyle={styles.listContent}
          ListEmptyComponent={renderEmpty}
          ListFooterComponent={renderFooter}
          onEndReached={handleLoadMore}
          onEndReachedThreshold={0.3}
          refreshControl={
            <RefreshControl
              refreshing={isRefreshing}
              onRefresh={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.md },
  statsBanner: { flexDirection: 'row', backgroundColor: colors.white, marginHorizontal: spacing.lg, borderRadius: 12, paddingVertical: spacing.lg, paddingHorizontal: spacing.md, marginBottom: spacing.md, alignItems: 'center' },
  statItem: { flex: 1, alignItems: 'center' },
  statValue: { ...typography.subtitle, color: colors.text, marginBottom: spacing.xs },
  statLabel: { ...typography.caption, color: colors.textMuted },
  statDivider: { width: 1, height: 32, backgroundColor: colors.border },
  listContent: { padding: spacing.lg, paddingTop: spacing.sm, flexGrow: 1 },
  loadingContainer: { flex: 1, alignItems: 'center', justifyContent: 'center' },
  card: { marginBottom: spacing.md },
  cardHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: spacing.sm },
  clientName: { ...typography.subtitle, color: colors.text, flex: 1, marginRight: spacing.sm },
  statusBadge: { borderRadius: 12, paddingHorizontal: spacing.md, paddingVertical: spacing.xs },
  statusText: { ...typography.caption, fontWeight: '700', color: colors.white },
  cardFooter: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' },
  timeText: { ...typography.caption, color: colors.textMuted },
  durationText: { ...typography.bodySmall, color: colors.textSecondary },
  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' },
});
