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

import { CustomImageViewer, Header, Loading, PageWrapper, WarningModal } from 'src/components';
import { CustomButton, PhotoEditModal } from '../Components';
import {
  useGetTempQuery,
  usePostDeletePhotoMutation,
  usePostUpdatePhotoMutation
} from '@api/photos';

import { API_HOST } from 'src/constants';
import { Colors } from 'src/theme';
import { NAVIGATION_PAGES } from 'src/types';
import { StoreType, storage } from 'src/storage';
import { AllRegions, PhotosData } from '../utils/types';
import { itemWidth } from '../utils';
import { styles } from './styles';

import AddImgSvg from '../../../../../assets/icons/travels-screens/add-img.svg';
import ChooseSvg from '../../../../../assets/icons/travels-screens/choose.svg';
import DotsSvg from '../../../../../assets/icons/travels-screens/three-dots.svg';
import TrashSvg from '../../../../../assets/icons/travels-screens/trash-solid.svg';
import CircleCheckSvg from '../../../../../assets/icons/travels-screens/circle-check.svg';
import PenSvg from '../../../../../assets/icons/travels-screens/pen-to-square.svg';

const MorePhotosScreen = ({ route }: { route: any }) => {
  const { data, allRegions } = route.params;
  const token = storage.get('token', StoreType.STRING) as string;
  const { data: tempData, refetch } = useGetTempQuery(token, true);
  const { mutate: deletePhoto } = usePostDeletePhotoMutation();
  const { mutate: updatePhoto } = usePostUpdatePhotoMutation();
  const navigation = useNavigation();

  const [selectionMode, setSelectionMode] = useState(false);
  const [selectedPhotos, setSelectedPhotos] = useState<{ [key: string]: boolean }>({});
  const [photoToEdit, setPhotoToEdit] = useState<PhotosData | null>(null);
  const [isLoading, setIsLoading] = useState(false);
  const [photos, setPhotos] = useState<PhotosData[]>(data.photos ?? []);
  const [shouldOpenWarningModal, setShouldOpenWarningModal] = useState(false);
  const [shouldOpenEditModal, setShouldOpenEditModal] = useState(false);
  const [selectedDate, setSelectedDate] = useState<string | null>(null);
  const [description, setDescription] = useState<string | null>(null);
  const [selectedRegion, setSelectedRegion] = useState<AllRegions | null>(null);
  const [fullImages, setFullImages] = useState<PhotosData[]>([]);
  const [currentImageIndex, setCurrentImageIndex] = useState(0);
  const [modalState, setModalState] = useState({
    isModalVisible: false,
    isWarningVisible: false,
    isEditModalVisible: false,
    isViewerVisible: false
  });

  const handleSelectPhoto = useCallback((id: number) => {
    setSelectedPhotos((prevSelected) => {
      const isSelected = !!prevSelected[id];
      return {
        ...prevSelected,
        [id]: !isSelected
      };
    });
  }, []);

  const toggleSelectionMode = () => {
    setSelectionMode(!selectionMode);
  };

  useEffect(() => {
    setFullImages(
      photos.map((photo) => ({
        ...photo,
        uri: API_HOST + photo.url_mid
      }))
    );
  }, [photos]);

  const openImageViewer = (index: number) => {
    setCurrentImageIndex(index);
    openModal('isViewerVisible');
  };

  const deleteSelectedPhotos = () => {
    const photoIds = Object.entries(selectedPhotos)
      .filter(([key, value]) => value)
      .map(([key, value]) => +key);
    photoIds.forEach((id) => {
      deletePhoto({ token, photo_id: id });
    });
    setPhotos(photos.filter((photo) => !photoIds.includes(photo.id)));
    setSelectedPhotos({});
  };

  const cancelSelection = () => {
    setSelectedPhotos({});
    setSelectionMode(false);
  };

  const handleDeletePhoto = () => {
    photoToEdit &&
      deletePhoto(
        { token, photo_id: photoToEdit.id },
        {
          onSuccess: (res) => {
            if (res.result === 'OK') {
              setPhotos(photos.filter((photo) => photo.id !== photoToEdit.id));
            }
          }
        }
      );
    setPhotoToEdit(null);
    closeModal('isModalVisible');
  };

  const handleUpdatePhoto = () => {
    photoToEdit &&
      updatePhoto(
        {
          token,
          photo_id: photoToEdit.id,
          date: selectedDate,
          region: selectedRegion?.id ?? null,
          description: description ?? photoToEdit.title
        },
        {
          onSuccess: (res) => {
            if (res.result === 'OK') {
              const filteredPhotos = photos.filter((photo) => {
                if (selectedRegion && !data?.date && selectedRegion?.id !== data?.region) {
                  return photo.id !== photoToEdit.id;
                } else if (selectedDate && data?.date && selectedDate !== data?.date) {
                  return photo.id !== photoToEdit.id;
                } else {
                  return true;
                }
              });

              const updatedPhotos = filteredPhotos.map((photo) => {
                if (photo.id === photoToEdit.id) {
                  return {
                    ...photo,
                    title: typeof description === 'string' ? description : photo.title,
                    date: selectedDate ?? photo.date,
                    region: selectedRegion?.id ?? photo.region
                  };
                }
                return photo;
              });

              setPhotos(updatedPhotos);
            }
          }
        }
      );

    closeModal('isEditModalVisible');
    setSelectedDate(null);
    setSelectedRegion(null);
    setDescription(null);
  };

  const renderItem = ({ item, index }: { item: PhotosData; index: number }) => (
    <View style={{ alignItems: 'center', marginVertical: 8 }}>
      <TouchableOpacity
        style={{ position: 'relative' }}
        onPress={() => (selectionMode ? handleSelectPhoto(item.id) : openImageViewer(index))}
      >
        <Image
          source={{ uri: API_HOST + item?.url_small, cache: 'reload' }}
          style={[styles.image, { width: itemWidth, height: itemWidth }]}
        />
        <TouchableOpacity
          style={styles.btnDots}
          onPress={() => {
            setPhotoToEdit(item);
            openModal('isModalVisible');
          }}
        >
          <DotsSvg />
        </TouchableOpacity>
        {selectionMode && (
          <View
            style={[
              styles.selectionIndicator,
              { backgroundColor: selectedPhotos[item.id] ? Colors.WHITE : 'rgba(15, 63, 79, 0.3)' }
            ]}
          >
            {selectedPhotos[item.id] && (
              <CircleCheckSvg fill={Colors.ORANGE} height={22} width={22} />
            )}
          </View>
        )}
      </TouchableOpacity>
      {item.title && (
        <Text style={[styles.description, { maxWidth: itemWidth }]}>{item.title}</Text>
      )}
    </View>
  );

  const handleImagePick = async () => {
    setIsLoading(true);

    await refetch().then(async (temp) => {
      if (temp.data?.photos && temp.data?.photos.length > 0) {
        setIsLoading(false);
        navigation.navigate(
          ...([
            NAVIGATION_PAGES.ADD_PHOTO,
            {
              data: data,
              images: [],
              allRegions: allRegions,
              tempData: temp.data.photos
            }
          ] as never)
        );
      } else {
        setIsLoading(false);

        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: data,
                images: result.assets,
                allRegions: allRegions
              }
            ] as never)
          );
        }
      }
    });
  };

  const handleEditModalClose = () => {
    closeModal('isEditModalVisible');
    setSelectedDate(null);
    setSelectedRegion(null);
    setDescription(null);
  };

  const closeModal = (modalName: string) => {
    setModalState((prevState) => ({ ...prevState, [modalName]: false }));
  };

  const openModal = (modalName: string) => {
    setModalState((prevState) => ({ ...prevState, [modalName]: true }));
  };

  return (
    <PageWrapper style={{ position: 'relative' }}>
      <Header label={data.country ?? data.date} />
      {isLoading && <Loading />}
      <View style={{ alignItems: 'center', marginBottom: 8 }}>
        {data.name && <Text style={styles.title}>{data.name}</Text>}
        <View
          style={[
            styles.btnContainer,
            {
              width: selectionMode ? 'auto' : '85%'
            }
          ]}
        >
          {selectionMode ? (
            <>
              <View>
                <CustomButton
                  onPress={() => openModal('isWarningVisible')}
                  icon={<TrashSvg fill={Colors.DARK_BLUE} />}
                />
              </View>
              <CustomButton
                title="Cancel"
                onPress={cancelSelection}
                icon={<CircleCheckSvg fill={Colors.DARK_BLUE} />}
              />
            </>
          ) : (
            <CustomButton
              title="Choose"
              icon={<ChooseSvg fill={Colors.DARK_BLUE} />}
              onPress={toggleSelectionMode}
            />
          )}
          <CustomButton
            title="Add photo"
            icon={<AddImgSvg fill={Colors.DARK_BLUE} />}
            onPress={handleImagePick}
          />
        </View>
      </View>
      <FlatList
        data={photos}
        renderItem={renderItem}
        keyExtractor={(item) => item.id.toString()}
        numColumns={2}
        columnWrapperStyle={styles.columnWrapper}
        showsVerticalScrollIndicator={false}
      />
      <ReactModal
        isVisible={modalState.isModalVisible}
        onBackdropPress={() => closeModal('isModalVisible')}
        style={styles.modal}
        statusBarTranslucent={true}
        presentationStyle="overFullScreen"
        onModalHide={() => {
          if (shouldOpenWarningModal) {
            openModal('isWarningVisible');
            setShouldOpenWarningModal(false);
          } else if (shouldOpenEditModal) {
            openModal('isEditModalVisible');
            setShouldOpenEditModal(false);
          }
        }}
      >
        <View style={styles.wrapper}>
          <View style={{ paddingVertical: 36 }}>
            <TouchableOpacity
              style={styles.btnModalEdit}
              onPress={() => {
                closeModal('isModalVisible');
                setShouldOpenEditModal(true);
              }}
            >
              <PenSvg fill={Colors.DARK_BLUE} />
              <Text style={styles.btnModalEditText}>Edit photo</Text>
            </TouchableOpacity>

            <TouchableOpacity
              style={styles.btnModalEdit}
              onPress={() => {
                closeModal('isModalVisible');
                setShouldOpenWarningModal(true);
              }}
            >
              <TrashSvg fill={Colors.DARK_BLUE} />
              <Text style={styles.btnModalEditText}>Delete</Text>
            </TouchableOpacity>
          </View>
        </View>
      </ReactModal>
      <WarningModal
        isVisible={modalState.isWarningVisible}
        onClose={() => {
          closeModal('isWarningVisible');
          setPhotoToEdit(null);
        }}
        type="delete"
        title={photoToEdit ? 'Delete photo?' : 'Delete photos?'}
        message={
          photoToEdit
            ? 'Are you sure you want to delete this photo?'
            : 'Are you sure you want to delete these photos?'
        }
        action={photoToEdit ? handleDeletePhoto : deleteSelectedPhotos}
      />
      <PhotoEditModal
        isVisible={modalState.isEditModalVisible}
        onClose={handleEditModalClose}
        photo={photoToEdit as PhotosData}
        allRegions={allRegions}
        handleUpdate={handleUpdatePhoto}
        description={description}
        setDescription={setDescription}
        selectedDate={selectedDate}
        setSelectedDate={setSelectedDate}
        selectedRegion={selectedRegion}
        setSelectedRegion={setSelectedRegion}
      />
      <CustomImageViewer
        images={fullImages as any}
        imageIndex={currentImageIndex}
        visible={modalState.isViewerVisible}
        onRequestClose={() => closeModal('isViewerVisible')}
        backgroundColor={Colors.DARK_BLUE}
      />
    </PageWrapper>
  );
};

export default MorePhotosScreen;
