import PenaltyBanner from '@/components/PenalyBanner'
import { useAddTrainMutation } from '@/hooks/mutations/useTrainMutation'
import { useAuth } from '@/hooks/useAuth'
import { useTrain } from '@/hooks/useTrain'
import { TrainTrip } from '@/utils/features/train/trainSlice'
import { FontAwesome6 } from '@expo/vector-icons'
import { useQueryClient } from '@tanstack/react-query'
import { useShareIntentContext } from 'expo-share-intent'
import { useEffect, useMemo, useState } from 'react'
import { FlatList, StyleSheet } from 'react-native'
import { Button, Dialog, Divider, FAB, HelperText, List, MD3Colors, Portal, Snackbar, Surface, Text, TextInput } from 'react-native-paper'

export default function TrainScreen() {
  const [addTrainVisible, setAddTrainVisible] = useState(false)
  const [addTrainUrl, setAddTrainUrl] = useState("")
  const trainId = useMemo(() => /[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}/.exec(addTrainUrl)?.[0], [addTrainUrl])

  const [successSnackbarVisible, setSuccessSnackbarVisible] = useState(false)
  const [errorVisible, setErrorVisible] = useState(false)
  const [error, setError] = useState([200, ""])

  const auth = useAuth()
  const queryClient = useQueryClient()
  const addTrainMutation = useAddTrainMutation({
    auth,
    onPostSuccess: () => {
      setAddTrainVisible(false)
      setSuccessSnackbarVisible(true)
      queryClient.invalidateQueries({ predicate: (query) => query.queryKey[0] === 'get-trains' })
    },
    onError: ({ response, error }) => {
      setErrorVisible(true)
      if (response)
        setError([response.statusCode, response.message])
      else if (error)
        setError([400, error.message])
    },
  })

  const trains = useTrain()


  const { hasShareIntent, shareIntent, resetShareIntent } = useShareIntentContext()
  useEffect(() => {
    console.log(hasShareIntent, shareIntent)
    if (hasShareIntent) {
      resetShareIntent()
      if (!shareIntent.text || !shareIntent.text.includes("eurailapp.com/share"))
        return
      const parsedTrainId = /[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}/.exec(shareIntent.text)?.[0]
      if (parsedTrainId)
        addTrainMutation.mutate(parsedTrainId)
      else {
        setErrorVisible(true)
        setError([400, "Impossible de récupérer l'identifiant du train à ajouter"])
      }
    }
  }, [hasShareIntent])

  return (
    <Surface style={{ flex: 1 }}>
      <PenaltyBanner />
      <FlatList
          data={trains}
          keyExtractor={(train) => train.id}
          ItemSeparatorComponent={() => <Divider />}
          renderItem={(item) => <TrainListItem train={item.item} />} />
      <FAB
          icon='plus'
          style={styles.addTrainButton}
          onPress={() => setAddTrainVisible(true)} />
      <Snackbar
          key='success-snackbar'
          visible={successSnackbarVisible}
          icon={'close'}
          onDismiss={() => setSuccessSnackbarVisible(false)}
          onIconPress={() => setSuccessSnackbarVisible(false)}>
        Train ajouté avec succès
      </Snackbar>
      <Snackbar
          key='error-snackbar'
          visible={errorVisible}
          icon={'close'}
          onDismiss={() => setErrorVisible(false)}
          onIconPress={() => setErrorVisible(false)}>
        <Text variant='bodyMedium' style={{ color: MD3Colors.secondary0 }}>
          Erreur {error[0]} : {error[1]}
        </Text>
      </Snackbar>
      <Portal>
        <Dialog visible={addTrainVisible} onDismiss={() => setAddTrainVisible(false)}>
          <Dialog.Title>Ajout d'un train</Dialog.Title>
          <Dialog.Content>
            <TextInput
                label="URL de partage RailPlanner"
                autoComplete='url'
                inputMode='url'
                defaultValue={addTrainUrl}
                multiline={true}
                onChangeText={setAddTrainUrl}
                error={!trainId}
                onEndEditing={() => {
                  if (trainId !== undefined)
                    addTrainMutation.mutate(trainId)
                }}
                placeholder="https://eurailapp.com/share/journey?id=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&type=list&brand=interrail" />
            <HelperText type='error' visible={!trainId && addTrainVisible}>
              Le champ doit contenir l'identifiant d'un voyage au format UUID. {trainId}
            </HelperText>
          </Dialog.Content>
          <Dialog.Actions>
            <Button onPress={() => setAddTrainVisible(false)}>Annuler</Button>
            <Button onPress={() => {
              if (trainId !== undefined)
                addTrainMutation.mutate(trainId)
            }} disabled={trainId === undefined || addTrainMutation.isPending}>Ajouter</Button>
          </Dialog.Actions>
        </Dialog>
      </Portal>
    </Surface>
  )
}

const styles = StyleSheet.create({
  addTrainButton: {
    position: 'absolute',
    right: 25,
    bottom: 25,
  }
})

function TrainListItem({ train }: { train: TrainTrip }) {
  const depDateTime = new Date(train.departureTime)
  const depDate = depDateTime.toLocaleDateString()
  const depTime = depDateTime.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' })
  const arrDateTime = new Date(train.arrivalTime)
  const arrTime = arrDateTime.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' })
  const durationInMinutes = (arrDateTime.getTime() - depDateTime.getTime()) / 1000 / 60
  const duration = `${Math.floor(durationInMinutes / 60).toString().padStart(2, '0')}:${Math.floor(durationInMinutes % 60).toString().padStart(2, '0')}`
  const title = `${train.from} ${depTime} => ${train.to} ${arrTime} (${depDate})`
  const distanceKm = Math.ceil(train.distance / 1000)
  const cost = 10 * distanceKm
  return <>
    <List.Item
      title={title}
      description={<><Text>Durée : {duration}, distance : {distanceKm} km, coût : {cost}</Text> <FontAwesome6 name='coins' /></>}
      />
    </>
}
