import React, { useEffect } from 'react'
import { Controller, useForm } from 'react-hook-form'
import { IForgotPassword, UserPreferences, UserUpdateValues } from '../../models/user'
import { loadedPreferences, loggedInUser, updateUserPreferences } from '../../stateManagement/userState'
import {
  Button,
  Container, Flex,
  FormControl,
  FormLabel,
  Heading,
  Input,
  Stack, Switch,
  useColorModeValue,
  useToast,
} from '@chakra-ui/react'
import { useHookstate } from '@hookstate/core'
import agent from '../../api/agent'
import { useNavigate } from 'react-router-dom'

export default function EditUser() {
  const userState = useHookstate(loggedInUser)
  const user = userState.get()
  const passwordLoading = useHookstate(false)
  const passwordDisabled = useHookstate(false)
  const preferencesState = useHookstate(loadedPreferences)
  const preferences = preferencesState.get()
  const {
    register,
    control,
    handleSubmit,
    reset,
    setValue,
    formState: { isSubmitting, isDirty },
  } = useForm({
    defaultValues: {
      name: user.name,
      displayName: user.displayName,
      email: user.email,
      theme: preferences.theme === "dark",
      stickyNav: preferences.stickyNav
    },
  })
  const history = useNavigate()

  useEffect(() => {
    reset(user)
    return
  }, [user.name !== ''])

  const toast = useToast()

  interface Message {
    success: boolean
    data: string
  }

  const onSubmit = handleSubmit(async (data) => {
    let theme: "light" | "dark"
    data.theme ? theme = "dark" : theme = "light"
    const newUserData: UserUpdateValues = {...data, role: user.role, avatar: user.avatar}
    const newPreferenceData: UserPreferences = { id: preferences.id, theme, stickyNav: data.stickyNav }
    await agent.Account.update(newUserData)
    await updateUserPreferences(newPreferenceData)
    return history('/edit-user')
  })

  const engageChangePassword = async (values: IForgotPassword) => {
    const message = await agent.Account.forgot(values as IForgotPassword) as Message
    toast({
      title: 'Email Sent',
      status: 'success',
      description: message.data,
      isClosable: true,
      duration: 10000,
      position: 'top'
    })
  }

  useEffect(() => {
      setValue("theme", preferences.theme === "dark")
  }, [setValue, preferences.theme]);

  useEffect(() => {
    setValue("stickyNav", preferences.stickyNav)
  }, [setValue, preferences.stickyNav])

  const bg = useColorModeValue('gray.50', 'transparent')

  return (
    <Container style={{ marginTop: '7rem', paddingBottom: '5rem' }}>
      <Heading as="h1" marginBottom={'3rem'}>Edit {user.displayName}</Heading>
      <form onSubmit={onSubmit}>
        <FormControl>
          <FormLabel htmlFor="name">Full Name</FormLabel>
          <Input
            id="name"
            bg={bg}
            border="1px"
            borderColor="gray.500"
            rounded="md"
            {...register('name', { required: 'Name is required' })}
          />
        </FormControl>
        <FormControl mt={'3'}>
          <FormLabel htmlFor="displayName">Display Name</FormLabel>
          <Input
            id="displayName"
            bg={bg}
            border="1px"
            borderColor="gray.500"
            rounded="md"
            {...register('displayName', { required: 'Display Name is required' })}
          />
        </FormControl>
        <FormControl mt={'3'}>
          <FormLabel htmlFor="email">Email</FormLabel>
          <Input
            id="email"
            bg={bg}
            _placeholder={{ color: 'gray.500' }}
            isDisabled
            border="1px"
            borderColor="gray.500"
            rounded="md"
            placeholder="Email"
            {...register('email', { required: 'Email is required' })}
          />
        </FormControl>
        <FormControl>
        <Flex mt={'6'}>
            <FormLabel htmlFor={"theme"}>Dark Mode:</FormLabel>
            <Controller
                control={control}
                name="theme"
                render={({ field: { onChange, value, ref } }) => (
                    <Switch isChecked={value} onChange={onChange} ref={ref} />
                )}
            />
        </Flex>
        </FormControl>
        <FormControl>
          <Flex mt={'6'}>
            <FormLabel htmlFor={"stickyNav"}>Sticky Navbar:</FormLabel>
            <Controller
                control={control}
                name="stickyNav"
                render={({ field: { onChange, value, ref } }) => (
                    <Switch isChecked={value} onChange={onChange} ref={ref} />
                )}
            />
          </Flex>
        </FormControl>
        <br />
        <Stack spacing={[1, 5]} direction={'row'} align="self-end" pb="3">
          <Button
            type="submit"
            disabled={!isDirty}
            isLoading={isSubmitting}
          >
            Submit
          </Button>
          <Button
            isLoading={passwordLoading.get()}
            isDisabled={passwordDisabled.get()}
            onMouseDown={async () => {
              passwordLoading.set(true)
              passwordDisabled.set(true)
              await engageChangePassword({ email: user.email })
              passwordLoading.set(false)
            }}
          >
            Change Password
          </Button>
        </Stack>
      </form>
    </Container>
  )
}
