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

import { Header, Input, Modal, PageWrapper, FlatList as List } from 'src/components';
import { API_HOST } from 'src/constants';
import { CustomButton } from '../Components';
import RangeCalendar from 'src/components/Calendars/RangeCalendar';
import { postSetUploadTemp, usePostRemoveTempMutation, usePostSaveTempMutation } from '@api/photos';

import { StoreType, storage } from 'src/storage';
import { AllRegions, ImageStatus, TempData } from '../utils/types';
import { itemWidth } from '../utils';
import { styles } from './styles';
import { Colors } from 'src/theme';

import AddImgSvg from '../../../../../assets/icons/travels-screens/add-img.svg';
import ChooseSvg from '../../../../../assets/icons/travels-screens/choose.svg';
import SaveSvg from '../../../../../assets/icons/travels-screens/save.svg';
import XCircleSvg from '../../../../../assets/icons/travels-screens/x-circle.svg';
import ChevronIcon from '../../../../../assets/icons/travels-screens/chevron-bottom.svg';
import CalendarSvg from '../../../../../assets/icons/calendar.svg';

const AddPhotoScreen = ({ route }: { route: any }) => {
  const navigation: any = useNavigation();
  const { data, images, allRegions, tempData } = route.params;
  const token = storage.get('token', StoreType.STRING) as string;
  const [isModalVisible, setIsModalVisible] = useState(false);
  const [selectedRegion, setSelectedRegion] = useState<AllRegions | null>(
    data && data.country
      ? ({
          id: data.id,
          country: data.country
        } as AllRegions)
      : null
  );
  const [description, setDescription] = useState('');
  const [selectedDate, setSelectedDate] = useState<string | null>(
    data && data.date ? data.date : new Date().toISOString().slice(0, 10)
  );
  const { mutate: removeTemp } = usePostRemoveTempMutation();
  const { mutate: saveTemp, data: saveResponse } = usePostSaveTempMutation();
  const [imagesStatus, setImagesStatus] = useState<ImageStatus[]>(
    images?.map((image: ImagePicker.ImagePickerAsset) => ({
      uri: image.uri,
      assetId: image.assetId,
      loaded: false,
      progress: 0,
      uploadResponse: null,
      dateTime: image.exif?.DateTimeOriginal?.split(' ')[0].replaceAll(':', '-') ?? null
    }))
  );
  const [calendarVisible, setCalendarVisible] = useState(false);

  useEffect(() => {
    if (tempData) {
      setImagesStatus(
        tempData.map((temp: TempData) => {
          return { assetId: temp.guid, loaded: true, uploadResponse: temp };
        })
      );
      return;
    } else {
      images.forEach((image: ImagePicker.ImagePickerAsset) => uploadTempImage(image));
    }

    const date = images[images.length - 1]?.exif?.DateTimeOriginal?.split(' ')[0].replaceAll(
      ':',
      '-'
    );
    date && setSelectedDate(date);
  }, [images]);

  const uploadTempImage = async (image: ImagePicker.ImagePickerAsset) => {
    const uriParts = image.uri.split('.');
    const fileType = uriParts[uriParts.length - 1];

    const imgData = {
      token,
      file: {
        uri: image.uri,
        name: image.uri.split('/').pop()!,
        type: `image/${fileType}`
      }
    };

    image.assetId && simulateUploadProgress(image.assetId);

    postSetUploadTemp(imgData)
      .then((response) => {
        if (response && response.result === 'OK') {
          setImagesStatus((currentStatus) =>
            currentStatus.map((item) => {
              if (item.assetId === image.assetId) {
                return {
                  ...item,
                  loaded: true,
                  progress: 1,
                  uploadResponse: { guid: response.guid, link: response.link }
                };
              }
              return item;
            })
          );
        }
      })
      .catch((error) => {
        console.error('Error', error);
      });
  };

  const simulateUploadProgress = (assetId: string) => {
    let progress = 0;
    const intervalId = setInterval(() => {
      progress += 0.05 + Math.random() * 0.25;
      if (progress >= 1) {
        clearInterval(intervalId);
        progress = 1;
      }

      setImagesStatus((currentStatus) =>
        currentStatus.map((item) => {
          if (item.assetId === assetId) {
            return { ...item, progress };
          }
          return item;
        })
      );
    }, 300);
  };

  const deleteTemp = (item: ImageStatus) => {
    removeTemp(
      { token, guid: item.uploadResponse?.guid as string },
      {
        onSuccess: (res) => {
          if (res.result === 'OK') {
            setImagesStatus(
              imagesStatus.filter(
                (img: ImageStatus) => img.uploadResponse?.guid !== item.uploadResponse?.guid
              )
            );
          }
        }
      }
    );
  };

  const handleSelectPhoto = async () => {
    await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      quality: 1,
      allowsMultipleSelection: true,
      exif: true
    }).then((result) => {
      if (!result.canceled) {
        addPhoto(result.assets);
      }
    });
  };

  const addPhoto = (newImages: ImagePicker.ImagePickerAsset[]) => {
    const date = newImages[newImages.length - 1]?.exif?.DateTimeOriginal?.split(' ')[0].replaceAll(
      ':',
      '-'
    );
    date && setSelectedDate(date);
    setImagesStatus([
      ...imagesStatus,
      ...newImages.map((image: any) => ({
        uri: image.uri,
        assetId: image.assetId,
        loaded: false,
        progress: 0,
        uploadResponse: null,
        dateTime: image.exif?.DateTimeOriginal?.split(' ')[0].replaceAll(':', '-') ?? null
      }))
    ]);
    newImages.forEach((image: ImagePicker.ImagePickerAsset) => uploadTempImage(image));
  };

  const saveTempData = () => {
    const tempData = {
      token,
      guids: imagesStatus.map((img) => img.uploadResponse?.guid!),
      date: selectedDate,
      region: selectedRegion?.id!,
      description
    };
    saveTemp(tempData, {
      onSuccess: () => {
        data && allRegions?.length ? navigation.pop(2) : navigation.goBack();
      }
    });
  };

  const renderItem = ({ item }: { item: ImageStatus }) => (
    <View style={styles.itemContainer}>
      <View style={{ position: 'relative' }}>
        {!item.loaded ? (
          <Progress.Bar
            progress={item.progress}
            width={itemWidth}
            color={Colors.DARK_BLUE}
            borderWidth={0}
            borderRadius={5}
            unfilledColor="rgba(0, 0, 0, 0.1)"
          />
        ) : (
          <Image
            source={{ uri: API_HOST + item.uploadResponse?.link }}
            style={[styles.image, { width: itemWidth, height: itemWidth }]}
          />
        )}
        {item.loaded && (
          <TouchableOpacity style={styles.deleteTemp} onPress={() => deleteTemp(item)}>
            <XCircleSvg />
          </TouchableOpacity>
        )}
      </View>
    </View>
  );

  const getHeaderLabel = () => {
    if (data?.country) return data.country;
    if (data?.date) return data.date;
    return 'Add photo';
  };

  return (
    <PageWrapper>
      <Header label={getHeaderLabel()} />
      <View style={{ alignItems: 'center', marginBottom: 8 }}>
        {data?.name && <Text style={styles.title}>{data.name}</Text>}
        <View style={styles.btnContainer}>
          <CustomButton
            title="Save"
            onPress={saveTempData}
            icon={<SaveSvg fill={Colors.DARK_BLUE} />}
            disabled={
              !selectedRegion ||
              imagesStatus.length === 0 ||
              imagesStatus.some((img) => !img.loaded)
            }
          />
          <CustomButton
            title="Add photo"
            icon={<AddImgSvg fill={Colors.DARK_BLUE} />}
            onPress={handleSelectPhoto}
          />
        </View>
      </View>
      <View style={{ gap: 10, marginVertical: 8 }}>
        <Input
          placeholder="Photo description"
          inputMode={'text'}
          onChange={(text) => setDescription(text)}
          value={description}
        />
        {!data?.country && (
          <TouchableOpacity
            style={[styles.regionSelector, { justifyContent: 'space-between' }]}
            onPress={() => setIsModalVisible(true)}
          >
            <Text style={styles.regionText}>{selectedRegion?.country ?? 'Choose a region'}</Text>
            <ChevronIcon />
          </TouchableOpacity>
        )}

        {!data?.date && (
          <TouchableOpacity style={styles.regionSelector} onPress={() => setCalendarVisible(true)}>
            <CalendarSvg fill={Colors.LIGHT_GRAY} />
            <Text style={styles.regionText}>{selectedDate ?? 'Add date'}</Text>
          </TouchableOpacity>
        )}
      </View>

      <FlatList
        data={imagesStatus}
        renderItem={renderItem}
        keyExtractor={(item, index) => index.toString()}
        numColumns={2}
        columnWrapperStyle={styles.columnWrapper}
        showsVerticalScrollIndicator={false}
      />
      <Modal
        onRequestClose={() => setIsModalVisible(false)}
        headerTitle={'Select Region'}
        visible={isModalVisible}
      >
        <List
          itemObject={(object) => {
            setSelectedRegion(object);
            setIsModalVisible(false);
          }}
          initialData={allRegions}
        />
      </Modal>

      <RangeCalendar
        isModalVisible={calendarVisible}
        closeModal={(startDate?: string | null, endDate?: string | null) => {
          startDate && setSelectedDate(startDate.toString());
          setCalendarVisible(false);
        }}
        allowRangeSelection={false}
        disableFutureDates={true}
      />
    </PageWrapper>
  );
};

export default AddPhotoScreen;
