// Lista ulubionych performerów + studiów + badge "ile nowych scen". Dwie zakładki
// na górze (Performers / Studios). Tap → odpowiedni screen scen + auto mark-seen
// (zeruje licznik). Klucz: przekazujemy `seenSince` (last_seen_at SPRZED markSeen)
// żeby PerformerScenesScreen / StudioScenesScreen mógł pokazać NEW badge na świeżych
// scenach.
import { useNavigation } from '@react-navigation/native';
import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import React from 'react';
import {
  ActivityIndicator,
  Alert,
  FlatList,
  Pressable,
  StyleSheet,
  Text,
  View,
} from 'react-native';
import { Image } from 'expo-image';
import { useClient } from '../ClientContext';
import { SceneTile, sceneGridProps } from '../components/SceneTile';
import { usePreferences } from '../PreferencesContext';
import type { RootStackParamList } from '../navigation';
import { theme } from '../theme';
import type { FavoriteMovieOut, FavoriteOut, FavoriteStudioOut } from '../types';

type Tab = 'scenes' | 'performers' | 'studios' | 'movies';

export function FavoritesScreen() {
  const client = useClient();
  const { gridColumns } = usePreferences();
  const queryClient = useQueryClient();
  const nav = useNavigation<NativeStackNavigationProp<RootStackParamList, 'Favorites'>>();
  const [tab, setTab] = React.useState<Tab>('scenes');

  const performersQuery = useQuery({
    queryKey: ['favorites'],
    queryFn: () => client.listFavorites(),
  });

  const studiosQuery = useQuery({
    queryKey: ['favorites-studios'],
    queryFn: () => client.listFavoriteStudios(),
  });

  const moviesQuery = useQuery({
    queryKey: ['favorites-movies'],
    queryFn: () => client.listFavoriteMovies(),
  });

  const scenesQuery = useQuery({
    queryKey: ['favorites-scenes'],
    queryFn: () => client.listSceneFavorites(),
  });

  const removeScene = useMutation({
    mutationFn: (id: string) => client.removeSceneFavorite(id),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['favorites-scenes'] }),
    onError: (e) => Alert.alert('Failed', e instanceof Error ? e.message : String(e)),
  });

  const removeMovie = useMutation({
    mutationFn: (id: string) => client.removeFavoriteMovie(id),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['favorites-movies'] }),
    onError: (e) => Alert.alert('Failed', e instanceof Error ? e.message : String(e)),
  });

  const removePerformer = useMutation({
    mutationFn: (id: string) => client.removeFavorite(id),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['favorites'] }),
    onError: (e) => Alert.alert('Failed', e instanceof Error ? e.message : String(e)),
  });

  const removeStudio = useMutation({
    mutationFn: (id: string) => client.removeFavoriteStudio(id),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['favorites-studios'] }),
    onError: (e) => Alert.alert('Failed', e instanceof Error ? e.message : String(e)),
  });

  const markPerformerSeen = (id: string) => {
    queryClient.setQueryData(['favorites'], (prev: typeof performersQuery.data) =>
      prev
        ? {
            ...prev,
            items: prev.items.map((f) =>
              f.performer_id === id ? { ...f, new_count: 0 } : f,
            ),
            new_total: Math.max(
              0,
              prev.new_total - (prev.items.find((f) => f.performer_id === id)?.new_count ?? 0),
            ),
          }
        : prev,
    );
    client.markFavoriteSeen(id).catch(() => {});
  };

  const markStudioSeen = (id: string) => {
    queryClient.setQueryData(['favorites-studios'], (prev: typeof studiosQuery.data) =>
      prev
        ? {
            ...prev,
            items: prev.items.map((f) =>
              f.studio_id === id ? { ...f, new_count: 0 } : f,
            ),
            new_total: Math.max(
              0,
              prev.new_total - (prev.items.find((f) => f.studio_id === id)?.new_count ?? 0),
            ),
          }
        : prev,
    );
    client.markFavoriteStudioSeen(id).catch(() => {});
  };

  // performers/studios mają new_total badge; scenes/movies nie (single entity).
  const activeData =
    tab === 'performers'
      ? performersQuery.data
      : tab === 'studios'
        ? studiosQuery.data
        : null;
  const activeQuery =
    tab === 'performers'
      ? performersQuery
      : tab === 'studios'
        ? studiosQuery
        : tab === 'movies'
          ? moviesQuery
          : scenesQuery;
  const headerCount = activeData?.total ?? (activeQuery.data as { total?: number } | undefined)?.total ?? 0;
  const isLoading = activeQuery.isLoading;
  const isRefetching = activeQuery.isRefetching;
  const error = activeQuery.error;
  const refetch = activeQuery.refetch;

  return (
    <View style={styles.container}>
      <View style={styles.headerRow}>
        <Text style={styles.headerLabel}>Favorites</Text>
        {activeData && activeData.new_total > 0 ? (
          <View style={styles.totalBadge}>
            <Text style={styles.totalBadgeText}>+{activeData.new_total} new</Text>
          </View>
        ) : (
          <Text style={styles.headerCount}>{headerCount}</Text>
        )}
      </View>

      <View style={styles.tabRow}>
        <TabButton
          label="Scenes"
          active={tab === 'scenes'}
          newCount={0}
          onPress={() => setTab('scenes')}
        />
        <TabButton
          label="Performers"
          active={tab === 'performers'}
          newCount={performersQuery.data?.new_total ?? 0}
          onPress={() => setTab('performers')}
        />
        <TabButton
          label="Studios"
          active={tab === 'studios'}
          newCount={studiosQuery.data?.new_total ?? 0}
          onPress={() => setTab('studios')}
        />
        <TabButton
          label="Movies"
          active={tab === 'movies'}
          newCount={0}
          onPress={() => setTab('movies')}
        />
      </View>

      <Text style={styles.hint}>
        tap to open scenes (resets the new badge) · long-press to remove
      </Text>

      {isLoading && <ActivityIndicator color={theme.fg} style={{ marginTop: 24 }} />}
      {error instanceof Error && <Text style={styles.error}>{error.message}</Text>}

      {tab === 'scenes' ? (
        <FlatList
          {...sceneGridProps(gridColumns)}
          // key per tab + per liczba kolumn: bez remountu RN rzuca "Changing numColumns
          // on the fly is not supported" (GOON-11). Zmiana kolumn też wymaga remountu.
          key={`fav-scenes-${gridColumns}`}
          data={scenesQuery.data?.items ?? []}
          keyExtractor={(s) => s.id}
          // patrz ScenesScreen: removeClippedSubviews blankuje miniaturki po scrollu.
          removeClippedSubviews={false}
          renderItem={({ item }) => (
            <SceneTile
              scene={item}
              secondLine="studio"
              onLongPress={() =>
                Alert.alert(
                  'Remove favorite',
                  `Remove "${item.title}" from favorites?`,
                  [
                    { text: 'Cancel', style: 'cancel' },
                    {
                      text: 'Remove',
                      style: 'destructive',
                      onPress: () => removeScene.mutate(item.id),
                    },
                  ],
                )
              }
            />
          )}
          refreshing={isRefetching}
          onRefresh={refetch}
          ListEmptyComponent={
            !isLoading ? (
              <Text style={styles.emptyText}>
                No scene favorites yet. Tap the heart on a scene to save it here.
              </Text>
            ) : null
          }
          contentContainerStyle={{ paddingBottom: 24 }}
        />
      ) : tab === 'movies' ? (
        <FlatList
          key="fav-list"
          data={moviesQuery.data?.items ?? []}
          keyExtractor={(f) => f.movie_id}
          renderItem={({ item }) => (
            <MovieRow
              fav={item}
              onPress={() => {
                client.markFavoriteMovieSeen(item.movie_id).catch(() => {});
                nav.navigate('MovieDetail', { id: item.movie_id });
              }}
              onLongPress={() =>
                Alert.alert(
                  'Remove favorite',
                  `Remove "${item.title}" from favorites?`,
                  [
                    { text: 'Cancel', style: 'cancel' },
                    {
                      text: 'Remove',
                      style: 'destructive',
                      onPress: () => removeMovie.mutate(item.movie_id),
                    },
                  ],
                )
              }
            />
          )}
          refreshing={isRefetching}
          onRefresh={refetch}
          ListEmptyComponent={
            !isLoading ? (
              <Text style={styles.emptyText}>
                No movie favorites yet. Tap the star on a movie to follow.
              </Text>
            ) : null
          }
          contentContainerStyle={{ paddingBottom: 24 }}
        />
      ) : tab === 'performers' ? (
        <FlatList
          key="fav-list"
          data={performersQuery.data?.items ?? []}
          keyExtractor={(f) => f.performer_id}
          renderItem={({ item }) => (
            <PerformerRow
              fav={item}
              onPress={() => {
                // Capture last_seen_at PRZED markSeen, żeby PerformerScenes mógł
                // porównać scene.created_at > seenSince i pokazać NEW badge.
                const seenSince = item.last_seen_at;
                markPerformerSeen(item.performer_id);
                nav.navigate('PerformerScenes', {
                  id: item.performer_id,
                  name: item.canonical_name,
                  seenSince,
                });
              }}
              onLongPress={() =>
                Alert.alert(
                  'Remove favorite',
                  `Stop following ${item.canonical_name}?`,
                  [
                    { text: 'Cancel', style: 'cancel' },
                    {
                      text: 'Remove',
                      style: 'destructive',
                      onPress: () => removePerformer.mutate(item.performer_id),
                    },
                  ],
                )
              }
            />
          )}
          refreshing={isRefetching}
          onRefresh={refetch}
          ListEmptyComponent={
            !isLoading ? (
              <Text style={styles.emptyText}>
                No performer favorites yet. Tap the star on a performer to follow.
              </Text>
            ) : null
          }
          contentContainerStyle={{ paddingBottom: 24 }}
        />
      ) : (
        <FlatList
          key="fav-list"
          data={studiosQuery.data?.items ?? []}
          keyExtractor={(f) => f.studio_id}
          renderItem={({ item }) => (
            <StudioRow
              fav={item}
              onPress={() => {
                const seenSince = item.last_seen_at;
                markStudioSeen(item.studio_id);
                nav.navigate('StudioScenes', {
                  id: item.slug,
                  studioId: item.studio_id,
                  name: item.name,
                  seenSince,
                });
              }}
              onLongPress={() =>
                Alert.alert(
                  'Remove favorite',
                  `Stop following ${item.name}?`,
                  [
                    { text: 'Cancel', style: 'cancel' },
                    {
                      text: 'Remove',
                      style: 'destructive',
                      onPress: () => removeStudio.mutate(item.studio_id),
                    },
                  ],
                )
              }
            />
          )}
          refreshing={isRefetching}
          onRefresh={refetch}
          ListEmptyComponent={
            !isLoading ? (
              <Text style={styles.emptyText}>
                No studio favorites yet. Tap the star on a studio to follow.
              </Text>
            ) : null
          }
          contentContainerStyle={{ paddingBottom: 24 }}
        />
      )}
    </View>
  );
}

