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 { TabView, TabBar } from 'react-native-tab-view';

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';

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(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: 'new', title: 'New' },
    { key: 'unchecked', title: 'Unchecked' },
    { key: 'checked', title: 'Checked' }
  ]);

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

    switch (index) {
      case 1:
        dataToFilter = filteredData[routes[index].key];
        break;
      case 2:
        dataToFilter = dataToFilter
          .map((group) => ({
            ...group,
            items: group.items.filter((item) => !item.checked)
          }))
          .filter((group) => group.items.length > 0);
        break;
      case 3:
        dataToFilter = dataToFilter
          .map((group) => ({
            ...group,
            items: group.items.filter((item) => item.checked)
          }))
          .filter((group) => group.items.length > 0);
        break;
      default:
        break;
    }

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

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

  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 }}
        data={activeFilteredData}
        renderItem={({ item }) => (
          <AccordionListItem
            item={item}
            onCheckboxChange={handleCheckboxChange}
            setIsInfoModalVisible={setIsInfoModalVisible}
            setInfoItem={setInfoItem}
            isSeries={id === -1}
          />
        )}
      />
    );
  };

  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 groupIndex = currentData.findIndex((group) => group.name === groupName);

        if (groupIndex === -1) return currentData;

        const newData = [...currentData];
        const newGroup = { ...newData[groupIndex] };

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

        newData[groupIndex] = newGroup;

        return newData;
      });

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

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

  return (
    <PageWrapper>
      <Header label={name} />
      <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'}
      />
      <Input
        inputMode={'search'}
        placeholder={'Search'}
        onChange={(text) => setSearch(text)}
        value={search}
        icon={<SearchIcon fill={'#C8C8C8'} width={14} height={14} />}
      />
      <TabView
        navigationState={{ index, routes }}
        renderScene={renderScene}
        onIndexChange={(i) => {
          handleIndexChange(i);
          setIndex(i);
        }}
        lazy={true}
        renderTabBar={(props) => (
          <TabBar
            {...props}
            indicatorStyle={{ backgroundColor: Colors.DARK_BLUE }}
            style={styles.tabBar}
            tabStyle={styles.tabStyle}
            pressColor={'transparent'}
            renderLabel={({ route, focused }) => (
              <Text
                style={[styles.tabLabel, { color: Colors.DARK_BLUE, opacity: focused ? 1 : 0.4 }]}
              >
                {route.title}
              </Text>
            )}
          />
        )}
      />
    </PageWrapper>
  );
};
