import React, { useCallback, useEffect, useState } from 'react';
import { View, Text, TouchableOpacity, FlatList } from 'react-native';
import { useFocusEffect, useNavigation } from '@react-navigation/native';
import * as ImagePicker from 'expo-image-picker';

import { PageWrapper, Header, Modal, FlatList as List, Loading } from 'src/components';
import { PhotoItem, CustomButton } from '../Components';
import { useGetPhotosForUserQuery, useGetTempQuery } from '@api/photos';
import { StoreType, storage } from 'src/storage';

import { AllRegions, ByDateData, ByRegionData, PhotosData } from '../utils/types';
import { compareDates, groupByDate } from '../utils';
import { NAVIGATION_PAGES } from 'src/types';
import { Colors } from 'src/theme';
import { styles } from './styles';

import AddImgSvg from '../../../../../assets/icons/travels-screens/add-img.svg';
import ChevronIcon from '../../../../../assets/icons/travels-screens/chevron-bottom.svg';

const ByRegionContent = ({
  data,
  allRegions
}: {
  data: ByRegionData[];
  allRegions: AllRegions[];
}) => {
  const [loading, setLoading] = useState(true);
  const [visible, setVisible] = useState(false);
  const [selectedRegion, setSelectedRegion] = useState<ByRegionData>();
  const [photos, setPhotos] = useState<ByRegionData[]>([]);

  useEffect(() => {
    if (selectedRegion?.country === 'All Regions') {
      setPhotos(data);
    } else {
      setPhotos(
        data.filter(
          (item) => item.country === selectedRegion?.country && item.name === selectedRegion?.name
        )
      );
    }
  }, [selectedRegion]);

  useFocusEffect(
    useCallback(() => {
      setPhotos(data);
      setLoading(false);
    }, [data])
  );

  if (loading) return <Loading />;

  return (
    <View style={{ flex: 1 }}>
      <TouchableOpacity style={styles.regionSelector} onPress={() => setVisible(true)}>
        <Text style={styles.regionText}>{selectedRegion?.country ?? 'All Regions'}</Text>
        <ChevronIcon />
      </TouchableOpacity>
      <Modal
        onRequestClose={() => setVisible(false)}
        headerTitle={'Select Region'}
        visible={visible}
      >
        <List
          itemObject={(object) => {
            setVisible(false);
            setSelectedRegion(object);
          }}
          initialData={[{ country: 'All Regions', id: 0 }, ...data]}
        />
      </Modal>

      <FlatList
        data={photos}
        renderItem={({ item }) => <PhotoItem item={item} allRegions={allRegions} />}
        keyExtractor={(item) => item.id.toString()}
        style={styles.listContainer}
        showsVerticalScrollIndicator={false}
      />
    </View>
  );
};

const ByDateContent = ({ data, allRegions }: { data: ByDateData; allRegions: AllRegions[] }) => {
  const [loading, setLoading] = useState<boolean>(true);
  const [visible, setVisible] = useState<boolean>(false);
  const [selectedDate, setSelectedDate] = useState<string | null>(null);
  const [photos, setPhotos] = useState<{ date: string; photos: PhotosData[] }[]>([]);
  const [filter, setFilter] = useState<string[]>([]);

  useEffect(() => {
    if (selectedDate) {
      setPhotos(groupByDate(data[selectedDate]));
    }
  }, [selectedDate]);

  useFocusEffect(
    useCallback(() => {
      const keys: string[] = Object.keys(data);

      if (keys.length > 0) {
        let sortedKeys = keys?.sort(compareDates);
        const firstKey = sortedKeys[0];

        const groupedByDate = groupByDate(data[firstKey]);
        setPhotos(groupedByDate);
        setFilter(sortedKeys);
      }
      setLoading(false);
    }, [data])
  );

  if (loading) return <Loading />;

  return (
    <View style={{ flex: 1 }}>
      <TouchableOpacity style={styles.regionSelector} onPress={() => setVisible(true)}>
        <Text style={styles.regionText}>{selectedDate ?? filter[0]}</Text>
        <ChevronIcon />
      </TouchableOpacity>
      <Modal onRequestClose={() => setVisible(false)} headerTitle={'Select Date'} visible={visible}>
        <List
          itemObject={(object) => {
            setVisible(false);
            setSelectedDate(object);
          }}
          initialData={filter}
          date={true}
        />
      </Modal>

      <FlatList
        data={photos}
        renderItem={({ item }) => <PhotoItem item={item} allRegions={allRegions} />}
        keyExtractor={(item) => item.date}
        style={styles.listContainer}
        showsVerticalScrollIndicator={false}
      />
    </View>
  );
};

const PhotosScreen = () => {
  const token = storage.get('token', StoreType.STRING) as string;
  const [loading, setLoading] = useState(true);
  const [contentIndex, setContentIndex] = useState(0);
  const { data, refetch } = useGetPhotosForUserQuery(token, true);
  const [allRegions, setAllRegions] = useState<AllRegions[]>([]);
  const { data: tempData, refetch: refetchTemp } = useGetTempQuery(token, true);
  const navigation = useNavigation();

  useFocusEffect(
    useCallback(() => {
      const fetchData = async () => {
        setLoading(true);
        try {
          await refetch().then((res) => {
            if (res.data?.result === 'OK') {
              setAllRegions(res?.data?.all_regions);
            }
          });
        } catch (error) {
          console.error(error);
        } finally {
          setLoading(false);
        }
      };

      fetchData();
    }, [refetch])
  );

  if (loading) return <Loading />;

  const renderContent = () => {
    switch (contentIndex) {
      case 0:
        return <ByRegionContent data={data?.by_region as ByRegionData[]} allRegions={allRegions} />;
      case 1:
        return <ByDateContent data={data?.by_date as ByDateData} allRegions={allRegions} />;
      default:
        return null;
    }
  };

  const handleImagePick = async () => {
    await refetchTemp().then(async (temp) => {
      if (temp.data?.photos && temp.data.photos.length > 0) {
        navigation.navigate(
          ...([
            NAVIGATION_PAGES.ADD_PHOTO,
            {
              data: null,
              images: [],
              allRegions: allRegions,
              tempData: temp.data.photos
            }
          ] as never)
        );
      } else {
        let result = await ImagePicker.launchImageLibraryAsync({
          mediaTypes: ImagePicker.MediaTypeOptions.Images,
          quality: 1,
          allowsMultipleSelection: true,
          exif: true
        });

        if (!result.canceled) {
          navigation.navigate(
            ...([
              NAVIGATION_PAGES.ADD_PHOTO,
              {
                data: null,
                images: result.assets,
                allRegions: allRegions
              }
            ] as never)
          );
        }
      }
    });
  };

  return (
    <PageWrapper>
      <Header label="Photos" />
      <View style={styles.buttonContainer}>
        <CustomButton
          title="By region"
          onPress={() => setContentIndex(0)}
          isActive={contentIndex === 0}
        />
        <CustomButton
          title="By date"
          onPress={() => setContentIndex(1)}
          isActive={contentIndex === 1}
        />
        <CustomButton
          title="Add"
          icon={<AddImgSvg fill={Colors.DARK_BLUE} />}
          onPress={handleImagePick}
        />
      </View>
      {renderContent()}
    </PageWrapper>
  );
};

export default PhotosScreen;