function TabButton({
  label,
  active,
  newCount,
  onPress,
}: {
  label: string;
  active: boolean;
  newCount: number;
  onPress: () => void;
}) {
  return (
    <Pressable style={[styles.tabBtn, active && styles.tabBtnActive]} onPress={onPress}>
      <Text style={[styles.tabBtnText, active && styles.tabBtnTextActive]}>{label}</Text>
      {newCount > 0 ? (
        <View style={styles.tabBadge}>
          <Text style={styles.tabBadgeText}>+{newCount}</Text>
        </View>
      ) : null}
    </Pressable>
  );
}

function initials(name: string): string {
  const parts = name.trim().split(/\s+/);
  const first = parts[0]?.[0] ?? '';
  const last = parts.length > 1 ? parts[parts.length - 1][0] ?? '' : '';
  return (first + last).toUpperCase() || '?';
}

function PerformerRow({
  fav,
  onPress,
  onLongPress,
}: {
  fav: FavoriteOut;
  onPress: () => void;
  onLongPress: () => void;
}) {
  return (
    <Pressable
      style={({ pressed }) => [styles.row, pressed && styles.rowPressed]}
      onPress={onPress}
      onLongPress={onLongPress}
      delayLongPress={400}
    >
      <View style={styles.avatar}>
        <Text style={styles.avatarText}>{initials(fav.canonical_name)}</Text>
      </View>
      <View style={styles.rowContent}>
        <Text style={styles.rowTitle} numberOfLines={1}>
          {fav.canonical_name}
        </Text>
        <Text style={styles.rowMuted}>
          {fav.scene_count} {fav.scene_count === 1 ? 'scene' : 'scenes'}
        </Text>
      </View>
      {fav.new_count > 0 ? (
        <View style={styles.newBadge}>
          <Text style={styles.newBadgeText}>+{fav.new_count}</Text>
        </View>
      ) : (
        <Text style={styles.chevron}>›</Text>
      )}
    </Pressable>
  );
}

