import { router } from 'expo-router';
import { useMemo, useState } from 'react';
import { ActivityIndicator, FlatList, Pressable, ScrollView, StyleSheet, Text, View } from 'react-native';
import { useQuery } from '@tanstack/react-query';
import { useTranslation } from 'react-i18next';
import { fetchRecipes } from '@/src/api/recipes.api';
import { EmptyState, RecipeCard } from '@/src/components/RecipeCard';
import { ErrorView } from '@/src/components/ErrorView';
import { Input } from '@/src/components/Input';
import { Screen } from '@/src/components/Screen';
import { useAppearance } from '@/src/context/AppearanceContext';
import { nextSort, sortBy, sortIndicator, type SortDirection } from '@/src/utils/sort';

type RecipeSortColumn = 'name' | 'calories' | 'prepTime';

const RECIPE_SORT_COLUMNS: { id: RecipeSortColumn; labelKey: string }[] = [
  { id: 'name', labelKey: 'manage.recipeName' },
  { id: 'calories', labelKey: 'recipes.calories' },
  { id: 'prepTime', labelKey: 'manage.prepTimeMin' },
];

export default function MealsScreen() {
  const { t } = useTranslation();
  const { colors } = useAppearance();
  const [search, setSearch] = useState('');
  const [ingredient, setIngredient] = useState('');
  const [recipeSort, setRecipeSort] = useState<{ column: RecipeSortColumn; direction: SortDirection }>({
    column: 'name',
    direction: 'asc',
  });

  const recipesQuery = useQuery({
    queryKey: ['recipes', search, ingredient],
    queryFn: () =>
      fetchRecipes({
        search: search.trim() || undefined,
        ingredient: ingredient.trim() || undefined,
      }),
  });

  const emptyMessage = useMemo(() => {
    if (ingredient.trim()) return t('recipes.noMatchingIngredient');
    return t('recipes.noMatchingFilter');
  }, [ingredient, t]);

  const sortedRecipes = useMemo(() => {
    const list = recipesQuery.data ?? [];
    const { column, direction } = recipeSort;
    return sortBy(list, direction, (recipe) => {
      switch (column) {
        case 'name':
          return recipe.name;
        case 'calories':
          return recipe.calories;
        case 'prepTime':
          return recipe.prepTimeMinutes;
      }
    });
  }, [recipesQuery.data, recipeSort]);

  return (
    <Screen title={t('recipes.allMealsTitle')} subtitle={t('recipes.allMealsSubtitle')}>
      <View style={styles.filters}>
        <Input
          placeholder={t('recipes.searchRecipes')}
          value={search}
          onChangeText={setSearch}
          autoCapitalize="none"
        />
        <Input
          placeholder={t('recipes.searchByIngredient')}
          value={ingredient}
          onChangeText={setIngredient}
          autoCapitalize="none"
        />
      </View>

      {(recipesQuery.data?.length ?? 0) > 0 ? (
        <ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={styles.sortRow}>
          {RECIPE_SORT_COLUMNS.map(({ id, labelKey }) => (
            <SortChip
              key={id}
              label={`${t(labelKey)}${sortIndicator(recipeSort, id)}`}
              active={recipeSort.column === id}
              onPress={() => setRecipeSort((current) => nextSort(current, id))}
            />
          ))}
        </ScrollView>
      ) : null}

      {recipesQuery.isLoading ? (
        <View style={styles.loading}>
          <ActivityIndicator size="large" color={colors.brand} />
        </View>
      ) : recipesQuery.isError ? (
        <ErrorView
          message={t('errors.loadRecipesFailed')}
          onRetry={() => recipesQuery.refetch()}
        />
      ) : (
        <FlatList
          data={sortedRecipes}
          keyExtractor={(item) => String(item.id)}
          contentContainerStyle={styles.list}
          ListEmptyComponent={
            <EmptyState title={t('recipes.noMatchingTitle')} description={emptyMessage} />
          }
          renderItem={({ item }) => (
            <RecipeCard
              recipe={item}
              onPress={() => router.push(`/(main)/recipe/${item.id}`)}
            />
          )}
        />
      )}
    </Screen>
  );
}

function SortChip({ label, active, onPress }: { label: string; active: boolean; onPress: () => void }) {
  const { colors } = useAppearance();
  return (
    <Pressable
      onPress={onPress}
      style={[
        styles.sortChip,
        {
          backgroundColor: active ? colors.brand : colors.surface,
          borderColor: active ? colors.brand : colors.border,
        },
      ]}
    >
      <Text style={{ color: active ? '#fff' : colors.text, fontWeight: '600', fontSize: 12 }}>{label}</Text>
    </Pressable>
  );
}

const styles = StyleSheet.create({
  filters: {
    gap: 10,
  },
  sortRow: {
    gap: 8,
    paddingBottom: 8,
  },
  sortChip: {
    borderWidth: 1,
    borderRadius: 999,
    paddingHorizontal: 12,
    paddingVertical: 6,
  },
  list: {
    gap: 10,
    paddingBottom: 24,
    flexGrow: 1,
  },
  loading: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    paddingVertical: 40,
  },
});
