import React, { useCallback, useEffect, useRef, useState } from 'react';
import {
  View,
  Text,
  Image,
  TouchableOpacity,
  ScrollView,
  KeyboardAvoidingView,
  Platform,
  TouchableWithoutFeedback,
  Keyboard
} from 'react-native';
import { Formik } from 'formik';
import * as yup from 'yup';
import { useNavigation } from '@react-navigation/native';
import { styles } from './styles';
import { ButtonVariants } from 'src/types/components';

import { StoreType, storage } from 'src/storage';

import AddImgSvg from 'assets/icons/travels-screens/add-img.svg';
import {
  Button,
  CustomImageViewer,
  Header,
  Input,
  Loading,
  PageWrapper,
  WarningModal
} from 'src/components';
import { Colors } from 'src/theme';

import EarthIcon from 'assets/icons/travels-section/earth.svg';
import NomadsIcon from 'assets/icons/bottom-navigation/travellers.svg';
import { getFontSize } from 'src/utils';
import { RichEditor, RichToolbar, actions } from 'react-native-pell-rich-editor';
import CalendarSvg from '../../../../../assets/icons/calendar.svg';
import RangeCalendar from 'src/components/Calendars/RangeCalendar';
import LocationIcon from 'assets/icons/bottom-navigation/map.svg';
import { ModalFlatList } from 'src/components/FlatList/modal-flatlist';
import {
  usePostAddEventMutation,
  usePostCancelEventMutation,
  usePostGetPhotosForRegionMutation,
  usePostUpdateEventMutation
} from '@api/events';
import { SheetManager } from 'react-native-actions-sheet';
import PhotosForRegionModal from '../Components/PhotosForRegionModal/PhotosForRegionModal';
import { API_HOST } from 'src/constants';
import AddMapPinModal from '../Components/AddMapPinModal';
import { InputTimePicker } from 'src/components/Calendar/InputTimePicker';
import { NAVIGATION_PAGES } from 'src/types';

const EventSchema = yup.object({
  event_name: yup.string().required().min(3),
  date: yup.date().nullable().required(),
  time_from: yup.date().nullable().required(),
  time_to: yup.date().nullable().required(),
  // capacity: yup.number().optional(),
  region: yup.number().required(),
  photo: yup.number().nullable().optional(),
  city: yup.string().required(),
  address: yup.string().optional(),
  pin: yup.object().nullable().required(),
  details: yup.string().required()
});

