import React, { useEffect, useMemo, useState } from 'react';
import {
  Dimensions,
  FlatList,
  ScrollView,
  StyleSheet,
  Text,
  TextInput,
  TouchableOpacity,
  View,
} from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { useRouter } from 'expo-router';
import { Ionicons } from '@expo/vector-icons';
import { useApp } from '../../context/AppContext';
import { useColors } from '../../constants/Colors';
import { Plant } from '../../types';
import { PlantCard } from '../../components/PlantCard';
import { ThemeBackdrop } from '../../components/ThemeBackdrop';
import {
  DatabaseEntry,
  PlantDatabaseService,
  SemanticSearchStatus,
} from '../../services/plantDatabaseService';
import { normalizeSearchText, rankHybridEntries } from '../../utils/hybridSearch';

const { width } = Dimensions.get('window');
const CARD_GAP = 12;
const CARD_WIDTH = (width - 40 - CARD_GAP) / 2;
const SEARCH_DEBOUNCE_MS = 250;
const SEMANTIC_SEARCH_CREDIT_COST = 2;

const getBillingCopy = (language: 'de' | 'en' | 'es') => {
  if (language === 'de') {
    return {
      creditsLabel: 'Credits',
      deepSearchCost: `Deep Search kostet ${SEMANTIC_SEARCH_CREDIT_COST} Credits`,
      insufficientCredits: 'Nicht genug Credits fuer AI Deep Search.',
      managePlan: 'Plan verwalten',
    };
  }

  if (language === 'es') {
    return {
      creditsLabel: 'Creditos',
      deepSearchCost: `Deep Search cuesta ${SEMANTIC_SEARCH_CREDIT_COST} creditos`,
      insufficientCredits: 'No tienes creditos suficientes para AI Deep Search.',
      managePlan: 'Gestionar plan',
    };
  }

  return {
    creditsLabel: 'Credits',
    deepSearchCost: `Deep Search costs ${SEMANTIC_SEARCH_CREDIT_COST} credits`,
    insufficientCredits: 'Not enough credits for AI Deep Search.',
    managePlan: 'Manage plan',
  };
};

const parseColor = (value: string) => {
  if (value.startsWith('#')) {
    const cleaned = value.replace('#', '');
    const normalized = cleaned.length === 3
      ? cleaned.split('').map((c) => `${c}${c}`).join('')
      : cleaned;
    const int = Number.parseInt(normalized, 16);
    return {
      r: (int >> 16) & 255,
      g: (int >> 8) & 255,
      b: int & 255,
    };
  }

  const match = value.match(/rgba?\(([^)]+)\)/i);
  if (!match) return { r: 255, g: 255, b: 255 };
  const parts = match[1].split(',').map((part) => part.trim());
  return {
    r: Number.parseFloat(parts[0]) || 255,
    g: Number.parseFloat(parts[1]) || 255,
    b: Number.parseFloat(parts[2]) || 255,
  };
};

const blendColors = (baseColor: string, tintColor: string, tintWeight: number) => {
  const base = parseColor(baseColor);
  const tint = parseColor(tintColor);
  const weight = Math.max(0, Math.min(1, tintWeight));
  const r = Math.round(base.r + (tint.r - base.r) * weight);
  const g = Math.round(base.g + (tint.g - base.g) * weight);
  const b = Math.round(base.b + (tint.b - base.b) * weight);
  return `rgb(${r}, ${g}, ${b})`;
};

const relativeLuminance = (value: string) => {
  const { r, g, b } = parseColor(value);
  const [nr, ng, nb] = [r, g, b].map((channel) => {
    const normalized = channel / 255;
    return normalized <= 0.03928
      ? normalized / 12.92
      : ((normalized + 0.055) / 1.055) ** 2.4;
  });
  return 0.2126 * nr + 0.7152 * ng + 0.0722 * nb;
};

const contrastRatio = (a: string, b: string) => {
  const l1 = relativeLuminance(a);
  const l2 = relativeLuminance(b);
  const lighter = Math.max(l1, l2);
  const darker = Math.min(l1, l2);
  return (lighter + 0.05) / (darker + 0.05);
};

const pickBestTextColor = (bgColor: string, candidates: string[]) => {
  let best = candidates[0];
  let bestRatio = contrastRatio(bgColor, best);
  for (let i = 1; i < candidates.length; i += 1) {
    const ratio = contrastRatio(bgColor, candidates[i]);
    if (ratio > bestRatio) {
      best = candidates[i];
      bestRatio = ratio;
    }
  }
  return best;
};

