import {useCallback, useEffect, useState} from 'react'
import {styled} from '@mui/material/styles'
import PropTypes from 'prop-types'
import axios from 'axios'
import {
  Box,
  Button,
  Container,
  FormControl,
  FormHelperText,
  Grid,
  IconButton,
  InputAdornment,
  InputLabel,
  LinearProgress,
  OutlinedInput,
  Snackbar,
  TextField,
  Tooltip,
  Typography
} from '@mui/material'
import MuiAlert from '@mui/material/Alert'
import CloseIcon from '@mui/icons-material/Close'

import AjouteTradiksyon from './ajoute-tradiksyon'

const PREFIX = 'EkriTeks'

const classes = {
  tooltip: `${PREFIX}-tooltip`
}

const StyledContainer = styled(Container)(() => ({
  [`& .${classes.tooltip}`]: {
    fontSize: 18
  }
}))

const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:1337'

const textLabels = {
  fr: {
    title: 'Traduction',
    help: 'Traduction des paroles de la musique',
    emoji: '&#127467;&#127479;'
  },
  en: {
    title: 'Translation',
    help: 'Translation of music lyrics',
    emoji: '&#127468;&#127463;'
  },
  es: {
    title: 'Traducción',
    help: 'Traducción de la letra de la música',
    emoji: '&#127466;&#127480;'
  }
}

function Alert(props) {
  return <MuiAlert elevation={6} variant='filled' {...props} />
}

const RemoveTooltip = Tooltip

