import { useNavigate } from '@/router'
import { Button, InputGroup, Label } from '@blueprintjs/core'
import { css } from '@emotion/css'
import useApolloClient from '@inject/graphql/client/useApolloClient'
import { useLogin } from '@inject/graphql/mutations/Login.generated'
import type { Identity } from '@inject/graphql/queries/Identity.generated'
import { IdentityDocument } from '@inject/graphql/queries/Identity.generated'
import ErrorMessage from '@inject/shared/components/ErrorMessage'
import type { FormEvent } from 'react'
import { useCallback, useState } from 'react'

const fields = css`
  display: flex;
  flex-direction: column;
  gap: 1rem;
`

const label = css`
  margin-bottom: 0 !important;
`

const loginForm = css`
  display: flex;
  flex-direction: column;
  gap: 2rem;
  margin: 0 auto;
  max-width: 30rem;
  padding: 1rem;
  width: 100%;
`

const Login = () => {
  const nav = useNavigate()
  const apollo = useApolloClient()

  const [username, setUsername] = useState('')
  const [password, setPassword] = useState('')
  const [showPassword, setShowPassword] = useState(false)

  const [login, { loading, error }] = useLogin({
    variables: { username, password },

    onCompleted: data => {
      if (data.login?.user) {
        apollo.writeQuery<Identity>({
          query: IdentityDocument,
          data: { whoAmI: data.login?.user },
          overwrite: true,
        })
        nav('/')
      }
    },
  })

  const handleSubmit = useCallback(
    (e: FormEvent<HTMLFormElement>) => {
      e.preventDefault()
      login()
    },
    [login]
  )

  return (
    <div>
      <form onSubmit={handleSubmit} className={loginForm}>
        {error && <ErrorMessage>{error.message}</ErrorMessage>}
        <div className={fields}>
          <Label className={label}>
            Email
            <InputGroup
              value={username}
              onChange={e => setUsername(e.target.value)}
            />
          </Label>
          <Label className={label}>
            Password
            <InputGroup
              type={showPassword ? 'text' : 'password'}
              value={password}
              onChange={e => setPassword(e.target.value)}
              rightElement={
                <Button
                  minimal
                  icon={showPassword ? 'eye-off' : 'eye-open'}
                  onClick={() => setShowPassword(prev => !prev)}
                />
              }
            />
          </Label>
        </div>

        <Button
          icon='log-in'
          type='submit'
          loading={loading}
          disabled={!username || !password}
          title={!username || !password ? 'Fill in both fields' : undefined}
          intent='primary'
        >
          Login
        </Button>
      </form>
    </div>
  )
}

export default Login
