import React, { useCallback, useEffect, useMemo } from 'react';
import {
  View,
  Text,
  FlatList,
  TouchableOpacity,
  StyleSheet,
  RefreshControl,
  ActivityIndicator,
  ScrollView,
} from 'react-native';
import { useNavigation } from '@react-navigation/native';
import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { colors } from '../../theme/colors';
import { typography } from '../../theme/typography';
import { spacing } from '../../theme/spacing';
import { TrainingCard } from '../../components/cards/TrainingCard';
import { useScheduleStore } from '../../stores/schedule.store';
import type { Training } from '../../types/training';
import type { ScheduleStackParamList } from './types';

type NavigationProp = NativeStackNavigationProp<ScheduleStackParamList>;

const DAY_NAMES_SHORT = ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'];
const MONTH_NAMES = [
  'Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь',
  'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь',
];

function formatDateKey(date: Date): string {
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const day = String(date.getDate()).padStart(2, '0');
  return `${year}-${month}-${day}`;
}

function isToday(date: Date): boolean {
  const today = new Date();
  return (
    date.getDate() === today.getDate() &&
    date.getMonth() === today.getMonth() &&
    date.getFullYear() === today.getFullYear()
  );
}

interface DayItem {
  date: Date;
  dateKey: string;
  dayName: string;
  dayNumber: number;
  isToday: boolean;
}

function generateWeekDays(centerDate: string): DayItem[] {
  const center = new Date(centerDate + 'T00:00:00');
  const days: DayItem[] = [];

  for (let offset = -14; offset <= 14; offset++) {
    const date = new Date(center);
    date.setDate(center.getDate() + offset);
    days.push({
      date,
      dateKey: formatDateKey(date),
      dayName: DAY_NAMES_SHORT[date.getDay()],
      dayNumber: date.getDate(),
      isToday: isToday(date),
    });
  }

  return days;
}

function getMonthTitle(dateStr: string): string {
  const date = new Date(dateStr + 'T00:00:00');
  return `${MONTH_NAMES[date.getMonth()]} ${date.getFullYear()}`;
}

export function ScheduleScreen(): React.JSX.Element {
  const styles = createStyles();
  const navigation = useNavigation<NavigationProp>();
  const {
    trainings,
    selectedDate,
    isLoading,
    isRefreshing,
    error,
    selectDate,
    fetchTrainingsByDate,
    refreshTrainings,
  } = useScheduleStore();

  const weekDays = useMemo(
    () => generateWeekDays(selectedDate),
    [selectedDate],
  );

  const monthTitle = useMemo(
    () => getMonthTitle(selectedDate),
    [selectedDate],
  );

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

  const handleDayPress = useCallback(
    (dateKey: string) => {
      selectDate(dateKey);
    },
    [selectDate],
  );

  const handleTrainingPress = useCallback(
    (training: Training) => {
      navigation.navigate('TrainingDetail', { trainingId: training.id });
    },
    [navigation],
  );

  const handleCreatePress = useCallback(() => {
    navigation.navigate('CreateTraining', { date: selectedDate });
  }, [navigation, selectedDate]);

  const renderDayItem = useCallback(
    (item: DayItem) => {
      const isSelected = item.dateKey === selectedDate;
      return (
        <TouchableOpacity
          key={item.dateKey}
          style={[
            styles.dayItem,
            isSelected && styles.dayItemSelected,
            item.isToday && !isSelected && styles.dayItemToday,
          ]}
          onPress={() => handleDayPress(item.dateKey)}
          activeOpacity={0.7}
        >
          <Text
            style={[
              styles.dayName,
              isSelected && styles.dayNameSelected,
            ]}
          >
            {item.dayName}
          </Text>
          <Text
            style={[
              styles.dayNumber,
              isSelected && styles.dayNumberSelected,
              item.isToday && !isSelected && styles.dayNumberToday,
            ]}
          >
            {item.dayNumber}
          </Text>
        </TouchableOpacity>
      );
    },
    [selectedDate, handleDayPress],
  );

  const renderTrainingItem = useCallback(
    ({ item }: { item: Training }) => (
      <TrainingCard training={item} onPress={handleTrainingPress} />
    ),
    [handleTrainingPress],
  );

  const renderEmptyState = 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}>
      <View style={styles.calendarHeader}>
        <Text style={styles.monthTitle}>{monthTitle}</Text>
      </View>

      <View style={styles.weekStrip}>
        <ScrollView
          horizontal
          showsHorizontalScrollIndicator={false}
          contentContainerStyle={styles.weekStripContent}
          contentOffset={{ x: 14 * 56 - 140, y: 0 }}
        >
          {weekDays.map(renderDayItem)}
        </ScrollView>
      </View>

      {error && (
        <View style={styles.errorBanner}>
          <Text style={styles.errorText}>{error}</Text>
        </View>
      )}

      {isLoading && !isRefreshing ? (
        <View style={styles.loadingContainer}>
          <ActivityIndicator size="large" color={colors.primary} />
        </View>
      ) : (
        <FlatList
          data={trainings}
          renderItem={renderTrainingItem}
          keyExtractor={(item) => item.id}
          contentContainerStyle={styles.listContent}
          ListEmptyComponent={renderEmptyState}
          refreshControl={
            <RefreshControl
              refreshing={isRefreshing}
              onRefresh={refreshTrainings}
              tintColor={colors.primary}
              colors={[colors.primary]}
            />
          }
        />
      )}

      <TouchableOpacity
        style={styles.fab}
        onPress={handleCreatePress}
        activeOpacity={0.8}
      >
        <Text style={styles.fabIcon}>+</Text>
      </TouchableOpacity>
    </View>
  );
}

