import Alert from '@mui/material/Alert'
import Box from '@mui/material/Box'
import Button from '@mui/material/Button'
import InputAdornment from '@mui/material/InputAdornment'
import Link from '@mui/material/Link'
import Stack from '@mui/material/Stack'
import TextField from '@mui/material/TextField'
import Typography from '@mui/material/Typography'
import { useMutation } from '@tanstack/react-query'
import { Lock, Mail } from 'lucide-react'
import { useForm } from 'react-hook-form'
import { Link as RouterLink } from 'react-router-dom'
import { apiClient } from '@/shared/api/client'
import { getApiErrorMessage } from '@/shared/lib/get-api-error-message'
import { tokenSet } from '@/shared/model/auth'

type AuthResponse = {
  token: string
  user: {
    id: string
    email: string
    displayName?: string | null
    avatar?: string | null
    avatarStyle?: string | null
  }
}

type FormValues = {
  email: string
  password: string
  passwordConfirm: string
  displayName: string
}

type Props = {
  isRegister: boolean
  onRegisterChange: (v: boolean) => void
  onSuccess: () => void
}

const EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/

export function AuthPasswordForm({ isRegister, onRegisterChange, onSuccess }: Props) {
  const {
    register,
    handleSubmit,
    watch,
    formState: { errors },
  } = useForm<FormValues>({
    defaultValues: { email: '', password: '', passwordConfirm: '', displayName: '' },
    mode: 'onChange',
  })

  const password = watch('password')

  const loginMutation = useMutation({
    mutationFn: async (values: FormValues) => {
      const { data } = await apiClient.post<AuthResponse>('auth/login', {
        email: values.email,
        password: values.password,
      })
      tokenSet(data.token)
    },
    onSuccess,
  })

  const registerMutation = useMutation({
    mutationFn: async (values: FormValues) => {
      const { data } = await apiClient.post<AuthResponse>('auth/register', {
        email: values.email,
        password: values.password,
        displayName: values.displayName || undefined,
      })
      tokenSet(data.token)
    },
    onSuccess,
  })

  const apiError = loginMutation.error || registerMutation.error
  const apiErrorMessage = apiError ? getApiErrorMessage(apiError) : null

  const onSubmit = isRegister
    ? handleSubmit((values) => registerMutation.mutate(values))
    : handleSubmit((values) => loginMutation.mutate(values))

  const isPending = loginMutation.isPending || registerMutation.isPending

  return (
    <Box component="form" onSubmit={onSubmit} noValidate>
      <Stack spacing={2}>
        <Stack direction="row" sx={{ justifyContent: 'center' }} spacing={3}>
          <Button
            variant="text"
            size="small"
            sx={{
              color: !isRegister ? 'primary.main' : 'text.secondary',
              borderBottom: !isRegister ? 2 : 0,
              borderColor: 'primary.main',
              borderRadius: 0,
              pb: 0.5,
              textTransform: 'none',
            }}
            onClick={() => onRegisterChange(false)}
          >
            Вход
          </Button>
          <Button
            variant="text"
            size="small"
            sx={{
              color: isRegister ? 'primary.main' : 'text.secondary',
              borderBottom: isRegister ? 2 : 0,
              borderColor: 'primary.main',
              borderRadius: 0,
              pb: 0.5,
              textTransform: 'none',
            }}
            onClick={() => onRegisterChange(true)}
          >
            Регистрация
          </Button>
        </Stack>

        <TextField
          label="Email"
          {...register('email', {
            required: 'Введите email',
            pattern: {
              value: EMAIL_PATTERN,
              message: 'Некорректный email',
            },
          })}
          fullWidth
          autoComplete="email"
          error={Boolean(errors.email)}
          helperText={errors.email?.message}
          slotProps={{
            input: {
              startAdornment: (
                <InputAdornment position="start">
                  <Mail size={18} />
                </InputAdornment>
              ),
            },
          }}
        />

        {isRegister && (
          <TextField
            label="Имя (необязательно)"
            {...register('displayName')}
            fullWidth
            helperText="Если не указать, будет использована часть email до @"
          />
        )}

        <TextField
          label="Пароль"
          type="password"
          autoComplete={isRegister ? 'new-password' : 'current-password'}
          {...register('password', {
            required: 'Введите пароль',
            minLength: {
              value: 8,
              message: 'Пароль должен быть не менее 8 символов',
            },
          })}
          fullWidth
          error={Boolean(errors.password)}
          helperText={errors.password?.message}
          slotProps={{
            input: {
              startAdornment: (
                <InputAdornment position="start">
                  <Lock size={18} />
                </InputAdornment>
              ),
            },
          }}
        />

        {isRegister && (
          <TextField
            label="Подтверждение пароля"
            type="password"
            autoComplete="new-password"
            {...register('passwordConfirm', {
              required: 'Подтвердите пароль',
              validate: (value) => value === password || 'Пароли не совпадают',
            })}
            fullWidth
            error={Boolean(errors.passwordConfirm)}
            helperText={errors.passwordConfirm?.message}
          />
        )}

        {apiErrorMessage && (
          <Alert
            severity="error"
            variant="outlined"
            onClose={() => {
              loginMutation.reset()
              registerMutation.reset()
            }}
          >
            {apiErrorMessage}
          </Alert>
        )}

        {isRegister ? (
          <Button variant="contained" size="large" type="submit" disabled={isPending}>
            Зарегистрироваться
          </Button>
        ) : (
          <Button variant="contained" size="large" type="submit" disabled={isPending}>
            Войти
          </Button>
        )}

        <Typography variant="caption" color="text.secondary" sx={{ textAlign: 'center' }}>
          Нажимая «{isRegister ? 'Зарегистрироваться' : 'Войти'}», вы принимаете{' '}
          <Link component={RouterLink} to="/terms" underline="hover">
            пользовательское соглашение
          </Link>{' '}
          и{' '}
          <Link component={RouterLink} to="/privacy" underline="hover">
            политику конфиденциальности
          </Link>
          .
        </Typography>
      </Stack>
    </Box>
  )
}
