import React, { useState } from 'react'
import {
  View,
  Text,
  Modal,
  TextInput,
  ActivityIndicator,
  LayoutChangeEvent,
  ViewStyle,
} from 'react-native'
import * as Sentry from 'sentry-expo'

import { colors } from '../Colors'
import { TextStyles } from '../Styles'
import { useFeedback } from '../hooks/useFeedback'
import { Strings } from '../i18n'
import { AutoLayout } from './AutoLayout'
import { Button } from './Button'
import { NotificationView } from './NotificationView'
import { TopCloseXButton } from './TopCloseXButton'

type ViewState = 'not-sent' | 'sending' | 'sent' | 'error'

export const useFeedbackModal = (initialOpen = false) => {
  const [feedbackModalOpen, setFeedbackModalOpen] = useState(initialOpen)
  return { feedbackModalOpen, setFeedbackModalOpen }
}

export const FeedbackModal: React.FC<{
  open: boolean
  onClose: () => void
  screenName?: string
  screenTitle?: string
}> = ({ open, onClose, screenName, screenTitle }) => {
  const [viewState, setViewState] = useState<ViewState>('not-sent')
  const [text, setText] = useState<string>()
  const { sendFeedback } = useFeedback()

  const handleOnSubmit = async (text: string) => {
    setViewState('sending')

    try {
      await sendFeedback(text, screenName, screenTitle)
      setViewState('sent')
    } catch (error) {
      console.error(error)
      Sentry.Native.captureException(error)

      setViewState('error')
    }
  }

  const handleOnClose = () => {
    setViewState('not-sent')
    setText(undefined)
    onClose()
  }

  const handleOnRetry = () => {
    setViewState('not-sent')
  }

  const renderContent = () => {
    if (viewState === 'error') {
      return (
        <NotificationView
          title={Strings.Feedback.Error}
          buttonText={Strings.Shared.Retry}
          onPressButton={handleOnRetry}
          type="error"
        />
      )
    }

    if (viewState === 'sent') {
      return (
        <NotificationView
          title={Strings.Feedback.ThankYou}
          buttonText={Strings.Shared.Dismiss}
          onPressButton={handleOnClose}
          type="success"
        />
      )
    }

    return (
      <FeedbackForm
        text={text}
        onChangeText={setText}
        onSubmit={handleOnSubmit}
        sending={viewState === 'sending'}
      />
    )
  }

  return (
    <Modal
      animationType="slide"
      transparent={false}
      visible={open}
      onRequestClose={onClose}
    >
      <View
        style={{
          flex: 1,
          paddingTop: 44,
          paddingBottom: 41,
          paddingHorizontal: 16,
          backgroundColor: colors.metals.metal3,
        }}
      >
        <Header onClose={handleOnClose} />
        {renderContent()}
      </View>
    </Modal>
  )
}

const FeedbackForm: React.FC<{
  text?: string
  onChangeText: (text: string) => void
  onSubmit: (text: string) => void
  sending: boolean
}> = ({ text, onChangeText, onSubmit, sending }) => {
  const [submitButtonStyle, setSubmitButtonStyle] = useState<ViewStyle>()

  return (
    <AutoLayout gap={24}>
      <Text
        style={{
          ...TextStyles.h4,
          color: colors.midWhite,
          marginBottom: 10,
        }}
      >
        {Strings.Feedback.FeedbackTitle}
      </Text>
      <Text
        style={{
          fontFamily: 'Montserrat Regular',
          fontSize: 16,
          color: colors.offWhite,
          lineHeight: 22,
        }}
      >
        {Strings.Feedback.FeedbackText}
      </Text>
      <View>
        <TextInput
          defaultValue={text}
          onChangeText={onChangeText}
          multiline
          autoFocus
          textAlignVertical="center"
          placeholder={Strings.Feedback.TellUsMore}
          placeholderTextColor={colors.offWhite}
          style={{
            fontFamily: 'Montserrat Regular',
            height: 200,
            padding: 16,
            paddingTop: 16, // For some reason paddingTop is needed to have a multiline text field obey the padding
            borderColor: sending ? colors.metals.metal1 : colors.offWhite,
            borderWidth: 2,
            borderRadius: 8,
            fontSize: 16,
            color: colors.white,
            lineHeight: 22,
          }}
        />
      </View>
      <Button
        type="filled"
        onPress={() => {
          if (!text) {
            return
          }
          onSubmit(text)
        }}
        muted={!text || sending}
        onLayout={(event: LayoutChangeEvent) => {
          // Skip if the width is already known
          if (submitButtonStyle) {
            return
          }

          setSubmitButtonStyle({ width: event.nativeEvent.layout.width })
        }}
        style={[{ alignSelf: 'flex-end' }, submitButtonStyle]}
        textStyle={sending && { color: colors.offWhite }}
      >
        {!sending ? Strings.Shared.Submit : <ActivityIndicator />}
      </Button>
    </AutoLayout>
  )
}

const Header: React.FC<{ onClose: () => void }> = ({ onClose }) => (
  <View
    style={{
      alignItems: 'flex-end',
    }}
  >
    <TopCloseXButton onPress={onClose} />
  </View>
)