const createStyles = () => StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: colors.background,
  },
  calendarHeader: {
    backgroundColor: colors.white,
    paddingHorizontal: spacing.lg,
    paddingTop: spacing.md,
    paddingBottom: spacing.xs,
  },
  monthTitle: {
    ...typography.subtitle,
    color: colors.text,
  },
  weekStrip: {
    backgroundColor: colors.white,
    paddingBottom: spacing.md,
    borderBottomWidth: 1,
    borderBottomColor: colors.border,
  },
  weekStripContent: {
    paddingHorizontal: spacing.md,
  },
  dayItem: {
    alignItems: 'center',
    justifyContent: 'center',
    width: 48,
    height: 64,
    marginHorizontal: spacing.xs,
    borderRadius: 12,
  },
  dayItemSelected: {
    backgroundColor: colors.primary,
  },
  dayItemToday: {
    backgroundColor: colors.background,
  },
  dayName: {
    ...typography.caption,
    color: colors.textSecondary,
    marginBottom: spacing.xs,
  },
  dayNameSelected: {
    color: colors.white,
  },
  dayNumber: {
    ...typography.body,
    fontWeight: '700',
    color: colors.text,
  },
  dayNumberSelected: {
    color: colors.white,
  },
  dayNumberToday: {
    color: colors.primary,
  },
  listContent: {
    padding: spacing.lg,
    paddingBottom: 100,
  },
  loadingContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  emptyContainer: {
    alignItems: 'center',
    paddingTop: spacing.xxxl * 2,
  },
  emptyTitle: {
    ...typography.subtitle,
    color: colors.text,
    marginBottom: spacing.sm,
  },
  emptySubtitle: {
    ...typography.body,
    color: colors.textMuted,
    textAlign: 'center',
  },
  errorBanner: {
    backgroundColor: colors.error,
    padding: spacing.md,
  },
  errorText: {
    ...typography.bodySmall,
    color: colors.white,
    textAlign: 'center',
  },
  fab: {
    position: 'absolute',
    bottom: 24,
    right: 24,
    width: 56,
    height: 56,
    borderRadius: 28,
    backgroundColor: colors.primary,
    alignItems: 'center',
    justifyContent: 'center',
    shadowColor: colors.black,
    shadowOffset: { width: 0, height: 4 },
    shadowOpacity: 0.2,
    shadowRadius: 8,
    elevation: 6,
  },
  fabIcon: {
    fontSize: 28,
    fontWeight: '400',
    color: colors.white,
    marginTop: -2,
  },
});
