import React, { useCallback, useEffect, useState } from 'react';
import { useFocusEffect } from '@react-navigation/native';
import { View, Text, FlatList } from 'react-native';
import { Button, Header, Input, Loading, Modal, PageWrapper } from 'src/components';

import SearchIcon from '../../../../../assets/icons/search.svg';
import { fetchItemsForSeries, usePostSetToggleItem } from '@api/series';
import { Colors } from 'src/theme';
import { ButtonVariants } from 'src/types/components';
import { AccordionListItem } from '../Components/AccordionListItem';

import { styles } from './styles';
import TabViewWrapper from 'src/components/TabViewWrapper';
import { SafeAreaView } from 'react-native-safe-area-context';

interface SeriesItem {
  series_id: number;
  item_id: number;
  icon: string | null;
  name: string;
  readonly: boolean;
  info: string;
  new: boolean;
  checked: boolean;
  checked_double: boolean;
  double: boolean;
}

interface SeriesGroup {
  name: string;
  icon: string;
  series_id: number;
  series_name: string;
  items: SeriesItem[];
}

interface FilteredData {
  [key: string]: SeriesGroup[];
}

interface Route {
  key: string;
  title: string;
}

export const SeriesItemScreen = ({ route }: { route: any }) => {
  const { id, name, token } = route.params;
  const { mutate: updateSeriesItem } = usePostSetToggleItem();

  const [search, setSearch] = useState<string>('');
  const [filteredData, setFilteredData] = useState<FilteredData>({});
  const [seriesData, setSeriesData] = useState<SeriesGroup[]>([]);
  const [index, setIndex] = useState<number>(0);
  const [isLoading, setIsLoading] = useState<boolean>(true);
  const [isInfoModalVisible, setIsInfoModalVisible] = useState<boolean>(false);
  const [infoItem, setInfoItem] = useState<SeriesItem | null>(null);
  const [activeFilteredData, setActiveFilteredData] = useState<SeriesGroup[]>([]);

  useFocusEffect(
    useCallback(() => {
      const fetchGroups = async () => {
        const data = await fetchItemsForSeries(String(token), id);
        if (!data) {
          setIsLoading(false);
          return;
        }
        const allItems = data.groups;
        const newItems = data.groups
          .map((group) => ({
            ...group,
            items: group.items.filter((item) => item.new)
          }))
          .filter((group) => group.items.length > 0);

        setFilteredData({ all: allItems, new: newItems, unchecked: [], checked: [] });
        setSeriesData(data.groups);
        setIsLoading(false);
      };

      fetchGroups();
    }, [])
  );

  const [routes] = useState([
    { key: 'all', title: 'All items' },
    { key: 'checked', title: 'Ticked' },
    { key: 'unchecked', title: 'Unticked' },
    { key: 'new', title: 'New' }
  ]);

  const handleIndexChange = (index: number) => {
    let dataToFilter = [...seriesData];

    switch (index) {
      case 3:
        dataToFilter = dataToFilter
          .map((group) => ({
            ...group,
            items: group.items.filter((item) => item.new)
          }))
          .filter((group) => group.items.length > 0);

        break;
      case 2:
        dataToFilter = dataToFilter
          .map((group) => ({
            ...group,
            items: group.items.filter(
              (item) => !item.checked || (item.double && !item.checked_double)
            )
          }))
          .filter((group) => group.items.length > 0);
        break;
      case 1:
        dataToFilter = dataToFilter
          .map((group) => ({
            ...group,
            items: group.items.filter(
              (item) => item.checked || (item.double && item.checked_double)
            )
          }))
          .filter((group) => group.items.length > 0);
        break;
      default:
        break;
    }

    setActiveFilteredData(dataToFilter);
    setFilteredData((prevState) => ({
      ...prevState,
      [routes[index].key]: dataToFilter
    }));
  };

  useEffect(() => {
    handleIndexChange(index);
  }, [seriesData, index]);

  useEffect(() => {
    setActiveFilteredData(filteredData[routes[index].key]);
  }, [filteredData]);

  const renderScene = ({ route }: { route: Route }) => {
    return isLoading ? (
      <Loading />
    ) : (
      <FlatList
        key={routes[index].key}
        keyExtractor={(item, index) => index.toString()}
        showsVerticalScrollIndicator={false}
        initialNumToRender={15}
        style={{ paddingTop: 10 }}
        contentContainerStyle={{ paddingBottom: 16 }}
        data={activeFilteredData}
        renderItem={({ item }) => (
          <AccordionListItem
            item={item}
            onCheckboxChange={handleCheckboxChange}
            setIsInfoModalVisible={setIsInfoModalVisible}
            setInfoItem={setInfoItem}
            isSeries={id === -1}
            token={token}
          />
        )}
      />
    );
  };

  useEffect(() => {
    const searchText = search.toLowerCase();
    const searchData = filteredData[routes[index].key]
      ?.map((group) => {
        const groupNameMatch = group.name.toLowerCase().includes(searchText);
        if (groupNameMatch) {
          return group;
        } else {
          const filteredItems = group.items.filter((item) =>
            item.name.toLowerCase().includes(searchText)
          );
          return filteredItems.length > 0 ? { ...group, items: filteredItems } : null;
        }
      })
      .filter((group) => group !== null);

    setActiveFilteredData(searchData as SeriesGroup[]);
  }, [search]);

  const handleCheckboxChange = useCallback(
    async (item: SeriesItem, groupName: string, double?: boolean) => {
      setSeriesData((currentData) => {
        const newData = currentData.map((group) => {
          const hasItem = group.items.some((subItem) => subItem.item_id === item.item_id);
          if (!hasItem) return group;

          return {
            ...group,
            items: group.items.map((subItem) =>
              subItem.item_id === item.item_id
                ? {
                  ...subItem,
                  ...(double
                    ? { checked_double: !subItem.checked_double }
                    : { checked: !subItem.checked })
                }
                : subItem
            )
          };
        });

        return newData;
      });

      const itemData = {
        token: token,
        series_id: item.series_id,
        item_id: item.item_id,
        checked: double ? (item.checked_double ? 0 : 1) : (item.checked ? 0 : 1) as 0 | 1,
        double: (double ? 1 : 0) as 0 | 1
      };

      try {
        updateSeriesItem(itemData);
      } catch (error) {
        console.error('Failed to update checkbox state', error);
      }
    },
    [token, updateSeriesItem]
  );

  return (
    <SafeAreaView style={{ height: '100%' }} edges={['top']}>
      <View style={{ marginLeft: '5%', marginRight: '5%' }}>
        <Header label={name} />
        <Input
          inputMode={'search'}
          placeholder={'Search'}
          onChange={(text) => setSearch(text)}
          value={search}
          icon={<SearchIcon fill={'#C8C8C8'} width={14} height={14} />}
        />
      </View>
      <Modal
        visible={isInfoModalVisible}
        children={
          <View style={styles.modalView}>
            <Text style={styles.infoTitle}>{infoItem?.name}</Text>
            <Text style={styles.infoText}>{infoItem?.info}</Text>
            <Button
              variant={ButtonVariants.OPACITY}
              containerStyles={styles.btnContainer}
              textStyles={{
                color: Colors.DARK_BLUE
              }}
              onPress={() => setIsInfoModalVisible(false)}
              children={'Got it'}
            />
          </View>
        }
        onRequestClose={() => setIsInfoModalVisible(false)}
        headerTitle={'Info'}
        visibleInPercent={'auto'}
      />

      {token ? (
        <TabViewWrapper
          routes={routes}
          renderScene={renderScene as never}
          setIndex={setIndex}
          lazy={false}
          selectedIndex={index}
        />
      ) : (
        <View style={{ paddingTop: 8, flex: 1, marginHorizontal: '5%' }}>
          {renderScene({ route: routes[index] })}
        </View>
      )}
    </SafeAreaView>
  );
};