function MovieRow({
  fav,
  onPress,
  onLongPress,
}: {
  fav: FavoriteMovieOut;
  onPress: () => void;
  onLongPress: () => void;
}) {
  return (
    <Pressable
      style={({ pressed }) => [styles.row, pressed && styles.rowPressed]}
      onPress={onPress}
      onLongPress={onLongPress}
      delayLongPress={400}
    >
      {fav.poster_url ? (
        <Image source={{ uri: fav.poster_url }} style={styles.poster} contentFit="cover" />
      ) : (
        <View style={[styles.poster, styles.posterPlaceholder]}>
          <Text style={styles.avatarText}>{initials(fav.title)}</Text>
        </View>
      )}
      <View style={styles.rowContent}>
        <Text style={styles.rowTitle} numberOfLines={1}>
          {fav.title}
        </Text>
        <Text style={styles.rowMuted}>
          {fav.release_year ?? '—'}
          {fav.studio_name ? ` · ${fav.studio_name}` : ''}
        </Text>
      </View>
      <Text style={styles.chevron}>›</Text>
    </Pressable>
  );
}

function StudioRow({
  fav,
  onPress,
  onLongPress,
}: {
  fav: FavoriteStudioOut;
  onPress: () => void;
  onLongPress: () => void;
}) {
  return (
    <Pressable
      style={({ pressed }) => [styles.row, pressed && styles.rowPressed]}
      onPress={onPress}
      onLongPress={onLongPress}
      delayLongPress={400}
    >
      <View style={styles.avatar}>
        <Text style={styles.avatarText}>{initials(fav.name)}</Text>
      </View>
      <View style={styles.rowContent}>
        <Text style={styles.rowTitle} numberOfLines={1}>
          {fav.name}
        </Text>
        <Text style={styles.rowMuted}>
          {fav.scene_count} {fav.scene_count === 1 ? 'scene' : 'scenes'}
          {fav.network ? ` · ${fav.network}` : ''}
        </Text>
      </View>
      {fav.new_count > 0 ? (
        <View style={styles.newBadge}>
          <Text style={styles.newBadgeText}>+{fav.new_count}</Text>
        </View>
      ) : (
        <Text style={styles.chevron}>›</Text>
      )}
    </Pressable>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, backgroundColor: theme.bg, paddingHorizontal: 16, paddingTop: 12 },
  headerRow: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    paddingBottom: 4,
  },
  headerLabel: {
    color: theme.muted,
    fontSize: 12,
    textTransform: 'uppercase',
    letterSpacing: 1.2,
    fontWeight: '700',
  },
  headerCount: { color: theme.fg, fontSize: 22, fontWeight: '800' },
  totalBadge: {
    backgroundColor: theme.accent,
    paddingHorizontal: 10,
    paddingVertical: 4,
    borderRadius: 10,
    shadowColor: theme.accent,
    shadowOffset: { width: 0, height: 0 },
    shadowOpacity: 0.5,
    shadowRadius: 6,
    elevation: 3,
  },
  totalBadgeText: {
    color: theme.fg,
    fontWeight: '800',
    fontSize: 13,
    letterSpacing: 0.3,
  },

  tabRow: { flexDirection: 'row', gap: 8, marginTop: 10, marginBottom: 4 },
  tabBtn: {
    flex: 1,
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    gap: 6,
    paddingVertical: 8,
    borderRadius: 8,
    backgroundColor: theme.card,
    borderColor: theme.border,
    borderWidth: 1,
  },
  tabBtnActive: { borderColor: theme.accent, backgroundColor: theme.bgElevated },
  tabBtnText: { color: theme.muted, fontWeight: '600', fontSize: 14 },
  tabBtnTextActive: { color: theme.fg },
  tabBadge: {
    backgroundColor: theme.accent,
    paddingHorizontal: 6,
    paddingVertical: 1,
    borderRadius: 4,
  },
  tabBadgeText: { color: theme.bg, fontWeight: '800', fontSize: 11 },

  hint: { color: theme.mutedDim, fontSize: 11, marginTop: 8, marginBottom: 12 },

  gridRow: { gap: 10, marginBottom: 14 },

  row: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 12,
    backgroundColor: theme.card,
    borderColor: theme.border,
    borderWidth: 1,
    borderRadius: 14,
    paddingHorizontal: 14,
    paddingVertical: 12,
    marginBottom: 10,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.2,
    shadowRadius: 4,
    elevation: 3,
  },
  rowPressed: { backgroundColor: theme.bgElevated, borderColor: theme.borderFocus },

  avatar: {
    width: 40,
    height: 40,
    borderRadius: 20,
    backgroundColor: theme.bgElevated,
    borderColor: theme.border,
    borderWidth: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  avatarText: {
    color: theme.accentGlow,
    fontWeight: '800',
    fontSize: 13,
    letterSpacing: 0.5,
  },
  poster: {
    width: 40,
    height: 56,
    borderRadius: 6,
    backgroundColor: theme.bgElevated,
    borderColor: theme.border,
    borderWidth: 1,
  },
  posterPlaceholder: { alignItems: 'center', justifyContent: 'center' },
  rowContent: { flex: 1 },
  rowTitle: { color: theme.fg, fontWeight: '700', fontSize: 16, marginBottom: 4 },
  rowMuted: { color: theme.muted, fontSize: 13 },

  newBadge: {
    backgroundColor: theme.accent,
    paddingHorizontal: 10,
    paddingVertical: 4,
    borderRadius: 10,
    shadowColor: theme.accent,
    shadowOffset: { width: 0, height: 0 },
    shadowOpacity: 0.5,
    shadowRadius: 6,
    elevation: 3,
  },
  newBadgeText: { color: theme.fg, fontWeight: '800', fontSize: 13 },
  chevron: { color: theme.mutedDim, fontSize: 22, fontWeight: '300' },

  emptyText: {
    color: theme.muted,
    textAlign: 'center',
    marginTop: 48,
    fontSize: 15,
    paddingHorizontal: 24,
    lineHeight: 22,
  },
  error: { color: theme.bad, padding: 16 },
});