const CreateEventScreen = ({ route }: { route: any }) => {
  const eventId = route.params?.eventId;
  const eventData = route.params?.event;
  const token = (storage.get('token', StoreType.STRING) as string) ?? null;
  const navigation = useNavigation();
  const scrollRef = useRef<ScrollView>(null);
  const richText = useRef<RichEditor | null>(null);
  const { mutateAsync: getPhotosForRegion } = usePostGetPhotosForRegionMutation();
  const { mutateAsync: addEvent } = usePostAddEventMutation();
  const { mutateAsync: updateEvent } = usePostUpdateEventMutation();
  const { mutateAsync: cancelEvent } = usePostCancelEventMutation();

  const [isSubmitting, setIsSubmitting] = useState(false);
  const [calendarVisible, setCalendarVisible] = useState(false);
  const [isViewerVisible, setIsViewerVisible] = useState(false);
  const [photos, setPhotos] = useState<any[]>([]);

  function timeStringToDate(timeStr: string): Date {
    const [hours, minutes] = timeStr.split(':').map(Number);
    const date = new Date();

    date.setHours(hours, minutes, 0, 0);
    return date;
  }

  const initialData: any = {
    event_name: eventData?.title ?? '',
    date: eventData?.date ?? '',
    time_from: eventData?.time_from ? timeStringToDate(eventData.time_from) : null,
    time_to: eventData?.time_to ? timeStringToDate(eventData.time_to) : null,
    // capacity: eventData?.capacity ?? '',
    region: eventData?.region ?? null,
    photo: eventData?.photo_id ?? null,
    city: eventData?.address1 ?? '',
    address: eventData?.address2 ?? '',
    pin:
      eventData && eventData?.lat
        ? {
            coordinate: {
              longitude: eventData?.lon,
              latitude: eventData?.lat
            },
            name: eventData?.address2
          }
        : null,
    details: eventData?.details ?? ''
  };

  const [modalInfo, setModalInfo] = useState({
    visible: false,
    type: 'success',
    title: '',
    message: '',
    buttonTitle: 'OK',
    action: () => {}
  });

  useEffect(() => {
    if (eventData && eventData.region) {
      handleGetPhotosForRegion(eventData.region);
    }
  }, [eventData]);

  const handleGetPhotosForRegion = useCallback(
    async (regionId: number) => {
      await getPhotosForRegion(
        { region_id: regionId },
        {
          onSuccess: (res) => {
            if (res.photos) {
              setPhotos(res.photos);
            }
          }
        }
      );
    },
    [token]
  );

  const handleCancelEvent = () => {
    setModalInfo({
      visible: true,
      type: 'delete',
      title: 'Cancel event',
      buttonTitle: 'Cancel',
      message: `Are you sure you want to cancel this event?`,
      action: () => {
        cancelEvent(
          { token, event_id: eventId },
          {
            onSuccess: (res) => {
              navigation.navigate(NAVIGATION_PAGES.EVENTS as never);
            }
          }
        );
      }
    });
  };

  return (
    <PageWrapper>
      <Header label="Add event" />

      <KeyboardAvoidingView
        behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
        style={{ flex: 1 }}
      >
        <TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
          <ScrollView ref={scrollRef} showsVerticalScrollIndicator={false}>
            <Formik
              validationSchema={EventSchema}
              initialValues={initialData}
              onSubmit={async (values) => {
                setIsSubmitting(true);

                const newEvent: any = {
                  title: values.event_name,
                  region: values.region,
                  address1: values.city,
                  address2: values.address,
                  date: values.date,
                  lon: (values.pin as any)?.coordinate?.longitude,
                  lat: (values.pin as any)?.coordinate?.latitude,
                  details: values.details
                };

                if (values.photo) {
                  newEvent.photo = values.photo;
                }

                // if (values.capacity) {
                //   newEvent.capacity = Number(values.capacity);
                // } else {
                //   newEvent.capacity = 0;
                // }

                if (values.time_from) {
                  newEvent.time_from = (values.time_from as Date).toLocaleTimeString([], {
                    hour: '2-digit',
                    minute: '2-digit'
                  });
                }

                if (values.time_to) {
                  newEvent.time_to = (values.time_to as Date).toLocaleTimeString([], {
                    hour: '2-digit',
                    minute: '2-digit'
                  });
                }

                if (eventId) {
                  await updateEvent(
                    { token, event_id: eventId, event: JSON.stringify(newEvent) },
                    {
                      onSuccess: (res) => {
                        setIsSubmitting(false);
                        navigation.goBack();
                      },
                      onError: (err) => {
                        setIsSubmitting(false);
                      }
                    }
                  );
                } else {
                  await addEvent(
                    { token, event: JSON.stringify(newEvent) },
                    {
                      onSuccess: (res) => {
                        setIsSubmitting(false);
                        setModalInfo({
                          visible: true,
                          type: 'success',
                          title: 'Success',
                          buttonTitle: 'OK',
                          message: `Thank you for adding this new meeting. It will undergo review soon. You'll be notified via email once the meeting is approved.`,
                          action: () => {}
                        });
                      },
                      onError: (err) => {
                        setIsSubmitting(false);
                      }
                    }
                  );
                }
              }}
            >
              {(props) => (
                <View style={{ gap: 12 }}>
                  <Input
                    header={'Event name'}
                    placeholder={'Add event name'}
                    inputMode={'text'}
                    onChange={props.handleChange('event_name')}
                    value={props.values.event_name}
                    onBlur={props.handleBlur('event_name')}
                    formikError={props.touched.event_name && (props.errors.event_name as string)}
                  />

                  <Input
                    header={'Date'}
                    placeholder={'Add date'}
                    inputMode={'none'}
                    onChange={props.handleChange('date')}
                    value={props.values.date}
                    onBlur={props.handleBlur('date')}
                    isFocused={() => setCalendarVisible(true)}
                    formikError={props.touched.date && (props.errors.date as string)}
                    icon={<CalendarSvg fill={Colors.LIGHT_GRAY} width={20} height={20} />}
                  />

                  <View style={{ flexDirection: 'row', gap: 8 }}>
                    <InputTimePicker
                      headerTitle={'Select Start Time'}
                      defaultTime={props.values.time_from}
                      selectedTime={(time) => props.setFieldValue('time_from', time)}
                      formikError={props.touched.time_from && (props.errors.time_from as string)}
                      inputHeader={'Start time'}
                      placeholder="Choose a time"
                    />

                    <InputTimePicker
                      headerTitle={'Select End Time'}
                      defaultTime={props.values.time_to}
                      selectedTime={(time) => props.setFieldValue('time_to', time)}
                      formikError={props.touched.time_to && (props.errors.time_to as string)}
                      inputHeader={'End time'}
                      placeholder="Choose a time"
                    />
                  </View>

                  {/* <Input
                    header={'Maximum capacity'}
                    placeholder={'Set the maximum of people'}
                    inputMode={'numeric'}
                    onChange={props.handleChange('capacity')}
                    value={props.values.capacity}
                    onBlur={props.handleBlur('capacity')}
                    formikError={props.touched.capacity && props.errors.capacity as string}
                    icon={<NomadsIcon fill={Colors.LIGHT_GRAY} width={20} height={20} />}
                  /> */}

                  {eventId ? (
                    <Input
                      header={'NomadMania region'}
                      inputMode={'none'}
                      editable={false}
                      value={eventData?.region_name}
                    />
                  ) : (
                    <ModalFlatList
                      headerTitle={'NomadMania region'}
                      selectedObject={(data) => {
                        props.setFieldValue('region', data.id);
                        props.setFieldValue('photo', null);
                        handleGetPhotosForRegion(data.id);
                      }}
                      placeholder="Please choose a region"
                      formikError={
                        props.touched.region && !props.values.region ? props.errors.region : null
                      }
                    />
                  )}

                  {props.values.region && photos.length > 0 ? (
                    <Input
                      header={'Photo'}
                      placeholder={props.values.photo ? 'Photo selected' : 'Choose a photo'}
                      inputMode={'none'}
                      onBlur={props.handleBlur('photo')}
                      isFocused={() =>
                        SheetManager.show('photos-for-region-modal', {
                          payload: {
                            photos,
                            selectPhoto: (photo: any) => {
                              props.setFieldValue('photo', photo);
                            }
                          } as any
                        })
                      }
                      formikError={props.touched.photo && (props.errors.photo as string)}
                      icon={<AddImgSvg fill={Colors.LIGHT_GRAY} width={20} height={20} />}
                    />
                  ) : null}

                  {props.values.photo ? (
                    <View
                      style={{
                        display: 'flex',
                        justifyContent: 'center',
                        alignItems: 'center',
                        gap: 8
                      }}
                    >
                      <TouchableOpacity
                        style={{ width: '100%' }}
                        onPress={async () => setIsViewerVisible(true)}
                      >
                        <Image
                          source={{ uri: `${API_HOST}/webapi/photos/${props.values.photo}/small` }}
                          style={{ width: '100%', height: 200, borderRadius: 4 }}
                        />
                      </TouchableOpacity>
                    </View>
                  ) : null}

                  <Input
                    header={'City'}
                    placeholder={'Add event city'}
                    inputMode={'text'}
                    onChange={props.handleChange('city')}
                    value={props.values.city}
                    onBlur={props.handleBlur('city')}
                    formikError={props.touched.city && (props.errors.city as string)}
                    icon={<EarthIcon fill={Colors.LIGHT_GRAY} width={20} height={20} />}
                  />

                  <Input
                    header={'Address'}
                    placeholder={'Add event address'}
                    inputMode={'text'}
                    onChange={props.handleChange('address')}
                    value={props.values.address}
                    onBlur={props.handleBlur('address')}
                    formikError={props.touched.address && (props.errors.address as string)}
                    icon={<LocationIcon fill={Colors.LIGHT_GRAY} width={20} height={20} />}
                  />

                  <Input
                    header={'Map pin'}
                    placeholder={'Choose from map'}
                    inputMode={'none'}
                    onChange={props.handleChange('pin')}
                    value={(props.values.pin as any)?.name}
                    onBlur={props.handleBlur('pin')}
                    isFocused={() =>
                      SheetManager.show('add-map-pin-modal', {
                        payload: {
                          setPin: (pin: any) => {
                            props.setFieldValue('pin', pin);
                            props.setFieldValue('city', pin?.city);
                          },
                          pin: props.values.pin
                        } as any
                      })
                    }
                    formikError={
                      props.touched.pin && !props.values.pin ? (props.errors.pin as string) : false
                    }
                    icon={<LocationIcon fill={Colors.LIGHT_GRAY} width={20} height={20} />}
                  />

                  <View>
                    <Text
                      style={{
                        color: Colors.DARK_BLUE,
                        fontSize: getFontSize(14),
                        fontFamily: 'redhat-700',
                        marginBottom: 8
                      }}
                    >
                      Details
                    </Text>
                    <RichToolbar
                      editor={richText}
                      selectedButtonStyle={{ backgroundColor: Colors.LIGHT_GRAY }}
                      style={[
                        {
                          borderTopLeftRadius: 4,
                          borderTopRightRadius: 4,
                          backgroundColor: Colors.FILL_LIGHT
                        },
                        props.touched.details && props.errors.details
                          ? {
                              borderTopColor: Colors.RED,
                              borderLeftColor: Colors.RED,
                              borderRightColor: Colors.RED,
                              borderWidth: 1,
                              borderBottomWidth: 0
                            }
                          : {}
                      ]}
                      actions={[
                        actions.keyboard,
                        actions.setBold,
                        actions.setItalic,
                        actions.setUnderline,
                        actions.alignLeft,
                        actions.alignCenter,
                        actions.alignRight,
                        actions.alignFull,
                        actions.insertLink,
                        actions.insertBulletsList,
                        actions.insertOrderedList,
                        actions.setStrikethrough,
                        actions.indent,
                        actions.outdent,
                        actions.undo,
                        actions.redo,
                        actions.blockquote,
                        actions.insertLine
                      ]}
                    />

                    <RichEditor
                      ref={richText}
                      initialHeight={100}
                      onFocus={() => {
                        scrollRef.current?.scrollTo({
                          y: 650,
                          animated: true
                        });
                      }}
                      placeholder="Add event details"
                      initialContentHTML={props.values.details}
                      onChange={props.handleChange('details')}
                      editorStyle={{
                        contentCSSText: 'font-size: 14px; padding: 12px; color: #C8C8C8;',
                        backgroundColor: Colors.FILL_LIGHT,
                        color: Colors.DARK_BLUE
                      }}
                      style={[
                        {
                          minHeight: 100,
                          borderBottomLeftRadius: 4,
                          borderBottomRightRadius: 4
                        },
                        props.touched.details && props.errors.details
                          ? {
                              borderBottomColor: Colors.RED,
                              borderLeftColor: Colors.RED,
                              borderRightColor: Colors.RED,
                              borderWidth: 1,
                              borderTopWidth: 0
                            }
                          : {}
                      ]}
                      onBlur={() => props.handleBlur('details')}
                    />
                    {props.touched.details && props.errors.details ? (
                      <Text
                        style={{
                          color: Colors.RED,
                          fontSize: getFontSize(12),
                          fontFamily: 'redhat-600',
                          marginTop: 5
                        }}
                      >
                        {props.errors.details as string}
                      </Text>
                    ) : null}
                  </View>

                  {eventId ? (
                    <View style={{ marginTop: 15, marginBottom: 15, gap: 8 }}>
                      <Button onPress={() => props.handleSubmit()} disabled={isSubmitting}>
                        Update event
                      </Button>

                      <Button
                        variant={ButtonVariants.OPACITY}
                        containerStyles={{
                          backgroundColor: Colors.RED,
                          borderColor: Colors.RED
                        }}
                        textStyles={{ color: Colors.WHITE }}
                        onPress={handleCancelEvent}
                      >
                        Cancel event
                      </Button>
                    </View>
                  ) : (
                    <View style={{ marginTop: 15, marginBottom: 15, gap: 8 }}>
                      <Button onPress={() => props.handleSubmit()} disabled={isSubmitting}>
                        Save
                      </Button>

                      <Button
                        variant={ButtonVariants.OPACITY}
                        containerStyles={{
                          backgroundColor: Colors.WHITE,
                          borderColor: Colors.BORDER_LIGHT
                        }}
                        textStyles={{ color: Colors.DARK_BLUE }}
                        onPress={() => navigation.goBack()}
                      >
                        Cancel
                      </Button>
                    </View>
                  )}

                  <RangeCalendar
                    isModalVisible={calendarVisible}
                    closeModal={(startDate?: string | null, endDate?: string | null) => {
                      startDate && props.handleChange('date')(startDate.toString());
                      setCalendarVisible(false);
                    }}
                    allowRangeSelection={false}
                    selectedDate={props.values.date}
                  />
                  <CustomImageViewer
                    images={[
                      {
                        uri: `${API_HOST}/webapi/photos/${props.values.photo}/full`
                      }
                    ]}
                    imageIndex={0}
                    visible={isViewerVisible}
                    onRequestClose={() => setIsViewerVisible(false)}
                    backgroundColor={Colors.DARK_BLUE}
                  />
                </View>
              )}
            </Formik>
          </ScrollView>
        </TouchableWithoutFeedback>
      </KeyboardAvoidingView>
      <PhotosForRegionModal />
      <AddMapPinModal />
      <WarningModal
        type={modalInfo.type}
        isVisible={modalInfo.visible}
        buttonTitle={modalInfo.buttonTitle}
        message={modalInfo.message}
        action={modalInfo.action}
        onClose={() => {
          if (modalInfo.type === 'success') {
            navigation.goBack();
            setModalInfo({ ...modalInfo, visible: false });
          } else {
            setModalInfo({ ...modalInfo, visible: false });
          }
        }}
        title={modalInfo.title}
      />
    </PageWrapper>
  );
};

export default CreateEventScreen;
