import React, { useEffect, useState } from 'react'
import Clipboard from '@react-native-clipboard/clipboard';
import { Messages as MessagesController, useSession, useUtils, useLanguage, ToastType, useToast, useConfig } from 'ordering-components/native'
import { useTheme } from 'styled-components/native';
import { launchImageLibrary } from 'react-native-image-picker'
import { GiftedChat, Actions, ActionsProps, InputToolbar, Composer, Send, Bubble, MessageImage, InputToolbarProps, ComposerProps } from 'react-native-gifted-chat'
import { USER_TYPE } from '../../config/constants'
import MaterialCommunityIcon from 'react-native-vector-icons/MaterialCommunityIcons'
import AntDesignIcon from 'react-native-vector-icons/AntDesign'
import { OIcon, OIconButton, OText, OButton } from '../shared'
import { TouchableOpacity, ActivityIndicator, StyleSheet, View, Platform, Keyboard } from 'react-native'
import { Header, TitleHeader, Wrapper, QuickMessageContainer, ProfileMessageHeader, MessageTypeItem } from './styles'
import { MessagesParams } from '../../types'
import { useWindowDimensions } from 'react-native'
import { useSafeAreaInsets } from 'react-native-safe-area-context'
import { getLogisticTag } from '../../utils'

const ORDER_STATUS: any = {
  0: 'ORDER_STATUS_PENDING',
  1: 'ORDERS_COMPLETED',
  2: 'ORDER_REJECTED',
  3: 'ORDER_STATUS_IN_BUSINESS',
  4: 'ORDER_READY',
  5: 'ORDER_REJECTED_RESTAURANT',
  6: 'ORDER_STATUS_CANCELLEDBYDRIVER',
  7: 'ORDER_STATUS_ACCEPTEDBYRESTAURANT',
  8: 'ORDER_CONFIRMED_ACCEPTED_BY_DRIVER',
  9: 'ORDER_PICKUP_COMPLETED_BY_DRIVER',
  10: 'ORDER_PICKUP_FAILED_BY_DRIVER',
  11: 'ORDER_DELIVERY_COMPLETED_BY_DRIVER',
  12: 'ORDER_DELIVERY_FAILED_BY_DRIVER',
  13: 'PREORDER',
  14: 'ORDER_NOT_READY',
  15: 'ORDER_PICKEDUP_COMPLETED_BY_CUSTOMER',
  16: 'ORDER_STATUS_CANCELLED_BY_CUSTOMER',
  17: 'ORDER_NOT_PICKEDUP_BY_CUSTOMER',
  18: 'ORDER_DRIVER_ALMOST_ARRIVED_BUSINESS',
  19: 'ORDER_DRIVER_ALMOST_ARRIVED_CUSTOMER',
  20: 'ORDER_CUSTOMER_ALMOST_ARRIVED_BUSINESS',
  21: 'ORDER_CUSTOMER_ARRIVED_BUSINESS',
  22: 'ORDER_LOOKING_FOR_DRIVER',
  23: 'ORDER_DRIVER_ON_WAY',
  24: 'ORDER_DRIVER_WAITING_FOR_ORDER',
  25: 'ORDER_ACCEPTED_BY_DRIVER_COMPANY',
  26: 'ORDER_DRIVER_ARRIVED_CUSTOMER'
}

const filterSpecialStatus = ['prepared_in', 'delivered_in', 'delivery_datetime']


