import { useState } from 'react'
import Alert from '@mui/material/Alert'
import Box from '@mui/material/Box'
import Button from '@mui/material/Button'
import Divider from '@mui/material/Divider'
import FormControl from '@mui/material/FormControl'
import InputLabel from '@mui/material/InputLabel'
import MenuItem from '@mui/material/MenuItem'
import Select from '@mui/material/Select'
import Stack from '@mui/material/Stack'
import TextField from '@mui/material/TextField'
import Typography from '@mui/material/Typography'
import { createAvatar } from '@dicebear/core'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { useUnit } from 'effector-react'
import { useForm } from 'react-hook-form'
import { apiClient } from '@/shared/api/client'
import { AVATAR_STYLE_LOADERS, DEFAULT_STYLE_ID, loadAvatarStyle } from '@/shared/lib/avatar-styles'
import { $user, updateProfileFx } from '@/shared/model/auth'
import type { UpdateProfileParams } from '@/shared/model/auth'
import { UserAvatar } from '@/shared/ui/UserAvatar'

function getApiErrorMessage(error: unknown): string | null {
  const e = error as { response?: { data?: { error?: string } } }
  const msg = e?.response?.data?.error
  return msg ? String(msg) : null
}

export function AdminSettingsPage() {
  const user = useUnit($user)
  const qc = useQueryClient()
  const pendingProfile = useUnit(updateProfileFx.pending)

  const {
    data: profile,
    isLoading,
    isError,
  } = useQuery({
    queryKey: ['admin', 'profile'],
    queryFn: async () => {
      const { data } = await apiClient.get<{
        id: string
        email: string
        displayName: string | null
        avatar: string | null
        avatarStyle: string | null
      }>('admin/profile')
      return data
    },
  })

  const profileForm = useForm<{ displayName: string }>({
    defaultValues: { displayName: profile?.displayName ?? '' },
    values: { displayName: profile?.displayName ?? '' },
    mode: 'onChange',
  })

  const [selectedStyle, setSelectedStyle] = useState(user?.avatarStyle || DEFAULT_STYLE_ID)
  const [previewSrc, setPreviewSrc] = useState<string | null>(null)
  const [previewStyle, setPreviewStyle] = useState<string>(DEFAULT_STYLE_ID)

  const hasUnsavedPreview = previewSrc !== null

  const profileSaveMut = useMutation({
    mutationFn: (params: { displayName: string | null; avatar?: string | null; avatarStyle?: string | null }) =>
      apiClient.patch('admin/profile', params),
    onSuccess: (_data, variables) => {
      const p: UpdateProfileParams = { displayName: variables.displayName ?? null }
      if (variables.avatar !== undefined) {
        p.avatar = variables.avatar
        p.avatarStyle = variables.avatarStyle ?? null
      }
      updateProfileFx(p)
      void qc.invalidateQueries({ queryKey: ['admin', 'profile'] })
    },
  })

  const profileErrorMsg = getApiErrorMessage(profileSaveMut.error)

  if (isLoading) return <Typography>Загрузка настроек…</Typography>
  if (isError) return <Alert severity="error">Не удалось загрузить настройки.</Alert>
  if (!user) return <Alert severity="info">Нужно войти.</Alert>

  return (
    <Box>
      <Typography variant="h4" gutterBottom>
        Настройки
      </Typography>
      <Typography color="text.secondary" sx={{ mb: 3 }}>
        Текущая почта: <b>{String(user.email)}</b>
      </Typography>

      {profileErrorMsg && (
        <Alert severity="error" sx={{ mb: 2 }}>
          {profileErrorMsg}
        </Alert>
      )}

      <Stack spacing={3} sx={{ maxWidth: 560 }}>
        <Box>
          <Typography variant="h6" gutterBottom>
            Профиль
          </Typography>
          <Stack spacing={2}>
            <TextField
              label="Имя или ник"
              helperText="До 40 символов"
              slotProps={{ htmlInput: { maxLength: 40 } }}
              {...profileForm.register('displayName')}
            />
            <Button
              variant="contained"
              disabled={pendingProfile || profileSaveMut.isPending}
              onClick={() => {
                const raw = profileForm.getValues('displayName')
                const name = raw.trim()
                profileSaveMut.mutate({ displayName: name.length ? name : null })
              }}
            >
              Сохранить
            </Button>
          </Stack>
        </Box>

        <Divider />

        <Box>
          <Typography variant="h6" gutterBottom>
            Аватар
          </Typography>

          <Stack direction="row" spacing={3} sx={{ alignItems: 'flex-start', mb: 2 }}>
            <Box sx={{ textAlign: 'center' }}>
              <UserAvatar
                userId={String(user.id)}
                avatarUrl={hasUnsavedPreview ? previewSrc : user.avatar}
                avatarStyle={hasUnsavedPreview ? previewStyle : user.avatarStyle}
                size={80}
                sx={{
                  border: 2,
                  borderColor: hasUnsavedPreview ? 'warning.main' : 'primary.main',
                }}
              />
              <Typography variant="caption" color="text.secondary" sx={{ display: 'block', mt: 0.5 }}>
                {hasUnsavedPreview ? 'Предпросмотр' : user.avatar ? 'Сохранён' : 'Авто'}
              </Typography>
            </Box>
            {hasUnsavedPreview && (
              <Box sx={{ textAlign: 'center' }}>
                <UserAvatar
                  userId={String(user.id)}
                  avatarUrl={user.avatar}
                  avatarStyle={user.avatarStyle}
                  size={80}
                  sx={{ border: 2, borderColor: 'divider', opacity: 0.6 }}
                />
                <Typography variant="caption" color="text.secondary" sx={{ display: 'block', mt: 0.5 }}>
                  Текущий
                </Typography>
              </Box>
            )}
          </Stack>

          <Stack direction="row" spacing={1} sx={{ flexWrap: 'wrap', gap: 1, mb: 1 }}>
            <FormControl size="small" sx={{ minWidth: 140 }}>
              <InputLabel>Стиль</InputLabel>
              <Select value={selectedStyle} label="Стиль" onChange={(e) => setSelectedStyle(e.target.value)}>
                {AVATAR_STYLE_LOADERS.map((s) => (
                  <MenuItem key={s.id} value={s.id}>
                    {s.label}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>
            <Button
              variant="outlined"
              onClick={async () => {
                const seed = `${String(user.id)}_${Date.now()}`
                const style = await loadAvatarStyle(selectedStyle)
                const avatar = createAvatar(style, { seed })
                setPreviewSrc(avatar.toDataUri())
                setPreviewStyle(selectedStyle)
              }}
            >
              Сгенерировать
            </Button>
          </Stack>

          {hasUnsavedPreview && (
            <Stack direction="row" spacing={1} sx={{ flexWrap: 'wrap', gap: 1, mb: 1 }}>
              <Button
                variant="contained"
                disabled={pendingProfile || profileSaveMut.isPending}
                onClick={() => {
                  const raw = profileForm.getValues('displayName')
                  const name = raw.trim()
                  profileSaveMut.mutate({
                    displayName: name.length ? name : null,
                    avatar: previewSrc,
                    avatarStyle: previewStyle,
                  })
                  setPreviewSrc(null)
                }}
              >
                Сохранить
              </Button>
              <Button variant="text" onClick={() => setPreviewSrc(null)}>
                Отмена
              </Button>
            </Stack>
          )}
        </Box>
      </Stack>
    </Box>
  )
}
