import FormNavigation from 'components/CommonKit/FormNavigation/FormNavigation'
import FormProgress from 'components/CommonKit/FormProgress/FormProgress'
import Content from 'components/Content/Content'
import CozyBar from 'components/Header/CozyBar'
import Header from 'components/Header/Header'
import useKonnectorAuth from 'components/Hooks/useKonnectorAuth'
import useUserInstanceSettings from 'components/Hooks/useUserInstanceSettings'
import { useClient } from 'cozy-client'
import { FORM_DOCTYPE } from 'doctypes'
import { FluidType } from 'enums'
import { AccountGRDFData } from 'models'
import React, { useCallback, useEffect, useRef, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { useAppSelector } from 'store/hooks'
import '../connection.scss'
import { createInitialGrdfState, useFormData } from '../useForm'
import StepConsent from './StepConsent'
import { StepIdentity } from './StepIdentity'

export enum GrdfStep {
  Identity,
  Consent,
}

/**
 * http://ecolyo.cozy.tools:8080/#/connect/gas
 */
export const GrdfConnectView = () => {
  const client = useClient()
  const navigate = useNavigate()
  const { formData } = useFormData()
  const { instanceSettings } = useUserInstanceSettings()
  const { fluidStatus } = useAppSelector(state => state.ecolyo.global)
  const currentFluidStatus = fluidStatus[FluidType.GAS]
  const account = currentFluidStatus.connection.account

  const [launchConnection, setLaunchConnection] = useState(false)
  const [currentStep, setCurrentStep] = useState<GrdfStep>(GrdfStep.Identity)
  const [grdfState, setGrdfState] = useState<AccountGRDFData>(
    createInitialGrdfState()
  )
  const [formConsent, setFormConsent] = useState({
    dataConsent: false,
    pceConfirm: false,
  })

  const mainContentRef = useRef<HTMLDivElement>(null)
  const focusMainContent = () => {
    setTimeout(() => mainContentRef.current?.focus(), 0)
  }

  const [connect, update] = useKonnectorAuth(FluidType.GAS, {
    grdfAuthData: grdfState,
  })

  useEffect(() => {
    setGrdfState(prev => ({
      ...prev,
      ...createInitialGrdfState(formData),
    }))
  }, [formData])

  useEffect(() => {
    setGrdfState(prev => ({
      ...prev,
      email: instanceSettings.email ?? prev.email,
    }))
  }, [instanceSettings])

  useEffect(() => {
    async function launchConnect() {
      if (launchConnection) {
        setLaunchConnection(false)
        if (!account) {
          await connect()
        } else {
          await update()
        }

        navigate('/consumption/gas')
      }
    }
    launchConnect()
  }, [account, connect, launchConnection, navigate, update])

  const isNextValid = useCallback(() => {
    if (currentStep === GrdfStep.Identity) {
      return (
        grdfState.firstname !== '' &&
        grdfState.lastname !== '' &&
        grdfState.postalCode !== '' &&
        grdfState.email.includes('@') &&
        grdfState.pce.length === 14
      )
    } else if (currentStep === GrdfStep.Consent) {
      return formConsent.dataConsent && formConsent.pceConfirm
    }
    return false
  }, [
    currentStep,
    formConsent.dataConsent,
    formConsent.pceConfirm,
    grdfState.email,
    grdfState.firstname,
    grdfState.lastname,
    grdfState.pce,
    grdfState.postalCode,
  ])

  const handleNext = useCallback(() => {
    if (!isNextValid()) return
    if (currentStep < GrdfStep.Consent) {
      setCurrentStep(prev => prev + 1)
      client.save({
        ...formData,
        _type: FORM_DOCTYPE,
        firstName: grdfState.firstname,
        lastName: grdfState.lastname,
        email: grdfState.email,
        pce: grdfState.pce,
        zipCode: grdfState.postalCode,
      })
    }
    if (currentStep === GrdfStep.Consent) {
      setLaunchConnection(true)
    }
    focusMainContent()
  }, [
    client,
    currentStep,
    formData,
    grdfState.firstname,
    grdfState.lastname,
    grdfState.email,
    grdfState.pce,
    grdfState.postalCode,
    isNextValid,
  ])

  const handlePrev = () => {
    setCurrentStep(prev => prev - 1)
    focusMainContent()
  }

  const renderStep = (step: GrdfStep) => {
    if (step === GrdfStep.Identity) {
      return <StepIdentity formData={grdfState} setFormData={setGrdfState} />
    } else {
      return (
        <StepConsent
          formConsent={formConsent}
          setFormConsent={setFormConsent}
        />
      )
    }
  }

  return (
    <>
      <CozyBar titleKey="common.title_gas_connect" displayBackArrow={true} />
      <Header
        desktopTitleKey="common.title_gas_connect"
        displayBackArrow={true}
      />
      <Content>
        <div ref={mainContentRef} className="connectView" tabIndex={-1}>
          <div className="stepContainer">
            <FormProgress
              currentStep={currentStep}
              totalSteps={Object.keys(GrdfStep).length / 2}
            />
            {renderStep(currentStep)}
          </div>
          <FormNavigation
            handlePrevious={handlePrev}
            handleNext={handleNext}
            isLoading={false}
            disableNextButton={!isNextValid()}
            disablePrevButton={currentStep === GrdfStep.Identity}
            isLastStep={currentStep === GrdfStep.Consent}
          />
        </div>
      </Content>
    </>
  )
}