'use client'

import React, {
  useState,
  type FormEvent,
  type ChangeEvent,
  useEffect,
  useTransition
} from 'react'
import { useAuthStore } from '@/zustand/authStore'
import { useParams, useRouter } from 'next/navigation'
import StepEnterNumber from '@/features/auth/components/StepEnterNumber'
import StepEnterOtp from '@/features/auth/components/StepEnterOtp'
import { AUTH_PAGE_ELEMENT, AUTH_STEP } from '@/enums'
import { useCountdown } from '@/hooks/useCountdown'
import StepNewPassword from '@/features/auth/components/StepNewPassword'
import AuthFormWrapper from '@/features/auth/components/AuthFormWrapper'
import { useCheckUserExistsLazy } from '@/hooks/auth/useCheckUserExists'
import { useOtpRequest } from '@/hooks/auth/useOtpRequest'
import { useOtpValidation } from '@/hooks/auth/useOtpValidation'
import { useResetPassword } from '@/hooks/auth/useResetPassword'
import { useAuthTempStore } from '@/zustand/authTempStroe'

type Props = object

function AuthIndex ({}: Props) {
  const update_temp_store = useAuthTempStore(state => state.update)
  const user_temp_store = useAuthTempStore(state => state.user)
  const user_auth_store = useAuthStore(state => state.user)
  const isAuthenticated = useAuthStore(state => state.isAuthenticated)
  const [number, setNumber] = useState(
    user_temp_store?.number ?? user_auth_store?.number ?? ''
  )
  const [password, setPassword] = useState('')
  const [passwordRepeat, setPasswordRepeat] = useState('')
  const [otp, setOtp] = useState('')
  const [showPassword, setShowPassword] = useState(false)
  const [showPasswordRepeat, setShowPasswordRepeat] = useState(false)
  const [step, setStep] = useState(
    number == '' ? AUTH_STEP.ENTER_NUMBER : AUTH_STEP.ENTER_OTP
  )
  const { timerRunning, secondsLeft, restart, stop } = useCountdown(
    step === AUTH_STEP.ENTER_OTP
  )
  const [isPending, startTransition] = useTransition()

  const { run: runUserExistCheck } = useCheckUserExistsLazy()
  const { run: runOtpRequest } = useOtpRequest()
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const { run: runOtpValidation } = useOtpValidation()
  const { run: runResetPassword } = useResetPassword()
  const router = useRouter()
  const { name } = useParams()
  const basePath = `/${name ?? ''}`

  useEffect(() => {
    if (step === AUTH_STEP.ENTER_OTP) {
      startTransition(() => {
        setOtp('')
        console.log('REQUEST OTP')
        runOtpRequest(number)
      })
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [step])

  const onChange = (e: ChangeEvent<HTMLInputElement>) => {
    if (e.target.name == AUTH_PAGE_ELEMENT.INPUT_PHONE) {
      setNumber(() => e.target.value)
    } else if (e.target.name == AUTH_PAGE_ELEMENT.INPUT_PASSWORD) {
      setPassword(() => e.target.value)
    } else if (e.target.name == AUTH_PAGE_ELEMENT.INPUT_PASSWORD_REPEAT) {
      setPasswordRepeat(() => e.target.value)
    } else if (e.target.name.startsWith(AUTH_PAGE_ELEMENT.INPUT_OTP)) {
      const index = +e.target.name.split('-')[2]
      const prev = otp.padEnd(6).split('')
      prev[index] = e.target.value
      const next = prev.join('')
      if (otp.length >= 6 && next.trim().length >= otp.length) return
      setOtp(next.trimEnd())
    }
  }

  const onClick = async (
    e:
      | React.MouseEvent<HTMLButtonElement, MouseEvent>
      | React.MouseEvent<HTMLInputElement, MouseEvent>
  ) => {
    e.stopPropagation()
    const target = e.target as HTMLButtonElement

    if (target.id === AUTH_PAGE_ELEMENT.TOGGLE_PASSWORD) {
      setShowPassword(state => !state)
    }
    if (target.id === AUTH_PAGE_ELEMENT.TOGGLE_REPEAT_PASSWORD) {
      setShowPasswordRepeat(state => !state)
    } else if (target.id === AUTH_PAGE_ELEMENT.RESET_PASSWORD) {
      setShowPassword(false)
      setShowPasswordRepeat(false)
      setPassword('')
      setPasswordRepeat('')
      setStep(() => AUTH_STEP.ENTER_OTP)
    } else if (target.id === AUTH_PAGE_ELEMENT.RESEND_OTP) {
      if (!timerRunning) {
        startTransition(async () => {
          try {
            await runOtpRequest(number)
            restart()
          } catch {
            console.error('Could not ask for otp')
          }
        })
      }
    }
  }

  const onSubmit = async (e: FormEvent<HTMLFormElement>) => {
    e.preventDefault()
    startTransition(async () => {
      try {
        /* DEV SECTION */
        /* REMOVE THIS CODE FOR PRODUCTION */
        throw false
        /* END OF DEV SECTION */

        /* SECTION DETAILS */
        /* if number is entered in the /auth page or is available in main auth store this page directly shows the OTP page */
        /* Otherwise it shows the number page */
        if (step == AUTH_STEP.ENTER_NUMBER) {
          const userExists = await runUserExistCheck(number)
          update_temp_store({
            number: number,
            mustLogin: userExists
          })
          if (userExists) {
            setStep(AUTH_STEP.ENTER_RESET_PASSWORD)
          } else {
            // TODO: error user not found
          }
        } else if (step == AUTH_STEP.ENTER_OTP) {
          // if (!await runOtpValidation({ phone: number, otp })) {
          //     setOtp('');
          //     console.error('Wrong otp');
          // }
          stop()
          console.log(await runUserExistCheck(number))
          if (await runUserExistCheck(number)) {
            setStep(AUTH_STEP.ENTER_RESET_PASSWORD)
          } else {
            // TODO: error user not found
          }
        } else if (
          step == AUTH_STEP.ENTER_CREATE_PASSWORD ||
          step == AUTH_STEP.ENTER_CURRENT_PASSWORD
        ) {
          setStep(AUTH_STEP.ENTER_RESET_PASSWORD)
        } else if (step == AUTH_STEP.ENTER_RESET_PASSWORD) {
          update_temp_store({
            password,
            repeatPassword: passwordRepeat
          })
          try {
            await runResetPassword({
              phone: number,
              newPassword: password,
              otp: otp
            })
            console.log('Password changed')
            if (isAuthenticated) {
              router.replace(basePath)
            } else {
              router.replace(`${basePath}/auth`)
            }
          } catch (e) {
            console.error('Could not reset password: ', e)
          }
        }
      } catch (ex) {
        console.error(ex)
        // TODO: Add toast errors

        /* DEV SECTION */
        /* REMOVE THIS CODE FOR PRODUCTION */
        if (step == AUTH_STEP.ENTER_NUMBER) {
          update_temp_store({
            number
          })
          setStep(AUTH_STEP.ENTER_OTP)
        } else if (step === AUTH_STEP.ENTER_OTP) {
          setStep(AUTH_STEP.ENTER_RESET_PASSWORD)
        } else if (
          step == AUTH_STEP.ENTER_CREATE_PASSWORD ||
          step == AUTH_STEP.ENTER_CURRENT_PASSWORD
        ) {
          setStep(AUTH_STEP.ENTER_RESET_PASSWORD)
        } else if (step == AUTH_STEP.ENTER_RESET_PASSWORD) {
          update_temp_store({
            password,
            repeatPassword: passwordRepeat
          })
          try {
            console.log('Password changed')
            if (isAuthenticated) {
              router.replace(basePath)
            } else {
              router.replace(`${basePath}/auth`)
            }
          } catch (e) {
            console.error('Could not reset password: ', e)
          }
        }
        /* END OF DEV SECTION */
      }
    })
  }

  return (
    <AuthFormWrapper isPending={isPending} onSubmit={onSubmit}>
      {step === AUTH_STEP.ENTER_NUMBER && (
        <StepEnterNumber
          pending={isPending}
          onChange={onChange}
          value={number}
        />
      )}

      {step === AUTH_STEP.ENTER_OTP && (
        <StepEnterOtp
          pending={isPending}
          onChange={onChange}
          onClick={onClick}
          phoneNumber={number}
          value={otp}
          timerRunning={timerRunning}
          secondsLeft={secondsLeft}
        />
      )}

      {step === AUTH_STEP.ENTER_RESET_PASSWORD && (
        <StepNewPassword
          isReset
          pending={isPending}
          onChange={onChange}
          onClick={onClick}
          value={password}
          repeatValue={passwordRepeat}
          passwordVisible={showPassword}
          repeatPasswordVisible={showPasswordRepeat}
        />
      )}
    </AuthFormWrapper>
  )
}

export default AuthIndex