const chunkIntoRows = <T,>(items: T[], size = 2): T[][] => {
  const rows: T[][] = [];
  for (let i = 0; i < items.length; i += size) {
    rows.push(items.slice(i, i + size));
  }
  return rows;
};

export default function SearchScreen() {
  const {
    plants,
    isDarkMode,
    colorPalette,
    t,
    language,
    billingSummary,
    refreshBillingSummary,
  } = useApp();
  const colors = useColors(isDarkMode, colorPalette);
  const router = useRouter();
  const billingCopy = getBillingCopy(language);
  const availableCredits = billingSummary?.credits.available ?? 0;

  const [searchQuery, setSearchQuery] = useState('');
  const [debouncedQuery, setDebouncedQuery] = useState('');
  const [isDeepSearching, setIsDeepSearching] = useState(false);
  const [aiStatus, setAiStatus] = useState<SemanticSearchStatus | 'idle' | 'loading'>('idle');
  const [aiResults, setAiResults] = useState<DatabaseEntry[]>([]);

  useEffect(() => {
    const timer = setTimeout(() => {
      setDebouncedQuery(searchQuery.trim());
    }, SEARCH_DEBOUNCE_MS);

    return () => clearTimeout(timer);
  }, [searchQuery]);

  useEffect(() => {
    setAiStatus('idle');
    setAiResults([]);
  }, [debouncedQuery, language]);

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

  const getCategoryBackground = (baseTint: string, accent: string) => {
    return isDarkMode ? baseTint : blendColors(baseTint, accent, 0.2);
  };

  const getCategoryTextColor = (bgColor: string, accent: string) => {
    const tintedDark = blendColors(accent, '#000000', 0.58);
    const tintedLight = blendColors(accent, '#ffffff', 0.64);
    return pickBestTextColor(bgColor, [
      isDarkMode ? tintedLight : tintedDark,
      colors.text,
      colors.textOnImage,
    ]);
  };

  const categories = [
    { id: 'easy', name: t.catCareEasy, bg: getCategoryBackground(colors.successTint, colors.success), accent: colors.success },
    { id: 'low_light', name: t.catLowLight, bg: getCategoryBackground(colors.infoTint, colors.info), accent: colors.info },
    { id: 'bright_light', name: t.catBrightLight, bg: getCategoryBackground(colors.primaryTint, colors.primaryDark), accent: colors.primaryDark },
    { id: 'sun', name: t.catSun, bg: getCategoryBackground(colors.warningTint, colors.warning), accent: colors.warning },
    { id: 'pet_friendly', name: t.catPetFriendly, bg: getCategoryBackground(colors.dangerTint, colors.danger), accent: colors.danger },
    { id: 'air_purifier', name: t.catAirPurifier, bg: getCategoryBackground(colors.primaryTint, colors.primary), accent: colors.primary },
    { id: 'high_humidity', name: t.catHighHumidity, bg: getCategoryBackground(colors.infoTint, colors.info), accent: colors.info },
    { id: 'hanging', name: t.catHanging, bg: getCategoryBackground(colors.successTint, colors.success), accent: colors.success },
    { id: 'patterned', name: t.catPatterned, bg: getCategoryBackground(colors.dangerTint, colors.primaryDark), accent: colors.primaryDark },
    { id: 'flowering', name: t.catFlowering, bg: getCategoryBackground(colors.primaryTint, colors.primaryDark), accent: colors.primaryDark },
    { id: 'succulent', name: t.catSucculents, bg: getCategoryBackground(colors.warningTint, colors.warning), accent: colors.warning },
    { id: 'tree', name: t.catTree, bg: getCategoryBackground(colors.surfaceStrong, colors.textSecondary), accent: colors.textSecondary },
    { id: 'large', name: t.catLarge, bg: getCategoryBackground(colors.surface, colors.textMuted), accent: colors.textMuted },
    { id: 'medicinal', name: t.catMedicinal, bg: getCategoryBackground(colors.successTint, colors.success), accent: colors.success },
  ];

  const normalizedQuery = normalizeSearchText(debouncedQuery);
  const isResultMode = Boolean(normalizedQuery);

  const localResults = useMemo(() => {
    if (!normalizedQuery) {
      return [] as Plant[];
    }

    return rankHybridEntries(plants, normalizedQuery, 30)
      .map((entry) => entry.entry);
  }, [plants, normalizedQuery]);

  const [lexiconResults, setLexiconResults] = useState<DatabaseEntry[]>([]);

  useEffect(() => {
    if (!normalizedQuery) {
      setLexiconResults([]);
      return;
    }
    let isCancelled = false;
    PlantDatabaseService.searchPlants(normalizedQuery, language, {
      limit: 30,
    }).then((results) => {
      if (!isCancelled) setLexiconResults(results);
    }).catch(console.error);

    return () => {
      isCancelled = true;
    };
  }, [normalizedQuery, language]);

  const filteredAiResults = aiResults;

  const showAiSection = aiStatus !== 'idle' || filteredAiResults.length > 0;
  const canRunDeepSearch = (
    searchQuery.trim().length >= 3 &&
    !isDeepSearching &&
    availableCredits >= SEMANTIC_SEARCH_CREDIT_COST
  );

  const handleDeepSearch = async () => {
    const query = searchQuery.trim();
    if (query.length < 3) return;
    if (availableCredits < SEMANTIC_SEARCH_CREDIT_COST) {
      setAiStatus('insufficient_credits');
      setAiResults([]);
      return;
    }

    setIsDeepSearching(true);
    setAiStatus('loading');
    setAiResults([]);

    try {
      const response = await PlantDatabaseService.semanticSearchDetailed(query, language);
      setAiStatus(response.status);
      setAiResults(response.results);
    } catch (error) {
      console.error('Deep search failed', error);
      setAiStatus('provider_error');
      setAiResults([]);
    } finally {
      setIsDeepSearching(false);
      await refreshBillingSummary();
    }
  };

  const openCategoryLexicon = (categoryId: string, categoryName: string) => {
    router.push({
      pathname: '/lexicon',
      params: {
        categoryId,
        categoryLabel: encodeURIComponent(categoryName),
      },
    });
  };

  const clearAll = () => {
    setSearchQuery('');
    setDebouncedQuery('');
    setAiStatus('idle');
    setAiResults([]);
  };

  const openLexiconDetail = (entry: DatabaseEntry) => {
    router.push({
      pathname: '/lexicon',
      params: { detail: encodeURIComponent(JSON.stringify(entry)) },
    });
  };

  const renderGrid = (
    items: Array<Plant | DatabaseEntry>,
    type: 'local' | 'lexicon' | 'ai',
  ) => {
    const rows = chunkIntoRows(items, 2);

    return (
      <View style={styles.grid}>
        {rows.map((row, rowIndex) => (
          <View key={`${type}-row-${rowIndex}`} style={styles.gridRow}>
            {row.map((item, itemIndex) => (
              <View key={`${type}-${item.name}-${itemIndex}`} style={styles.cardWrapper}>
                <PlantCard
                  plant={item}
                  width={CARD_WIDTH}
                  onPress={() => {
                    if (type === 'local' && 'id' in item) {
                      router.push(`/plant/${item.id}`);
                      return;
                    }
                    openLexiconDetail(item as DatabaseEntry);
                  }}
                  t={t}
                  isDark={isDarkMode}
                  colorPalette={colorPalette}
                />
              </View>
            ))}
            {row.length === 1 ? <View style={styles.cardSpacer} /> : null}
          </View>
        ))}
      </View>
    );
  };

  const aiStatusText = (() => {
    if (aiStatus === 'loading') return t.searchAiLoading;
    if (aiStatus === 'timeout') return t.searchAiUnavailable;
    if (aiStatus === 'provider_error') return t.searchAiUnavailable;
    if (aiStatus === 'insufficient_credits') return billingCopy.insufficientCredits;
    if (aiStatus === 'no_results') return t.searchAiNoResults;
    return null;
  })();

  const SectionTitle = ({ label, count }: { label: string; count: number }) => (
    <View style={styles.sectionHeader}>
      <Text style={[styles.sectionTitle, { color: colors.text }]}>{label}</Text>
      <Text style={[styles.sectionCount, { color: colors.textSecondary }]}>{count}</Text>
    </View>
  );

  return (
    <SafeAreaView style={[styles.container, { backgroundColor: colors.background }]}>
      <ThemeBackdrop colors={colors} />

      <Text style={[styles.title, { color: colors.text }]}>{t.searchTitle}</Text>

      <View style={[styles.searchBar, { backgroundColor: colors.cardBg, borderColor: colors.cardBorder, shadowColor: colors.cardShadow }]}>
        <Ionicons name="search" size={20} color={colors.textMuted} />
        <TextInput
          style={[styles.searchInput, { color: colors.text }]}
          placeholder={t.searchPlaceholder}
          placeholderTextColor={colors.textMuted}
          value={searchQuery}
          onChangeText={setSearchQuery}
          autoCorrect={false}
          autoCapitalize="none"
          returnKeyType="search"
        />
        {searchQuery ? (
          <TouchableOpacity onPress={clearAll} hitSlop={8}>
            <Ionicons name="close" size={20} color={colors.textMuted} />
          </TouchableOpacity>
        ) : null}
      </View>

      <FlatList
        horizontal
        data={categories}
        keyExtractor={item => item.id}
        style={styles.chipsList}
        showsHorizontalScrollIndicator={false}
        contentContainerStyle={styles.chipsContent}
        renderItem={({ item }) => {
          return (
            <TouchableOpacity
              style={[
                styles.catChip,
                {
                  backgroundColor: item.bg,
                  borderColor: colors.chipBorder,
                },
              ]}
              onPress={() => openCategoryLexicon(item.id, item.name)}
              activeOpacity={0.8}
            >
              <Text style={[styles.catChipText, { color: getCategoryTextColor(item.bg, item.accent) }]}>
                {item.name}
              </Text>
            </TouchableOpacity>
          );
        }}
      />

      {searchQuery.trim().length >= 3 ? (
        <View style={styles.deepSearchWrap}>
          <TouchableOpacity
            style={[
              styles.deepSearchBtn,
              {
                backgroundColor: canRunDeepSearch ? colors.primary : colors.surfaceStrong,
                borderColor: canRunDeepSearch ? colors.primaryDark : colors.borderStrong,
                shadowColor: canRunDeepSearch ? colors.fabShadow : colors.cardShadow,
              },
            ]}
            onPress={handleDeepSearch}
            disabled={!canRunDeepSearch}
            activeOpacity={0.85}
          >
            <Ionicons
              name="sparkles"
              size={16}
              color={canRunDeepSearch ? colors.onPrimary : colors.textMuted}
            />
            <Text style={[styles.deepSearchText, { color: canRunDeepSearch ? colors.onPrimary : colors.textMuted }]}>
              {isDeepSearching ? t.searchAiLoading : t.searchDeepAction}
            </Text>
          </TouchableOpacity>

          <View style={styles.creditMetaRow}>
            <Text style={[styles.creditMetaText, { color: colors.textSecondary }]}>
              {billingCopy.creditsLabel}: {availableCredits}
            </Text>
            <Text style={[styles.creditMetaText, { color: colors.textMuted }]}>
              {billingCopy.deepSearchCost}
            </Text>
          </View>
        </View>
      ) : null}

      {isResultMode ? (
        <ScrollView style={styles.results} contentContainerStyle={styles.resultsContent} showsVerticalScrollIndicator={false}>
          <SectionTitle label={t.searchMyPlants} count={localResults.length} />
          {localResults.length > 0 ? (
            renderGrid(localResults, 'local')
          ) : (
            <Text style={[styles.emptyText, { color: colors.textSecondary }]}>{t.searchNoLocalResults}</Text>
          )}

          <SectionTitle label={t.searchLexicon} count={lexiconResults.length} />
          {lexiconResults.length > 0 ? (
            renderGrid(lexiconResults, 'lexicon')
          ) : (
            <Text style={[styles.emptyText, { color: colors.textSecondary }]}>{t.searchNoLexiconResults}</Text>
          )}

          {showAiSection ? (
            <View style={styles.aiSection}>
              <SectionTitle label={t.searchAiSection} count={filteredAiResults.length} />
              {aiStatus === 'loading' ? (
                <View style={styles.aiLoadingRow}>
                  <Ionicons name="sparkles" size={14} color={colors.primary} />
                  <Text style={[styles.aiStatusText, { color: colors.textSecondary }]}>{aiStatusText}</Text>
                </View>
              ) : filteredAiResults.length > 0 ? (
                renderGrid(filteredAiResults, 'ai')
              ) : aiStatusText ? (
                <View style={styles.aiStatusBlock}>
                  <Text style={[styles.emptyText, { color: colors.textSecondary }]}>{aiStatusText}</Text>
                  {aiStatus === 'insufficient_credits' ? (
                    <TouchableOpacity
                      style={[styles.managePlanBtn, { borderColor: colors.borderStrong, backgroundColor: colors.surfaceStrong }]}
                      onPress={() => router.push('/(tabs)/profile')}
                      activeOpacity={0.85}
                    >
                      <Text style={[styles.managePlanText, { color: colors.text }]}>{billingCopy.managePlan}</Text>
                    </TouchableOpacity>
                  ) : null}
                </View>
              ) : null}
            </View>
          ) : null}
        </ScrollView>
      ) : (
        <ScrollView
          style={styles.results}
          contentContainerStyle={styles.discoveryContent}
          showsVerticalScrollIndicator={false}
        >
          <TouchableOpacity
            style={[styles.lexiconBanner, { backgroundColor: colors.primaryDark }]}
            activeOpacity={0.85}
            onPress={() => router.push('/lexicon')}
          >
            <Ionicons name="book-outline" size={20} color={colors.iconOnImage} />
            <Text style={[styles.lexiconTitle, { color: colors.iconOnImage }]}>{t.lexiconTitle}</Text>
            <Text style={[styles.lexiconDesc, { color: colors.heroButton }]}>{t.lexiconDesc}</Text>
            <View style={[styles.lexiconBadge, { backgroundColor: colors.heroButtonBorder }]}>
              <Text style={[styles.lexiconBadgeText, { color: colors.iconOnImage }]}>{t.browseLexicon}</Text>
            </View>
          </TouchableOpacity>
        </ScrollView>
      )}
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, paddingHorizontal: 20 },
  title: { fontSize: 23, fontWeight: '700', letterSpacing: 0.2, marginTop: 12, marginBottom: 16 },
  searchBar: {
    flexDirection: 'row',
    alignItems: 'center',
    borderWidth: 1,
    borderRadius: 16,
    paddingHorizontal: 14,
    paddingVertical: 10,
    gap: 10,
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.14,
    shadowRadius: 8,
    elevation: 2,
  },
  searchInput: { flex: 1, fontSize: 15 },
  chipsList: { marginTop: 10, height: 50, maxHeight: 50 },
  chipsContent: { gap: 8, paddingRight: 4, paddingVertical: 1, alignItems: 'center' },
  catChip: {
    height: 40,
    paddingHorizontal: 14,
    paddingVertical: 0,
    borderRadius: 20,
    justifyContent: 'center',
    alignItems: 'center',
    borderWidth: 1,
  },
  catChipText: {
    fontSize: 12.5,
    lineHeight: 18,
    fontWeight: '700',
    includeFontPadding: false,
  },
  deepSearchBtn: {
    marginTop: 12,
    flexDirection: 'row',
    alignItems: 'center',
    alignSelf: 'flex-start',
    gap: 8,
    paddingHorizontal: 11,
    paddingVertical: 6,
    borderRadius: 10,
    borderWidth: 1,
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.16,
    shadowRadius: 6,
    elevation: 2,
  },
  deepSearchWrap: {
    marginTop: 12,
    gap: 6,
    alignSelf: 'flex-start',
  },
  deepSearchText: { fontSize: 12, fontWeight: '700' },
  creditMetaRow: {
    gap: 1,
    marginLeft: 2,
  },
  creditMetaText: {
    fontSize: 11,
    fontWeight: '600',
  },
  results: { marginTop: 14 },
  resultsContent: { paddingBottom: 110 },
  sectionHeader: {
    marginBottom: 10,
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
  },
  sectionTitle: { fontSize: 15, fontWeight: '600' },
  sectionCount: { fontSize: 13, fontWeight: '500' },
  grid: { marginBottom: 18 },
  gridRow: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    marginBottom: CARD_GAP,
  },
  cardWrapper: { width: CARD_WIDTH },
  cardSpacer: { width: CARD_WIDTH },
  emptyText: { marginBottom: 18, fontSize: 14, lineHeight: 20 },
  aiSection: { marginTop: 2 },
  aiStatusBlock: { marginBottom: 18 },
  aiLoadingRow: { flexDirection: 'row', alignItems: 'center', gap: 8, marginBottom: 18 },
  aiStatusText: { fontSize: 13, fontWeight: '500' },
  managePlanBtn: {
    alignSelf: 'flex-start',
    borderWidth: 1,
    borderRadius: 10,
    paddingHorizontal: 10,
    paddingVertical: 6,
    marginTop: -8,
  },
  managePlanText: { fontSize: 12, fontWeight: '700' },
  discoveryContent: { paddingTop: 16, paddingBottom: 120 },
  lexiconBanner: {
    marginTop: 8,
    padding: 18,
    borderRadius: 18,
    gap: 4,
  },
  lexiconTitle: { fontSize: 18, fontWeight: '700' },
  lexiconDesc: { fontSize: 12 },
  lexiconBadge: {
    marginTop: 8,
    paddingHorizontal: 12,
    paddingVertical: 5,
    borderRadius: 20,
    alignSelf: 'flex-start',
  },
  lexiconBadgeText: { fontSize: 11, fontWeight: '700' },
});