function EkriTeks({session}) {
  const {jwt, user} = session
  const [teksEkri, setTeksEkri] = useState({awtis: '', tit: '', transkripsyon: ''})
  const [tradiksyon, setTradiksyon] = useState({fr: '', en: '', es: ''})
  const [kiChawLang, setKiChwalang] = useState([])
  const [error, setError] = useState('')
  const [success, setSuccess] = useState('')
  const [loading, setLoading] = useState(false)
  const [open, setOpen] = useState(false)

  const handleUpdate = useCallback(update => {
    setTeksEkri({...teksEkri, ...update})
  }, [teksEkri])

  const handleUpdateTradiksyon = useCallback(update => {
    setTradiksyon({...tradiksyon, ...update})
  }, [tradiksyon])

  const handleRemoveTradiksyon = useCallback(idTradiksyon => {
    setKiChwalang(kiChawLang.filter(t => t !== idTradiksyon))
    setTradiksyon({[tradiksyon.idTradiksyon]: ''})
  }, [kiChawLang, setKiChwalang, setTradiksyon, tradiksyon])

  const handleClose = (event, reason) => {
    if (reason === 'clickaway') {
      return
    }

    setOpen(false)
    setSuccess('')
    setError('')
  }

  const handleClick = () => {
    setLoading(true)
    const {awtis, tit, transkripsyon} = teksEkri
    const {fr, en, es} = tradiksyon

    if (teksEkri.awtis === '' || teksEkri.tit === '' || teksEkri.transkripsyon === '') {
      setError({message: 'Certains champs sont obligatoires'})
      setLoading(false)

      return
    }

    const headers = {
      'content-type': 'application/json',
      Authorization: `Bearer ${jwt}`
    }

    axios.post(`${API_URL}/awtis`, {
      alias: awtis,
      user
    }, {
      headers
    })
      .then(awtisResponse => {
        axios.post(`${API_URL}/teks`, {
          tit,
          transkripsyon,
          tradiksyon: {
            francais: fr === '' ? null : fr,
            english: en === '' ? null : en,
            espagnol: es === '' ? null : es
          },
          user,
          awtis: [awtisResponse.data._id]
        }, {
          headers
        })
          .then(teksResponse => {
            const {data} = teksResponse
            setSuccess(`Le texte "${data.tit}" a été soumis avec succès. Il apparaîtra sur le site après validation.`)
            setLoading(false)
          })
          .catch(error => {
            setError(error)
            setLoading(false)
          })
      })
      .catch(error => {
        setError(error)
        setLoading(false)
      })
  }

  const handleReset = () => {
    setTeksEkri({awtis: '', tit: '', transkripsyon: ''})
    setTradiksyon({fr: '', en: '', es: ''})
    setKiChwalang([])
  }

  useEffect(() => {
    if (success) {
      setOpen(true)
      handleReset()
    }
  }, [success])

  useEffect(() => {
    if (error) {
      setOpen(true)
    }
  }, [error])

  return (
    <StyledContainer maxWidth='sm'>
      <Box sx={{textAlign: 'center', marginBottom: 2}}>
        <Typography display='inline' variant='h5' component='h1'>
          Soumettre un texte
        </Typography>
      </Box>
      <form noValidate autoComplete='off'>
        <Grid container style={{textAlign: 'center'}} spacing={1}>
          <Grid item xs>
            <TextField
              required
              id='awtis'
              name='awtis'
              label='Artiste'
              value={teksEkri.awtis}
              variant='outlined'
              helperText='Nom de l’artiste (obligatoire)'
              onChange={event => handleUpdate({awtis: event.target.value})}
            />
          </Grid>
          <Grid item xs>
            <TextField
              required
              id='tit'
              name='tit'
              label='Titre'
              value={teksEkri.tit}
              variant='outlined'
              helperText='Titre de la musique (obligatoire)'
              onChange={event => handleUpdate({tit: event.target.value})}
            />
          </Grid>
        </Grid>
        <TextField
          fullWidth
          multiline
          required
          helperText='Transcription des paroles de la musique (obligatoire)'
          style={{marginTop: '1em'}}
          id='transkripsyon'
          label='Transcription'
          value={teksEkri.transkripsyon}
          rows={8}
          variant='outlined'
          onChange={event => handleUpdate({transkripsyon: event.target.value})}
        />
        {kiChawLang.length > 0 && kiChawLang.map(k => (
          <FormControl key={k} fullWidth style={{marginBlock: 10}}>
            <InputLabel htmlFor={`tradiksyon-${k}`}>
              <span dangerouslySetInnerHTML={{__html: textLabels[k].emoji}} /> {textLabels[k].title}
            </InputLabel>
            <OutlinedInput
              multiline
              style={{marginTop: '1em'}}
              id={`tradiksyon-${k}`}
              name={`tradiksyon-${k}`}
              label={`${textLabels[k].title}`}
              value={tradiksyon[k]}
              rows={8}
              endAdornment={
                <InputAdornment position='end'>
                  <RemoveTooltip
                    title='Effacer la traduction'
                    placement='left'
                    classes={{
                      tooltip: classes.tooltip
                    }}
                  >
                    <IconButton
                      color='secondary'
                      style={{bottom: 75}}
                      aria-label='remove-tradiksyon'
                      edge='end'
                      size='large'
                      onClick={() => handleRemoveTradiksyon(k)}
                    >
                      <CloseIcon />
                    </IconButton>
                  </RemoveTooltip>
                </InputAdornment>
              }
              onChange={event => handleUpdateTradiksyon({[k]: event.target.value})}
            />
            <FormHelperText id={`tradiksyon-${k}`}>{textLabels[k].help}</FormHelperText>
          </FormControl>
        ))}
      </form>
      <AjouteTradiksyon chwaLang={kiChawLang} setChwaLang={setKiChwalang} />
      <div>
        <Button
          fullWidth
          disabled={loading || teksEkri.awtis === '' || teksEkri.tit === '' || teksEkri.transkripsyon === ''}
          style={{marginBlock: 20}}
          variant='contained'
          color='primary'
          onClick={handleClick}
        >
          <Typography style={{fontWeight: 'bold'}}>
            Valider
          </Typography>
        </Button>
        {loading && <LinearProgress size={24} style={{width: '100%', marginBlock: '1em'}} />}
      </div>
      {success && (
        <Snackbar open={open} autoHideDuration={10_000} onClose={handleClose}>
          <Alert severity='success' onClose={handleClose}>
            <strong>{success}</strong>
          </Alert>
        </Snackbar>
      )}
      {error && (
        <Snackbar open={open} autoHideDuration={6000} onClose={handleClose}>
          <Alert severity='error' onClose={handleClose}>
            <strong>Une erreur s’est produite</strong> : <i>{error.message}</i>
          </Alert>
        </Snackbar>
      )}
    </StyledContainer>
  )
}

EkriTeks.propTypes = {
  session: PropTypes.object.isRequired
}

export default EkriTeks
