import { useState, useEffect, useMemo, useCallback } from "react";
import {
  View,
  Text,
  TouchableOpacity,
  FlatList,
  Platform,
  useWindowDimensions,
  ScrollView,
} from "react-native";
import { Portal } from "react-native-paper";
import { Ionicons } from "@expo/vector-icons";

import { useLazyQuickSearchQuery, SearchResult } from "@/store/api/searchApi";
import { useAppSelector } from "@/store/hooks";
import { selectSidebarCollapsed } from "@/store/screen/screenSizeSlice";

interface SearchDropdownProps {
  searchQuery: string;
  onResultSelect: (result: SearchResult) => void;
  onViewAllResults: (query: string) => void;
}

const getIconName = (type: SearchResult["type"]) => {
  switch (type) {
    case "user":
      return "person-outline";
    case "admin":
      return "shield-outline";
    case "todo":
      return "list-outline";
    default:
      return "search-outline";
  }
};

const getResultTypeLabel = (type: SearchResult["type"]) => {
  switch (type) {
    case "user":
      return "User";
    case "admin":
      return "Admin";
    case "todo":
      return "Todo";
    default:
      return "Result";
  }
};

export const SearchDropdown = ({
  searchQuery,
  onResultSelect,
  onViewAllResults,
}: SearchDropdownProps) => {
  const [isVisible, setIsVisible] = useState(false);
  const containerId = "global-search-dropdown";
  const { width: windowWidth, height: windowHeight } = useWindowDimensions();
  const sidebarCollapsed = useAppSelector(selectSidebarCollapsed);

  const [triggerSearch, { data, isLoading, error }] = useLazyQuickSearchQuery();

  // Fetch results when query changes
  useEffect(() => {
    if (searchQuery && searchQuery.trim().length >= 2) {
      triggerSearch({ q: searchQuery })
        .unwrap()
        .then(() => setIsVisible(true))
        .catch(() => setIsVisible(false));
    } else {
      setIsVisible(false);
    }
  }, [searchQuery, triggerSearch]);

  // Hide if query cleared
  useEffect(() => {
    if (!searchQuery.trim()) setIsVisible(false);
  }, [searchQuery]);

  // Close dropdown on outside click (web only)
  useEffect(() => {
    if (!isVisible || Platform.OS !== "web") return;

    const handler = (e: MouseEvent | TouchEvent) => {
      const el = document.getElementById(containerId);
      if (!el) return;
      if (e.target instanceof Node && !el.contains(e.target)) {
        setIsVisible(false);
      }
    };

    document.addEventListener("mousedown", handler);
    document.addEventListener("touchstart", handler, { passive: true });

    return () => {
      document.removeEventListener("mousedown", handler);
      document.removeEventListener("touchstart", handler);
    };
  }, [isVisible]);

  // Group results memoized
  const groupedResults = useMemo(() => {
    if (!data?.results) return [];
    const groups: { type: string; items: SearchResult[] }[] = [];
    const map: Record<string, SearchResult[]> = {};
    data.results.forEach((r) => {
      (map[r.type] ||= []).push(r);
    });
    for (const [type, items] of Object.entries(map)) {
      groups.push({ type, items });
    }
    return groups;
  }, [data?.results]);

  const renderGroupHeader = useCallback(
    ({ type, items }: { type: string; items: SearchResult[] }) => (
      <View>
        <View className="p-2 bg-gray-50 border-b border-gray-200 flex-row items-center">
          <Ionicons
            name={getIconName(type as SearchResult["type"])}
            size={14}
            color="#6b7280"
            style={{ marginRight: 4 }}
          />
          <Text className="font-bold text-xs text-gray-700 uppercase tracking-wider">
            {getResultTypeLabel(type as SearchResult["type"])}s ({items.length})
          </Text>
        </View>
        <FlatList
          data={items}
          keyExtractor={(r) => `${r.type}-${r.id}`}
          renderItem={({ item }) => (
            <TouchableOpacity
              className="flex-row items-center p-3 border-b border-gray-100"
              onPress={() => {
                setIsVisible(false);
                onResultSelect(item);
              }}
            >
              <View className="flex-1 pl-6">
                <Text className="font-semibold text-gray-900" numberOfLines={1}>
                  {item.title}
                </Text>
                {item.subtitle ? (
                  <Text
                    className="text-sm text-gray-600 mb-1"
                    numberOfLines={1}
                  >
                    {item.subtitle}
                  </Text>
                ) : null}
                {item.description ? (
                  <Text className="text-xs text-gray-500" numberOfLines={1}>
                    {item.description}
                  </Text>
                ) : null}
              </View>
            </TouchableOpacity>
          )}
        />
      </View>
    ),
    [onResultSelect]
  );

  if (!isVisible || !searchQuery || searchQuery.length < 2) return null;

  // Calculate dropdown positioning based on sidebar and content area
  // Sidebar widths: collapsed = 80px, expanded = 200px
  // We want dropdown to span from sidebar edge to content area with padding
  const sidebarWidth = sidebarCollapsed ? 80 : 200;
  const contentPadding = 20;
  const rightPadding = 4;
  const leftOffset = sidebarWidth + contentPadding;
  const dropdownWidth = windowWidth - leftOffset - rightPadding - 16;

  // Calculate max height: leave space at bottom (48px from top + some bottom margin)
  const maxDropdownHeight = windowHeight - 48 - 32;

  // For empty results, make it narrower and align to the right
  const isEmpty = data && data.results.length === 0 && !isLoading;

  return (
    <Portal>
      <View
        className="absolute top-12 bg-white rounded-md shadow-lg z-50 p-2"
        style={{
          left: leftOffset,
          right: rightPadding + 16,
          width: dropdownWidth,
          maxWidth: dropdownWidth,
          zIndex: 9999,
        }}
        nativeID={containerId}
      >
        {isLoading && (
          <View className="p-4">
            <Text className="text-gray-500 text-center">Searching...</Text>
          </View>
        )}

        {error && (
          <View className="p-4">
            <Text className="text-red-500 text-center">Search failed</Text>
          </View>
        )}

        {isEmpty && (
          <View className="p-4">
            <Text className="text-gray-500 text-center">
              No results found for &quot;{searchQuery}&quot;
            </Text>
          </View>
        )}

        {groupedResults.length > 0 && (
          <ScrollView
            style={{ maxHeight: maxDropdownHeight }}
            showsVerticalScrollIndicator={true}
          >
            <FlatList
              data={groupedResults}
              keyExtractor={(g) => g.type}
              renderItem={({ item }) => renderGroupHeader(item)}
              scrollEnabled={false}
              ListFooterComponent={
                <TouchableOpacity
                  className="p-3 border-t border-gray-200 bg-gray-50"
                  onPress={() => {
                    setIsVisible(false);
                    onViewAllResults(searchQuery);
                  }}
                >
                  <Text className="text-center text-blue-600 font-medium">
                    View all results for &quot;{searchQuery}&quot;
                  </Text>
                </TouchableOpacity>
              }
            />
          </ScrollView>
        )}
      </View>
    </Portal>
  );
};
