import React, { useEffect, useMemo, useState } from 'react'

import ButtonWithProgress from '@agiliza/components/atoms/ButtonWithProgress'
import FirstAccessTemplate, { initState } from '@agiliza/components/templates/FirstAccess'
import { useFormState } from '@agiliza/utils/hooks/state'
import { values } from '@agiliza/utils/method'
import { isValidCPF } from '@agiliza/utils/validators'
import {
  Button,
  Dialog,
  DialogActions,
  DialogContent,
  DialogProps,
  DialogTitle,
  MobileStepper
} from '@material-ui/core'
import { withStyles, WithStyles } from '@material-ui/core/styles'
import {
  KeyboardArrowLeft as KeyboardArrowLeftIcon,
  KeyboardArrowRight as KeyboardArrowRightIcon
} from '@material-ui/icons'

import { connected, ConnectedProps } from './connect'
import CreatePassword from './CreatePassword'
import styles from './styles'
import VerifyCode from './VerifyCode'
import VerifyCPF from './VerifyCPF'

type ExtendedProps = Pick<DialogProps, 'open'> & WithStyles<typeof styles> & ConnectedProps

interface Props extends ExtendedProps {
  onClose: () => void
}

const FirstAccessDialog = (props: Props) => {
  const { classes, open, onClose, context, fetching, sendingCode } = props

  const { state, actions } = useFormState('firstAccessForm', initState)
  const [code, setCode] = useState('')
  const [password, setPassword] = useState('')
  const [confirmPassword, setConfirmPassword] = useState('')

  useEffect(() => {
    if (!context.states.length) props.getContext()
  }, [])

  const { states, cities } = context

  const [activeStep, setActiveStep] = useState(0)

  const { cpf, email } = state

  const handleNext = () => {
    switch (activeStep) {
      case 0:
        props.verifyCPF({
          cpf,
          onSuccess: () => setActiveStep((prevActiveStep) => prevActiveStep + 1),
        })
        break
      case 1:
        props.createCustomer({
          ...state,
          onSuccess: () => {
            props.sendCode({ cpf, email, onSuccess: () => setActiveStep((prevActiveStep) => prevActiveStep + 1) })
          },
        })
        break
      case 2:
        props.verifyCode({ cpf, code, onSuccess: () => setActiveStep((prevActiveStep) => prevActiveStep + 1) })
        break
      case 3:
        props.createPassword({
          cpf,
          code,
          password,
          onSuccess: () => {
            props.login({ username: cpf, password, onSuccess: onClose })
          },
        })
        break
      default:
        setActiveStep((prevActiveStep) => prevActiveStep + 1)
    }
  }

  const handleBack = () => {
    setActiveStep((prevActiveStep) => prevActiveStep - 1)
  }

  const steps = useMemo(() => 4, [])

  const canGoForward = useMemo(() => {
    switch (activeStep) {
      case 0:
        return isValidCPF(state.cpf)
      case 1:
        return values(state).every((st) => !!st)
      case 2:
        return !!code
      case 3:
        return password && confirmPassword && password === confirmPassword
    }
  }, [state, code, activeStep, confirmPassword, password])

  const renderStep = (step: number) => {
    switch (step) {
      case 0:
        return <VerifyCPF cpf={state.cpf} onChange={(cpf) => actions.update({ cpf })} />
      case 1:
        return <FirstAccessTemplate state={state} actions={actions} states={states} cities={cities} />
      case 2:
        return <VerifyCode code={code} onChange={(value) => setCode(value)} onResendCode={() => props.sendCode({ cpf, email })} />
      case 3:
        return (
          <CreatePassword
            password={password}
            confirmPassword={confirmPassword}
            onChange={(type) => (value) => {
              if (type === 'password') setPassword(value)
              if (type === 'confirmPassword') setConfirmPassword(value)
            }}
          />
        )
    }
  }

  return (
    <Dialog onClose={onClose} aria-labelledby="simple-dialog-title" open={open} PaperProps={{ className: classes.dialog }}>
      <DialogTitle>Primeiro acesso</DialogTitle>
      <DialogContent>{renderStep(activeStep)}</DialogContent>
      <DialogActions>
        <MobileStepper
          variant="dots"
          steps={steps}
          position="static"
          activeStep={activeStep}
          className={classes.stepper}
          nextButton={
            <ButtonWithProgress
              fetching={fetching || sendingCode}
              size="small"
              variant="text"
              onClick={handleNext}
              disabled={!canGoForward || activeStep === steps}
            >
              {activeStep === steps - 1 ? (
                'Finalizar'
              ) : (
                <>
                  Próximo
                  <KeyboardArrowRightIcon />
                </>
              )}
            </ButtonWithProgress>
          }
          backButton={
            <Button size="small" onClick={handleBack} disabled={activeStep === 0}>
              <KeyboardArrowLeftIcon />
              Anterior
            </Button>
          }
        />
      </DialogActions>
    </Dialog>
  )
}

export default connected(withStyles(styles)(FirstAccessDialog))
