import React, {useCallback, useEffect, useRef, useState} from 'react';
import {
  Dimensions,
  FlatList,
  StatusBar,
  StyleSheet,
  Text,
  TextInput,
  View,
} from 'react-native';
import {TVTouchable as TouchableOpacity} from '../components/common/TVTouchable';
import {useNavigation, useFocusEffect} from '@react-navigation/native';
import {StackNavigationProp} from '@react-navigation/stack';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import {RootStackParamList} from '../navigation/types';
import {addonManager} from '../api/addonManager';
import {MetaPreview} from '../api/addonTypes';
import {colors, typography} from '../utils/colors';
import {IS_TV} from '../utils/tv';
import {SIDEBAR_W} from '../utils/dimensions';
import Card from '../components/common/Card';
import LoadingSpinner from '../components/common/LoadingSpinner';

const SCREEN_W = Dimensions.get('window').width;
const CONTENT_W = SCREEN_W - SIDEBAR_W; // account for sidebar on TV/tablet
const GRID_PADDING = 12;
const CARD_GAP = IS_TV ? 12 : 8;
const NUM_COLUMNS = IS_TV ? 6 : 3;
const CARD_WIDTH = Math.floor(
  (CONTENT_W - GRID_PADDING * 2 - CARD_GAP * (NUM_COLUMNS - 1)) / NUM_COLUMNS,
);

type Nav = StackNavigationProp<RootStackParamList>;
const DEBOUNCE_MS = 350;

export default function SearchScreen() {
  const navigation = useNavigation<Nav>();
  const [query, setQuery] = useState('');
  const [results, setResults] = useState<MetaPreview[]>([]);
  const [loading, setLoading] = useState(false);
  const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const inputRef = useRef<TextInput>(null);

  const doSearch = useCallback(async (q: string) => {
    if (!q.trim()) {
      setResults([]);
      setLoading(false);
      return;
    }
    setLoading(true);
    try {
      const items = await addonManager.searchAll(q.trim());
      setResults(items);
    } catch {
      setResults([]);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    if (debounceRef.current) clearTimeout(debounceRef.current);
    if (!query.trim()) {
      setResults([]);
      setLoading(false);
      return;
    }
    setLoading(true);
    debounceRef.current = setTimeout(() => doSearch(query), DEBOUNCE_MS);
    return () => {
      if (debounceRef.current) clearTimeout(debounceRef.current);
    };
  }, [query, doSearch]);

  // Re-focus the input when the tab is re-entered
  useFocusEffect(
    useCallback(() => {
      const timer = setTimeout(() => inputRef.current?.focus(), 100);
      return () => clearTimeout(timer);
    }, []),
  );

  const goToDetail = (item: MetaPreview) =>
    navigation.navigate('Detail', {
      id: item.id,
      type: item.type,
      name: item.name,
      poster: item.poster,
    });

  return (
    <View style={styles.container}>
      <StatusBar barStyle="light-content" backgroundColor={colors.background} />

      {/* Header */}
      <View style={styles.header}>
        <Text style={styles.headerTitle}>Search</Text>
      </View>

      {/* Search input */}
      <View style={styles.searchRow}>
        <View style={styles.searchBox}>
          <Icon name="magnify" size={22} color={colors.primary} style={styles.searchIcon} />
          <TextInput
            ref={inputRef}
            style={styles.searchInput}
            value={query}
            onChangeText={setQuery}
            placeholder="Movies, series, people..."
            placeholderTextColor={colors.textMuted}
            returnKeyType="search"
            autoCapitalize="none"
            autoCorrect={false}
            autoFocus
            focusable
            onSubmitEditing={() => doSearch(query)}
          />
          {query.length > 0 && (
            <TouchableOpacity onPress={() => setQuery('')} style={styles.clearBtn} focusable={IS_TV || undefined}>
              <Icon name="close-circle" size={20} color={colors.textMuted} />
            </TouchableOpacity>
          )}
        </View>
      </View>

      {/* Loading */}
      {loading && (
        <View style={styles.loadingRow}>
          <LoadingSpinner size="small" />
        </View>
      )}

      {/* No results */}
      {!loading && query.length > 0 && results.length === 0 && (
        <View style={styles.emptyState}>
          <Icon name="movie-search-outline" size={72} color={colors.textMuted} />
          <Text style={styles.emptyTitle}>No results for "{query}"</Text>
          <Text style={styles.emptyText}>
            Try a different term, or install more addons that support search.
          </Text>
        </View>
      )}

      {/* Results */}
      {!loading && results.length > 0 && (
        <FlatList
          data={results}
          keyExtractor={i => i.id}
          numColumns={NUM_COLUMNS}
          contentContainerStyle={styles.grid}
          columnWrapperStyle={styles.gridRow}
          showsVerticalScrollIndicator={false}
          renderItem={({item}) => (
            <Card item={item} onPress={goToDetail} width={CARD_WIDTH} style={styles.card} />
          )}
        />
      )}

      {/* Idle state */}
      {!query && !loading && (
        <View style={styles.emptyState}>
          <Icon name="magnify" size={72} color={colors.textMuted} />
          <Text style={styles.emptyTitle}>Search anything</Text>
          <Text style={styles.emptyText}>
            Find movies and series across all your installed addons.
          </Text>
        </View>
      )}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {flex: 1, backgroundColor: colors.background},
  header: {
    paddingHorizontal: 20,
    paddingTop: 52,
    paddingBottom: 8,
  },
  headerTitle: {
    ...typography.title,
    color: colors.textPrimary,
    fontSize: 28,
    fontWeight: '800',
  },
  searchRow: {
    paddingHorizontal: 16,
    paddingVertical: 10,
  },
  searchBox: {
    flexDirection: 'row',
    alignItems: 'center',
    backgroundColor: colors.surfaceLight,
    borderRadius: 14,
    borderWidth: 1,
    borderColor: colors.border,
    paddingHorizontal: 14,
    height: 50,
  },
  searchIcon: {marginRight: 10},
  searchInput: {
    flex: 1,
    color: colors.textPrimary,
    fontSize: 16,
    paddingVertical: 0,
  },
  clearBtn: {padding: 4},
  loadingRow: {paddingVertical: 24, alignItems: 'center'},
  grid: {paddingHorizontal: GRID_PADDING, paddingTop: 8, paddingBottom: 24},
  gridRow: {gap: CARD_GAP, marginBottom: IS_TV ? 16 : 12},
  card: {width: CARD_WIDTH},
  emptyState: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    paddingHorizontal: 40,
    gap: 14,
    paddingBottom: 60,
  },
  emptyTitle: {
    ...typography.title,
    color: colors.textSecondary,
    textAlign: 'center',
  },
  emptyText: {
    ...typography.body,
    color: colors.textMuted,
    textAlign: 'center',
    lineHeight: 22,
  },
});
