import { useEffect, useState } from 'react'
import Alert from '@mui/material/Alert'
import Box from '@mui/material/Box'
import Button from '@mui/material/Button'
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 { useUnit } from 'effector-react'
import { useForm } from 'react-hook-form'
import { useNavigate, useSearchParams } from 'react-router-dom'
import { apiClient } from '@/shared/api/client'
import { $user, tokenSet } from '@/shared/model/auth'

type AuthResponse = { token: string; user: { id: string; email: string; name?: string | null; phone?: string | null } }

function getApiErrorMessage(err: unknown): string | null {
  if (!err || typeof err !== 'object') return null
  const anyErr = err as Record<string, unknown>
  const response = anyErr.response as Record<string, unknown> | undefined
  const data = response?.data as Record<string, unknown> | undefined
  const msg = data?.error
  return typeof msg === 'string' ? msg : null
}

export function AuthPage() {
  const [message, setMessage] = useState<string | null>(null)
  const [oauthError, setOauthError] = useState<string | null>(null)
  const [searchParams, setSearchParams] = useSearchParams()
  const navigate = useNavigate()
  const user = useUnit($user)
  const { register, watch } = useForm<{
    email: string
    code: string
  }>({
    defaultValues: { email: '', code: '' },
    mode: 'onChange',
  })

  const email = watch('email')
  const code = watch('code')
  useEffect(() => {
    if (user) navigate('/', { replace: true })
  }, [navigate, user])

  useEffect(() => {
    const err = searchParams.get('oauthError')
    if (!err) return
    setOauthError(err)
    setSearchParams({}, { replace: true })
  }, [searchParams, setSearchParams])

  const requestCode = useMutation({
    mutationFn: async () => {
      await apiClient.post('auth/request-code', { email })
    },
    onSuccess: () => setMessage('Код отправлен. Проверьте почту (в dev может быть в логах сервера).'),
  })

  const verifyCode = useMutation({
    mutationFn: async () => {
      const { data } = await apiClient.post<AuthResponse>('auth/verify-code', { email, code })
      tokenSet(data.token)
      setMessage(`Вход выполнен: ${data.user.email}`)
      navigate('/', { replace: true })
    },
  })

  const errMsg = getApiErrorMessage(requestCode.error || verifyCode.error)

  return (
    <Box>
      <Typography variant="h4" gutterBottom>
        Вход / регистрация
      </Typography>

      {message && (
        <Alert severity="success" sx={{ mb: 2 }}>
          {message}
        </Alert>
      )}
      {oauthError && (
        <Alert severity="error" sx={{ mb: 2 }} onClose={() => setOauthError(null)}>
          {oauthError}
        </Alert>
      )}
      {errMsg && (
        <Alert severity="error" sx={{ mb: 2 }}>
          {errMsg}
        </Alert>
      )}

      <Stack spacing={2} sx={{ maxWidth: 520 }}>
        <TextField label="Email" {...register('email')} fullWidth />

        <Typography variant="h6">Email + код</Typography>
        <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>
          <Button variant="outlined" onClick={() => requestCode.mutate()} disabled={!email || requestCode.isPending}>
            Отправить код
          </Button>
          <TextField label="Код (6 цифр)" inputMode="numeric" {...register('code')} />
          <Button
            variant="contained"
            onClick={() => verifyCode.mutate()}
            disabled={!email || code.length !== 6 || verifyCode.isPending}
          >
            Войти
          </Button>
        </Stack>
      </Stack>
    </Box>
  )
}