const MessagesUI = (props: MessagesParams) => {
  const {
    type,
    order,
    messages,
    image,
    message,
    sendMessage,
    setCanRead,
    setMessage,
    handleSend,
    setImage,
    readMessages,
    onClose,
    business,
    driver,
    onMessages,
    isMeesageListing
  } = props

  const [{ user }] = useSession()
  const [{ configs }] = useConfig()
  const [{ parseDate }] = useUtils()
  const [, t] = useLanguage()
  const [, { showToast }] = useToast();

  const [formattedMessages, setFormattedMessages] = useState<Array<any>>([])
  const [isKeyboardShow, setIsKeyboardShow] = useState(false)
  const previousStatus = [1, 2, 5, 6, 10, 11, 12, 15, 16, 17]
  const chatDisabled = previousStatus.includes(order?.status)
  const { height } = useWindowDimensions();
  const { top, bottom } = useSafeAreaInsets();

  const theme = useTheme();

  const quickMessageList = [
    { key: 'customer_message_1', text: t('CUSTOMER_MESSAGE_1', 'Lorem ipsum 1') },
    { key: 'customer_message_2', text: t('CUSTOMER_MESSAGE_2', 'Lorem ipsum 2') },
    { key: 'customer_message_3', text: t('CUSTOMER_MESSAGE_3', 'Lorem ipsum 3') },
    { key: 'customer_message_4', text: t('CUSTOMER_MESSAGE_4', 'Lorem ipsum 4') }
  ]

  const handleClickQuickMessage = (text: string) => {
    setMessage && setMessage(`${message}${text}`)
  }

  const onChangeMessage = (val: string) => {
    setMessage && setMessage(val)
  }

  const removeImage = () => {
    setImage && setImage(null)
  }

  const handleImagePicker = () => {
    launchImageLibrary({ mediaType: 'photo', maxHeight: 2048, maxWidth: 2048, includeBase64: true }, (response: any) => {
      if (response?.didCancel) {
        showToast(ToastType.Error, t('IMAGE_CANCELLED', 'User cancelled image picker'));
      } else if (response?.errorMessage) {
        showToast(ToastType.Error, response.errorMessage);
      } else {
        if (response?.assets?.length > 0) {
          const image = response?.assets[0]
          const url = `data:${image.type};base64,${image.base64}`
          setImage && setImage(url);
        } else {
          showToast(ToastType.Error, t('IMAGE_NOT_FOUND', 'Image not found'));
        }
      }
    });
  };

  const onSubmit = (values: any) => {
    handleSend && handleSend()
    setImage && setImage(null)
    setMessage && setMessage('')
  }

  const messageConsole = (message: any) => {
    return message.change?.attribute !== 'driver_id'
      ?
      `${t('ORDER', 'Order')} ${t(message.change.attribute.toUpperCase(), message.change.attribute.replace('_', ' '))} ${t('CHANGED_FROM', 'Changed from')} ${filterSpecialStatus.includes(message.change.attribute)
        ? `${message.change.old === null ? '0' : message.change.old} ${t('TO', 'to')} ${message.change.new} ${t('MINUTES', 'Minutes')}`
        : `${message.change?.attribute !== 'logistic_status'
          ? message.change.old !== null && t(ORDER_STATUS[parseInt(message.change.old, 10)])
          : message.change.old !== null && getLogisticTag(message.change.old, t)} ${t('TO', 'to')} ${message.change?.attribute !== 'logistic_status'
            ? t(ORDER_STATUS[parseInt(message.change.new, 10)])
            : getLogisticTag(message.change.new, t)}`
      }`
      : message.change.new
        ?
        `${message.driver?.name} ${message.driver?.lastname !== null ? message.driver.lastname : ''} ${t('WAS_ASSIGNED_AS_DRIVER', 'Was assigned as driver')} ${message.comment ? message.comment.length : ''}`
        :
        `${t('DRIVER_UNASSIGNED', 'Driver unassigned')}`
  }

  useEffect(() => {
    const newMessages: Array<any> = []
    const _console = `${t('ORDER_PLACED_FOR', 'Order placed for')} ${parseDate(order?.created_at)} ${t('VIA', 'Via')} ${order?.app_id ? t(order?.app_id.toUpperCase(), order?.app_id) : t('OTHER', 'Other')}`
    const firstMessage = {
      _id: 0,
      type: 0,
      text: _console,
      createdAt: parseDate(order?.created_at, { outputFormat: 'YYYY-MM-DD HH:mm:ss' }),
      system: true
    }
    messages.messages.map((message: any) => {
      if (message.change?.attribute === 'driver_group_id') return
      if (business && message.type !== 0 && (props?.messagesToShow?.messages?.length || message?.can_see?.includes('2'))) {
        newMessages.push({
          _id: message?.id,
          text: message.type === 1 ? messageConsole(message) : message.comment,
          createdAt: message.type !== 0 && parseDate(message?.created_at, { outputFormat: 'YYYY-MM-DD HH:mm:ss' }),
          image: message.source,
          type: message.type,
          system: message.type === 1,
          user: {
            _id: message.author && message.author.id,
            name: message.author && message.author.name,
            avatar: message.author && (message.author.id !== user.id && type === USER_TYPE.DRIVER ? order?.driver?.photo : order?.business?.logo)
          }
        });
      }

      if (driver && message.type !== 0 && (props?.messagesToShow?.messages?.length || message?.can_see?.includes('4'))) {
        newMessages.push({
          _id: message?.id,
          text: message.type === 1 ? messageConsole(message) : message.comment,
          createdAt: message.type !== 0 && parseDate(message?.created_at, { outputFormat: 'YYYY-MM-DD HH:mm:ss' }),
          image: message.source,
          type: message.type,
          system: message.type === 1,
          user: {
            _id: message.author && message.author.id,
            name: message.author && message.author.name,
            avatar: message.author && (message.author.id !== user.id && type === USER_TYPE.DRIVER ? order?.driver?.photo : order?.business?.logo)
          }
        });
      }

      if (message.type === 0) {
        newMessages.push(firstMessage);
      }
    })
    let _arrayMessages = [...newMessages.reverse()]

    setFormattedMessages(_arrayMessages);
  }, [messages.messages.length, business, driver])

  useEffect(() => {
    const keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', () => {
      setIsKeyboardShow(true)
    })
    const keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', () => {
      setIsKeyboardShow(false)
    })
    const keyboardWillHideListener = Keyboard.addListener('keyboardWillHide', () => {
      setIsKeyboardShow(false)
    })
    return () => {
      keyboardDidShowListener.remove()
      keyboardDidHideListener.remove()
      keyboardWillHideListener.remove()
    }
  }, [])

  useEffect(() => {
    if (business) setCanRead({ business: true, administrator: true, customer: true, driver: false })
    else if (driver) setCanRead({ business: false, administrator: true, customer: true, driver: true })
  }, [business, driver])

  const RenderActions = (props: any) => {
    return (
      <Actions
        {...props}
        options={{
          'Send Image': () => handleImagePicker(),
        }}
        containerStyle={styles.containerActions}
        optionTintColor='#222845'
        icon={() => (
          <>
            <OIconButton
              borderColor={theme.colors.white}
              style={{ width: 32, height: 44, borderRadius: 10, backgroundColor: theme.colors.clear, borderColor: theme.colors.clear }}
              icon={image ? { uri: image } : theme.images.general.image}
              iconStyle={{ borderRadius: image ? 10 : 0, width: image ? 32 : 16, height: image ? 32 : 16 }}
              onClick={handleImagePicker}
              iconCover
            />
            {image && (
              <TouchableOpacity
                style={{ position: 'absolute', top: -5, right: -5, borderColor: theme.colors.backgroundDark, backgroundColor: theme.colors.white, borderRadius: 25 }}
                onPress={removeImage}
              >
                <MaterialCommunityIcon name='close-circle-outline' color={theme.colors.backgroundDark} size={24} />
              </TouchableOpacity>
            )}
          </>
        )}
      />
    )
  }

  const renderAccessory = () => {
    return (
      !chatDisabled &&
      <QuickMessageContainer
        style={{
          marginLeft: 10,
          marginBottom: 10
        }}
        contentContainerStyle={{
          alignItems: 'center',
        }}
        horizontal
        showsHorizontalScrollIndicator={false}
      >
        {quickMessageList.map((quickMessage, i) => (
          <OButton
            key={i}
            text={quickMessage.text}
            bgColor='#E9ECEF'
            borderColor='#E9ECEF'
            imgRightSrc={null}
            textStyle={{
              fontSize: 11,
              lineHeight: 16,
              color: '#414954'
            }}
            style={{ ...styles.editButton }}
            onClick={() => handleClickQuickMessage(quickMessage.text)}
          />
        ))}
      </QuickMessageContainer>
    )
  }

  const renderInputToolbar = (props: typeof InputToolbarProps) => (
    <InputToolbar
      {...props}
      containerStyle={{
        padding: Platform.OS === 'ios' && isKeyboardShow ? 0 : 10,
        flexDirection: 'column-reverse'
      }}
      primaryStyle={{ alignItems: 'center', justifyContent: 'flex-start' }}
      renderAccessory={() => renderAccessory()}
    />
  )

  const renderComposer = (props: typeof ComposerProps) => (
    chatDisabled ? (
      <View
        style={{
          width: '100%',
          flexDirection: 'column',
          alignItems: 'center'
        }}
      >
        <MaterialCommunityIcon
          name='close-octagon-outline'
          size={24}
        />
        <OText size={14}>{t('NOT_SEND_MESSAGES', 'You can\'t send messages because the order has ended')}</OText>
      </View>
    ) : (
      <View style={{
        flexDirection: 'row', width: '80%', alignItems: 'center', backgroundColor: theme.colors.backgroundGray100,
        borderRadius: 7.6,
      }}>
        <Composer
          {...props}
          textInputStyle={{
            height: 32,
            minHeight: 32,
            alignItems: 'center',
            justifyContent: 'center',
            paddingHorizontal: 12,
            borderColor: '#DBDCDB',
            color: '#010300',
          }}
          textInputProps={{
            value: message,
            onSubmitEditing: onSubmit,
            returnKeyType: message ? 'send' : 'done',
            blurOnSubmit: true,
            multiline: false,
            numberOfLines: 1,
            autoCorrect: false,
            autoCompleteType: 'off',
            enablesReturnKeyAutomatically: false
          }}
          placeholder={t('WRITE_MESSAGE', 'Write message...')}
        />
        <RenderActions {...props} />
      </View>
    )
  )

  const renderSend = (props: any) => {
    const isDisabled = (sendMessage?.loading || (message === '' && !image) || messages?.loading)
    return (
      <Send
        {...props}
        disabled={isDisabled}
        alwaysShowSend
        containerStyle={styles.containerSend}
      >
        <OIconButton
          onClick={onSubmit}
          style={{
            height: 44,
            width: 44,
            borderRadius: 7.6,
            opacity: isDisabled ? 0.2 : 1,
            borderColor: isDisabled ? theme.colors.secondary : theme.colors.primary,
            backgroundColor: isDisabled ? theme.colors.secondary : theme.colors.primary,
          }}
          iconStyle={{ marginTop: 3, marginRight: 2 }}
          icon={theme.images.general.enter}
          iconColor={isDisabled ? '#000' : '#fff'}
          disabled={isDisabled}
          disabledColor={theme.colors.secondary}
        />
      </Send>
    )
  }

  const renderBubble = (props: any) => (
    <Bubble
      {...props}
      textStyle={{
        left: {},
        right: { color: theme.colors.white }
      }}
      containerStyle={{
        left: { marginVertical: 5, borderBottomRightRadius: 7.6 },
        right: { marginVertical: 5, borderBottomRightRadius: 7.6 }
      }}
      wrapperStyle={{
        left: { backgroundColor: '#f7f7f7', padding: 5, borderBottomLeftRadius: 0 },
        right: { backgroundColor: theme.colors.primary, padding: 5, borderBottomRightRadius: 0 }
      }}
    />
  )

  const renderMessageImage = (props: any) => (
    <MessageImage
      {...props}
    />
  )

  const renderScrollToBottomComponent = () => (
    <MaterialCommunityIcon name='chevron-double-down' size={32} />
  )

  const getViewHeight = () => {
    if (Platform.OS === 'android') {
      return '100%';
    } else {
      return height - top - bottom - (isKeyboardShow ? 48 : 0);
    }
  }

  const onLongPress = (context: any, message: any) => {
    const options = [
      t('COPY_TEXT', 'Copy text'),
      t('CANCEL', 'Cancel'),
    ];
    const cancelButtonIndex = options.length - 1;
    context.actionSheet().showActionSheetWithOptions({
      options,
      cancelButtonIndex
    }, (buttonIndex: any) => buttonIndex === 0 && Clipboard.setString(message.text)
    );
  }

  useEffect(() => {
    if (!order?.id || messages?.loading) return
    readMessages && readMessages()
  }, [order?.id, messages?.loading])

  return (
    <View style={{ height: getViewHeight(), width: '100%', paddingTop: 12, backgroundColor: 'white' }}>
      <Wrapper>
        {!isMeesageListing ? (
          <Header>
            <TouchableOpacity onPress={onClose} style={{ paddingStart: 10, borderColor: theme.colors.clear }}>
              <AntDesignIcon name='arrowleft' size={26} />
            </TouchableOpacity>
            <View style={{ marginRight: 10, shadowColor: theme.colors.black, shadowOpacity: 0.1, shadowOffset: { width: 0, height: 1 }, shadowRadius: 2 }}>
              <OIcon
                url={type === USER_TYPE.DRIVER ? order?.driver?.photo : order?.business?.logo}
                width={32}
                height={32}
                style={{ borderRadius: 7.6 }}
              />
            </View>
            <TitleHeader>
              <OText size={14} lineHeight={21} weight={'600'}>{type === USER_TYPE.DRIVER ? order?.driver?.name : order?.business?.name}</OText>
              <OText size={12} color={theme.colors.textSecondary}>{type === USER_TYPE.DRIVER ? t('DRIVER', 'Driver') : t('BUSINESS', 'Business')}</OText>
            </TitleHeader>
          </Header>
        ) : (
          <ProfileMessageHeader>
            <View style={{ ...styles.headerTitle }}>
              <TouchableOpacity onPress={onClose} style={styles.headerItem}>
                <AntDesignIcon name='arrowleft' size={26} />
              </TouchableOpacity>
              <OText size={18}>{t('ORDER', theme?.defaultLanguages?.ORDER || 'Order')} #{order?.id}</OText>
            </View>
            <View style={{ ...styles.typeWraper }}>
              {order.business && (
                <TouchableOpacity
                  onPress={() => onMessages({ business: true, driver: false })}
                >
                  <MessageTypeItem
                    active={business}
                  >
                    <OIcon
                      url={order?.business?.logo || theme.images.dummies.businessLogo}
                      width={32}
                      height={32}
                      style={{ borderRadius: 32 }}
                    />
                  </MessageTypeItem>
                </TouchableOpacity>
              )}

              {order?.driver && (
                <TouchableOpacity
                  onPress={() => onMessages({ business: false, driver: true })}
                >
                  <MessageTypeItem
                    active={driver}
                  >
                    <OIcon
                      url={order?.driver?.photo}
                      width={32}
                      height={32}
                      style={{ borderRadius: 32 }}
                    />
                  </MessageTypeItem>
                </TouchableOpacity>
              )}
            </View>
          </ProfileMessageHeader>
        )}
        <GiftedChat
          messages={formattedMessages}
          user={{
            _id: user.id,
            name: user.name,
            avatar: user.photo
          }}
          onSend={onSubmit}
          onInputTextChanged={onChangeMessage}
          alignTop
          onLongPress={(context: any, message: any) => onLongPress(context, message)}
          scrollToBottom
          renderAvatarOnTop
          renderUsernameOnMessage
          renderAvatar={() => null}
          renderInputToolbar={renderInputToolbar}
          renderComposer={renderComposer}
          renderSend={renderSend}
          renderBubble={renderBubble}
          renderMessageImage={renderMessageImage}
          scrollToBottomComponent={() => renderScrollToBottomComponent()}
          messagesContainerStyle={{
            paddingTop: 18,
            paddingHorizontal: 28,
            paddingBottom: 55
          }}
          isLoadingEarlier={messages.loading}
          renderLoading={() => <ActivityIndicator size="small" color="#000" />}
          keyboardShouldPersistTaps='handled'
        />
      </Wrapper>
    </View>
  )
}

