import React, { useCallback, useReducer } from 'react';
import { ThemedText, ThemedView } from '@/components/theme/Theme';
import { Alert, Linking, Platform, StyleSheet } from 'react-native';
import { MaterialIcons } from '@expo/vector-icons';
import {
  GiftedChat,
  IMessage,
  Send,
  SendProps,
  SystemMessage,
} from 'react-native-gifted-chat';
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
import AccessoryBar from '@/components/chat/AccessoryBar';
import CustomActions from '@/components/chat/CustomActions';
import CustomView from '@/components/chat/CustomView';
//import NavBar from '@/components/chat/NavBar';
import earlierMessages from '@/components/chat/data/earlierMessages';
import messages from '@/components/chat/data/messages';
import * as Clipboard from 'expo-clipboard';
import {
  GCUser,
  GCState,
  GCStateAction,
  ActionKind,
} from '@/constants/Types';

const tempUser: GCUser = {
  _id: 1,
  name: 'Developer',
};

const reducer = (state: GCState, action: GCStateAction) => {
  switch (action.type) {
    case ActionKind.SEND_MESSAGE: {
      return {
        ...state,
        step: state.step + 1,
        messages: action.payload,
      };
    }
    case ActionKind.LOAD_EARLIER_MESSAGES: {
      return {
        ...state,
        loadEarlier: true,
        isLoadingEarlier: false,
        messages: action.payload,
      };
    }
    case ActionKind.LOAD_EARLIER_START: {
      return {
        ...state,
        isLoadingEarlier: true,
      }
    }
    case ActionKind.SET_IS_TYPING: {
      return {
        ...state,
        isTyping: action.payload,
      }
    }
  }
};

const MessagesScreen = () => {
  const [state, dispatch] = useReducer(reducer, {
    messages: messages,
    step: 0,
    loadEarlier: true,
    isLoadingEarlier: false,
    isTyping: false,
  })

  const onSend = useCallback((messages: any[]) => {
    const sentMessages = [{ ...messages[0], sent: true, received: true }]
    const newMessages = GiftedChat.append(
      state.messages, sentMessages, Platform.OS !== 'web'
    );
    dispatch({ type: ActionKind.SEND_MESSAGE, payload: newMessages });
  }, [dispatch, state.messages]);

  const onLoadEarlier = useCallback(() => {
    dispatch({ type: ActionKind.LOAD_EARLIER_START });
    setTimeout(() => {
      const newMessages = GiftedChat.prepend(
        state.messages, earlierMessages() as IMessage[], Platform.OS !== 'web'
      );
      dispatch({ type: ActionKind.LOAD_EARLIER_MESSAGES, payload: newMessages })
    }, 1500) // simulating network
  }, [dispatch, state.messages]);

  const parsePatterns = useCallback(() => {
    return [
      {
        pattern: /#(\w+)/g,
        style: { textDecorationLine: 'underline', color: 'darkorange' },
        onPress: () => Linking.openURL('https://www.gbrown.org'),
      },
    ]
  }, []);

  const onLongPressAvatar = useCallback((pressedUser: any) => {
    Alert.alert(JSON.stringify(pressedUser))
  }, []);

  const onPressAvatar = useCallback(() => {
    Alert.alert('Pressed avatar!')
  }, []);

  const handleLongPress = useCallback((context: unknown, currentMessage: object) => {
    if (!currentMessage.text) return;
    const options = [
      'Copy text',
      'Cancel',
    ]
    const cancelButtonIndex = options.length - 1;
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    (context as any).actionSheet().showActionSheetWithOptions(
      { options, cancelButtonIndex },
      (buttonIndex: number) => {
        switch (buttonIndex) {
          case 0:
            Clipboard.setStringAsync(currentMessage.text);
            break;
          default: break;
        }
      }
    )
  }, []);

  const onQuickReply = useCallback((replies: any[]) => {
    const createdAt = new Date();
    if (replies.length === 1)
      onSend([
        {
          createdAt,
          _id: Math.round(Math.random() * 1000000),
          text: replies[0].title,
          tempUser,
        },
      ]);
    else if (replies.length > 1)
      onSend([
        {
          createdAt,
          _id: Math.round(Math.random() * 1000000),
          text: replies.map(reply => reply.title).join(', '),
          tempUser,
        },
      ]);
    else console.warn('replies param is not set correctly');
  }, []);

  const renderQuickReplySend = useCallback(() => {
    return <ThemedText>{'custom send =>'}</ThemedText>
  }, []);

  const setIsTyping = useCallback((isTyping: boolean) => {
    dispatch({ type: ActionKind.SET_IS_TYPING, payload: isTyping });
  }, [dispatch]);

  const onSendFromUser = useCallback((messages: IMessage[] = []) => {
    const createdAt = new Date();
    const messagesToUpload = messages.map(message => ({
      ...message, tempUser, createdAt, id: Math.round(Math.random() * 1000000),
    }));
    onSend(messagesToUpload);
  }, [onSend]);

  const renderAccessory = useCallback(() => {
    return (
      <AccessoryBar
        onSend={onSendFromUser}
        isTyping={() => setIsTyping(!state.isTyping)}
      />
    );
  }, [onSendFromUser, setIsTyping, state.isTyping]);

  const renderCustomActions = useCallback(
    props =>
      Platform.OS === 'web' ? null : (
        <CustomActions {...props} onSend={onSendFromUser} />
      ),
    [onSendFromUser]
  );

  const renderSystemMessage = useCallback(props => {
    return (
      <SystemMessage
        {...props}
        containerStyle={{marginBottom: 15}}
        textStyle={{fontSize: 14}}
      />
    );
  }, []);

  const renderCustomView = useCallback(props => {
    return <CustomView {...props} />
  }, []);

  const renderSend = useCallback((props: SendProps<IMessage>) => {
    return (
      <Send
        {...props}
        containerStyle={{justifyContent: 'center', paddingHorizontal: 10}}
      >
        <MaterialIcons size={30} color={'tomato'} name={'send'} />
      </Send>
    );
  }, []);
  return (
    <SafeAreaView style={styles.fill}>
      <ThemedView style={styles.fill}>
        <GiftedChat
          messages={state.messages}
          onSend={onSend}
          loadEarlier={state.loadEarlier}
          onLoadEarlier={onLoadEarlier}
          isLoadingEarlier={state.isLoadingEarlier}
          parsePatterns={parsePatterns}
          user={tempUser}
          scrollToBottom
          onPressAvatar={onPressAvatar}
          onLongPressAvatar={onLongPressAvatar}
          onLongPress={handleLongPress}
          onQuickReply={onQuickReply}
          quickReplyStyle={{ borderRadius: 2 }}
          quickReplyTextStyle={{
            fontWeight: '200',
          }}
          renderQuickReplySend={renderQuickReplySend}
          //renderAccessory={renderAccessory}
          renderActions={renderCustomActions}
          renderSystemMessage={renderSystemMessage}
          renderCustomView={renderCustomView}
          renderSend={renderSend}
          keyboardShouldPersistTaps='never'
          timeTextStyle={{
            left: { color: 'red' },
            right: { color: 'yellow' },
          }}
          isTyping={state.isTyping}
          inverted={Platform.OS !== 'web'}
          infiniteScroll
        />
      </ThemedView>
    </SafeAreaView>
  )
};

const ChatWrapper = () => {
  return (
    <SafeAreaProvider><MessagesScreen /></SafeAreaProvider>
  );
};

export default ChatWrapper;

const styles = StyleSheet.create({
  fill: {
    flex: 1,
  },
});
