import { Button, FormControl, InputLabel, MenuItem, Popover, TextField } from '@material-ui/core'
import { Alert, AlertTitle } from '@material-ui/lab'
import axios from 'axios'
import { Formik, FormikHelpers } from 'formik'
import React from 'react'
import * as Yup from 'yup'
import { getCompetitions } from '../../../actions/competitions'
import { useAppDispatch, useAppSelector } from '../../../hooks'
import { City } from '../../../interfaces/ApiModels'
import { AddCompetitionModel, FormModel } from '../../../interfaces/FormModels'
import { AddButton, AddContent, AddForm } from '../styledComp'

type formType = FormModel<AddCompetitionModel>

const noCitySelected = 'Välj stad'

const competitionSchema: Yup.SchemaOf<formType> = Yup.object({
  model: Yup.object()
    .shape({
      name: Yup.string().required('Namn krävs'),
      city: Yup.string().required('Stad krävs').notOneOf([noCitySelected], 'Välj en stad'),
      year: Yup.number()
        .integer('År måste vara ett heltal')
        .required('År krävs')
        .moreThan(1999, 'År måste vara minst 2000'),
    })
    .required(),
  error: Yup.string().optional(),
})

const AddCompetition: React.FC = (props: any) => {
  const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(null)
  const cities = useAppSelector((state) => state.cities.cities)
  const currentUser = useAppSelector((state) => state.user.userInfo)
  const userCity = cities.find((city) => city.id === currentUser?.city_id)
  const [selectedCity, setSelectedCity] = React.useState<City | undefined>(userCity)
  const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
    setAnchorEl(event.currentTarget)
  }
  const handleClose = () => {
    setAnchorEl(null)
  }

  const open = Boolean(anchorEl)
  const dispatch = useAppDispatch()
  const id = open ? 'simple-popover' : undefined
  const currentYear = new Date().getFullYear()
  const handleCompetitionSubmit = async (values: formType, actions: FormikHelpers<formType>) => {
    const params = {
      name: values.model.name,
      year: values.model.year,
      city_id: selectedCity?.id as number,
    }
    await axios
      .post('/competitions', params)
      .then(() => {
        actions.resetForm()
        setAnchorEl(null)
        dispatch(getCompetitions())
        setSelectedCity(undefined)
      })
      .catch(({ response }) => {
        console.warn(response.data)
        if (response.data && response.data.message)
          actions.setFieldError('error', response.data && response.data.message)
        else actions.setFieldError('error', 'Something went wrong, please try again')
      })
      .finally(() => {
        actions.setSubmitting(false)
      })
  }

  const competitionInitialValues: formType = {
    model: { name: '', city: userCity?.name ? userCity.name : noCitySelected, year: currentYear },
  }
  return (
    <div>
      <AddButton
        style={{ backgroundColor: '#4caf50', color: '#fcfcfc' }}
        color="default"
        variant="contained"
        onClick={handleClick}
      >
        Ny Tävling
      </AddButton>
      <Popover
        id={id}
        open={open}
        anchorEl={anchorEl}
        onClose={handleClose}
        anchorOrigin={{
          vertical: 'bottom',
          horizontal: 'center',
        }}
        transformOrigin={{
          vertical: 'top',
          horizontal: 'center',
        }}
      >
        <AddContent>
          <Formik
            initialValues={competitionInitialValues}
            validationSchema={competitionSchema}
            onSubmit={handleCompetitionSubmit}
          >
            {(formik) => (
              <AddForm onSubmit={formik.handleSubmit}>
                <TextField
                  label="Namn"
                  name="model.name"
                  helperText={formik.touched.model?.name ? formik.errors.model?.name : ''}
                  error={Boolean(formik.touched.model?.name && formik.errors.model?.name)}
                  onChange={formik.handleChange}
                  onBlur={formik.handleBlur}
                  margin="normal"
                />
                <FormControl>
                  <InputLabel shrink id="demo-customized-select-native">
                    Region
                  </InputLabel>
                  <TextField
                    select
                    name="model.city"
                    id="standard-select-currency"
                    value={selectedCity ? selectedCity.name : noCitySelected}
                    onChange={formik.handleChange}
                    onBlur={formik.handleBlur}
                    error={Boolean(formik.errors.model?.city && formik.touched.model?.city)}
                    helperText={formik.touched.model?.city && formik.errors.model?.city}
                    margin="normal"
                  >
                    <MenuItem value={noCitySelected} onClick={() => setSelectedCity(undefined)}>
                      {noCitySelected}
                    </MenuItem>
                    {cities &&
                      cities.map((city) => (
                        <MenuItem key={city.name} value={city.name} onClick={() => setSelectedCity(city)}>
                          {city.name}
                        </MenuItem>
                      ))}
                  </TextField>
                </FormControl>
                <TextField
                  label="År"
                  name="model.year"
                  type="number"
                  defaultValue={formik.initialValues.model.year}
                  helperText={formik.touched.model?.year ? formik.errors.model?.year : ''}
                  error={Boolean(formik.touched.model?.year && formik.errors.model?.year)}
                  onChange={formik.handleChange}
                  onBlur={formik.handleBlur}
                  margin="normal"
                />
                <Button
                  type="submit"
                  fullWidth
                  variant="contained"
                  color="secondary"
                  disabled={!formik.isValid || !formik.values.model?.name || !formik.values.model?.city}
                >
                  Skapa
                </Button>
                {formik.errors.error && (
                  <Alert severity="error">
                    <AlertTitle>Error</AlertTitle>
                    {formik.errors.error}
                  </Alert>
                )}
              </AddForm>
            )}
          </Formik>
        </AddContent>
      </Popover>
    </div>
  )
}

export default AddCompetition