const styles = StyleSheet.create({
  containerActions: {
    width: 44,
    height: 44,
    alignItems: 'center',
    justifyContent: 'center',
    marginHorizontal: 4,
    marginBottom: 0,
  },
  containerSend: {
    width: 64,
    height: 44,
    alignItems: 'center',
    justifyContent: 'center',
    marginHorizontal: 4
  },
  editButton: {
    borderRadius: 50,
    backgroundColor: '#E9ECEF',
    marginRight: 10,
    height: 24,
    borderWidth: 1,
    paddingLeft: 0,
    paddingRight: 0
  },
  headerTitle: {
    flexDirection: 'row',
    alignItems: 'center'
  },
  headerItem: {
    overflow: 'hidden',
    width: 35,
    marginVertical: 18,
  },
  typeWraper: {
    flexDirection: 'row',
    height: 45,
    alignItems: 'center'
  }

})

export const Messages = (props: MessagesParams) => {
  const [allMessages, setAllMessages] = useState(props.messages)

  useEffect(() => {
    setAllMessages(props.messages)
  }, [props.messages])

  const MessagesProps = {
    ...props,
    UIComponent: MessagesUI,
    messages: allMessages,
    setMessages: (values: any) => {
      props.setMessages && props.setMessages(values)
      setAllMessages(values)
    }
  }
  return <MessagesController {...MessagesProps} />
}
