import { AutoCompleteItem } from "@/apis/autoCompleteApi";
import { Season } from "@/apis/seasonApi";
import { Show } from "@/apis/showApi";
import styles from "@/app/tabStyles/indexStyles";
import ShowBox from "@/components/discovery/ShowBox";
import { useDiscoveryContext } from "@/contexts/DiscoveryContext";
import { FontAwesome } from "@expo/vector-icons";
import Feather from "@expo/vector-icons/Feather";
import React from "react";
import {
  Keyboard,
  ScrollView,
  Text,
  TextInput,
  TouchableOpacity,
  TouchableWithoutFeedback,
  View,
} from "react-native";

import { getShowById } from "@/apis/showApi";
import PersonRow from "@/components/discovery/PersonRow";
import SeasonCarousel from "@/components/discovery/SeasonCarousel";
import TagChip from "@/components/discovery/TagChip";
import { useSearch } from "@/hooks/useSearch";
import {
  getIconName,
  mapApiPersonToUI,
  mapApiSeasonToUI,
  mapApiShowToUI,
} from "@/utils/searchMapping";

export default function ExploreScreen() {
  const { query, setQuery, suggestions } = useDiscoveryContext();

  const [tags, setTags] = React.useState<AutoCompleteItem[]>([]);
  const tagStrings = React.useMemo(() => tags.map((t) => t.text), [tags]);

  const {
    data: results = [],
    error,
    refetch,
    // isLoading, // optional, falls benötigt
  } = useSearch(tagStrings as string[]);

  // Lokaler Show-Cache
  const [showsById, setShowsById] = React.useState<Record<number, Show>>({});

  // Steuerung für Vorschlagsliste
  const [showSuggestions, setShowSuggestions] = React.useState(false);

  function tagAdded(tag: AutoCompleteItem) {
    const nextTags = tags.some((t) => t.text === tag.text) ? tags : [...tags, tag];
    setTags(nextTags);
    setQuery("");
    setShowSuggestions(false);
    Keyboard.dismiss();
  }

  function tagRemoved(tag: AutoCompleteItem) {
    const nextTags = tags.filter((t) => t.text !== tag.text);
    setTags(nextTags);
  }

  // Cache mit SHOW-Resultaten füllen
  React.useEffect(() => {
    const fromResults: Record<number, Show> = {};
    for (const r of results) {
      if (r.type === "SHOW") {
        const uiShow = mapApiShowToUI(r.data);
        if (uiShow.showId != null) fromResults[Number(uiShow.showId)] = uiShow as Show;
      }
    }
    if (Object.keys(fromResults).length) {
      setShowsById((prev) => ({ ...prev, ...fromResults }));
    }
  }, [results]);

  // SEASON-Ergebnisse nach showId gruppieren
  const seasonsByShowId = React.useMemo(() => {
    const map = new Map<number, Season[]>();
    for (const r of results) {
      if (r.type !== "SEASON") continue;
      const s = mapApiSeasonToUI(r.data);
      if (!s || s.showId == null) continue;
      const key = Number(s.showId);
      const list = map.get(key) ?? [];
      list.push(s as Season);
      map.set(key, list);
    }
    for (const [k, list] of map) {
      list.sort((a, b) => {
        const da = a?.startDate ? new Date(a.startDate).getTime() : Number.POSITIVE_INFINITY;
        const db = b?.startDate ? new Date(b.startDate).getTime() : Number.POSITIVE_INFINITY;
        return da - db;
      });
      map.set(k, list);
    }
    return map;
  }, [results]);

  // Fehlende Shows für Carousels nachladen
  React.useEffect(() => {
    const needed = Array.from(seasonsByShowId.keys()).filter((id) => !showsById[id]);
    if (needed.length === 0) return;

    let cancelled = false;
    (async () => {
      try {
        const fetched = await Promise.all(needed.map((id) => getShowById(id)));
        if (cancelled) return;

        const next: Record<number, Show> = {};
        for (const s of fetched) {
          if (!s) continue;
          next[s.id] = s;
        }
        if (Object.keys(next).length) {
          setShowsById((prev) => ({ ...prev, ...next }));
        }
      } catch (e) {
        console.error(e);
      }
    })();

    return () => {
      cancelled = true;
    };
  }, [seasonsByShowId, showsById]);

  // PERSON-Resultate
  const persons = React.useMemo(() => {
    return results
      .filter((r) => r.type === "PERSON")
      .map((r) => mapApiPersonToUI(r.data))
      .sort((a, b) => (a.name || "").localeCompare(b.name || ""));
  }, [results]);

  // Moderner Fehlerblock
  if (error) {
    return (
      <View
        style={[
          styles.mainContainer,
          { justifyContent: "center", alignItems: "center", padding: 20 },
        ]}
      >
        <View
          style={{
            alignItems: "center",
            gap: 12,
            backgroundColor: "rgba(255,255,255,0.05)",
            paddingVertical: 24,
            paddingHorizontal: 20,
            borderRadius: 12,
            width: "85%",
          }}
        >
          <Text style={{ fontSize: 36 }}>⚠️</Text>
          <Text
            style={{
              fontSize: 18,
              fontWeight: "600",
              color: "white",
              textAlign: "center",
            }}
          >
            Fehler beim Laden
          </Text>
          <Text
            style={{
              fontSize: 14,
              color: "rgba(255,255,255,0.6)",
              textAlign: "center",
            }}
          >
            {error?.message || "Ein unerwarteter Fehler ist aufgetreten."}
          </Text>

          <TouchableOpacity
            onPress={() => {
              if (typeof refetch === "function") refetch();
            }}
            style={{
              marginTop: 6,
              backgroundColor: "rgba(255,255,255,0.15)",
              paddingVertical: 10,
              paddingHorizontal: 18,
              borderRadius: 8,
            }}
          >
            <Text style={{ color: "white", fontWeight: "600" }}>Erneut versuchen</Text>
          </TouchableOpacity>
        </View>
      </View>
    );
  }

  const noResults = persons.length === 0 && seasonsByShowId.size === 0;

  return (
    <View style={[styles.mainContainer]}>
      <View style={styles.header}>
        <Text style={[styles.title, { fontSize: 28 }]}>Durchsuchen</Text>
      </View>

      <TouchableWithoutFeedback
        onPress={() => {
          Keyboard.dismiss();
          setShowSuggestions(false);
        }}
      >
        <View style={{ flex: 1 }}>
          <View style={styles.sectionContainer}>
            <View style={styles.searchContainer}>
              <TextInput
                value={query}
                autoComplete="off"
                autoCorrect={false}
                onChangeText={(t) => {
                  setQuery(t);
                  if (t.length > 0 && !showSuggestions) setShowSuggestions(true);
                  if (t.length === 0) setShowSuggestions(false);
                }}
                placeholder="Wonach suchst du?"
                placeholderTextColor=""
                style={styles.searchInput}
                returnKeyType="search"
                onFocus={() => setShowSuggestions(true)}
                onSubmitEditing={() => {
                  if (!query.trim()) return;
                  tagAdded({ type: "CUSTOM", text: query.trim() });
                }}
                autoCapitalize="none"
              />

              {query.length === 0 ? (
                <Feather name="search" size={24} color="hsl(221, 39%, 80%)" />
              ) : (
                <Feather
                  name="x"
                  size={24}
                  color="hsl(221, 39%, 80%)"
                  onPress={() => {
                    setQuery("");
                    setShowSuggestions(false);
                  }}
                />
              )}
            </View>

            <View style={styles.tagContainer}>
              {tags.map((tag) => (
                <TagChip
                  key={tag.text}
                  icon={getIconName(tag.type)}
                  label={tag.text}
                  onPress={() => {
                    tagRemoved(tag);
                  }}
                />
              ))}
            </View>

            {/* Suggestions dropdown */}
            {query.length > 0 && showSuggestions && (
              <View style={styles.suggestionsSection}>
                <Text style={styles.suggestionTitle}>Suchvorschläge</Text>
                <ScrollView keyboardShouldPersistTaps="handled">
                  {suggestions.map((suggestion, idx) => (
                    <TouchableOpacity
                      key={suggestion.text + "_" + idx}
                      style={styles.suggestionContainer}
                      onPress={() => tagAdded(suggestion)}
                    >
                      <FontAwesome
                        name={getIconName(suggestion.type)}
                        size={16}
                        color="hsl(0, 0%, 90%)"
                      />
                      <Text style={styles.suggestionLabel}>
                        {suggestion.text}
                      </Text>
                    </TouchableOpacity>
                  ))}
                </ScrollView>
              </View>
            )}
          </View>

          {/* Results */}
          <View style={{ flex: 1 }}>
            <ScrollView keyboardShouldPersistTaps="handled">
              {/* Personen Section (top) */}
              {persons.length > 0 && (
                <View style={styles.sectionContainer}>
                  <Text style={styles.sectionTitle}>Personen</Text>
                  {persons.slice(0, 5).map((p) => (
                    <PersonRow key={`p-${p.personId ?? p.id}`} person={p} />
                  ))}
                </View>
              )}

              <View style={styles.sectionContainer}>
                {seasonsByShowId.size > 0 && (
                  <Text style={styles.sectionTitle}>Staffeln</Text>
                )}

                {Array.from(seasonsByShowId.entries()).map(([showId, seasons]) => {
                  const show = showsById[Number(showId)];
                  if (!seasons || seasons.length === 0) return null;

                  if (!show) {
                    return (
                      <SeasonCarousel
                        key={`sc-${showId}`}
                        show={
                          {
                            showId: showId as any,
                            title: "blaaa",
                            description: "",
                            genre: "",
                            thumbnailUrl: "",
                            running: false,
                          } as any
                        }
                        seasons={seasons}
                        renderItem={(s) => (
                          <ShowBox
                            show={
                              {
                                showId: showId as any,
                                title: `Show #${showId}`,
                                description: "",
                                genre: "",
                                thumbnailUrl: "",
                                running: false,
                              } as any
                            }
                            displayedSeason={s}
                            shadow={false}
                          />
                        )}
                      />
                    );
                  }
                  return (
                    <SeasonCarousel
                      key={`sc-${showId}`}
                      show={show}
                      seasons={seasons}
                      renderItem={(s) => (
                        <ShowBox show={show} displayedSeason={s} shadow={false} />
                      )}
                    />
                  );
                })}

                {/* Schöner Empty-State */}
                {noResults && (
                  <View
                    style={{
                      alignItems: "center",
                      justifyContent: "center",
                      gap: 12,
                      backgroundColor: "rgba(255,255,255,0.04)",
                      paddingVertical: 28,
                      paddingHorizontal: 20,
                      borderRadius: 12,
                      marginTop: 8,
                    }}
                  >
                    <Feather
                      name="search"
                      size={36}
                      color="rgba(255,255,255,0.9)"
                    />
                    <Text
                      style={{
                        fontSize: 18,
                        fontWeight: "600",
                        color: "white",
                        textAlign: "center",
                      }}
                    >
                      Keine Ergebnisse gefunden
                    </Text>
                    <Text
                      style={{
                        fontSize: 14,
                        color: "rgba(255,255,255,0.7)",
                        textAlign: "center",
                      }}
                    >
                      Passen Sie Ihre Tags an oder setzen Sie die Filter zurück.
                    </Text>

                    <View style={{ flexDirection: "row", gap: 10, marginTop: 4 }}>
                      <TouchableOpacity
                        onPress={() => {
                          setTags([]);
                          setQuery("");
                          setShowSuggestions(false);
                          Keyboard.dismiss();
                          if (typeof refetch === "function") refetch();
                        }}
                        style={{
                          backgroundColor: "rgba(255,255,255,0.15)",
                          paddingVertical: 10,
                          paddingHorizontal: 14,
                          borderRadius: 8,
                        }}
                      >
                        <Text style={{ color: "white", fontWeight: "600" }}>
                          Filter zurücksetzen
                        </Text>
                      </TouchableOpacity>

                      <TouchableOpacity
                        onPress={() => {
                          setQuery("");
                          setShowSuggestions(false);
                          Keyboard.dismiss();
                        }}
                        style={{
                          backgroundColor: "rgba(255,255,255,0.08)",
                          paddingVertical: 10,
                          paddingHorizontal: 14,
                          borderRadius: 8,
                        }}
                      >
                        <Text style={{ color: "white" }}>Eingabe löschen</Text>
                      </TouchableOpacity>
                    </View>
                  </View>
                )}
              </View>
            </ScrollView>
          </View>
        </View>
      </TouchableWithoutFeedback>
    </View>
  );
}
