import { useRef, useState } from 'react'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { Ban, CheckCircle2, Upload, X } from 'lucide-react'
import {
  getAdminUser,
  listAdminTeams,
  updateAdminUser,
  uploadAdminUserAvatar,
  type AdminUserOut,
} from '@/api/admin'
import { ApiError } from '@/api/client'
import { useAuth } from '@/auth/useAuth'
import { Avatar } from '@/components/ui/Avatar'
import { Select } from '@/components/ui/Select'
import { useToast } from '@/components/ui/ToastProvider'

/** Разрешённые типы/лимит размера файла аватара — те же ограничения, что и на ProfilePage/backend. */
const ALLOWED_AVATAR_TYPES = ['image/jpeg', 'image/png', 'image/webp']
const MAX_AVATAR_BYTES = 2 * 1024 * 1024
/** Верхний предел выборки команд для селекта — без отдельной пагинации в этом контексте (как в AdminUsersTab). */
const TEAMS_LIMIT = 200

interface AdminUserProfileDialogProps {
  userId: string
  onClose: () => void
}

/**
 * Карточка профиля пользователя в админке — открывается
 * кликом по имени в таблице «Пользователи» (`AdminUsersTab.tsx`). Те же поля,
 * что и в собственном профиле (`ProfilePage.tsx`) плюс уже существующие
 * админ-действия «роль»/«блокировка» — та же логика прав (собственная учётная
 * запись администратора защищена от самоизменения роли/блокировки).
 */
export function AdminUserProfileDialog({ userId, onClose }: AdminUserProfileDialogProps) {
  const { user: currentUser } = useAuth()
  const toast = useToast()
  const queryClient = useQueryClient()
  const fileInputRef = useRef<HTMLInputElement>(null)
  const [avatarError, setAvatarError] = useState<string | null>(null)
  const [name, setName] = useState<string | null>(null)

  const { data, isLoading } = useQuery({ queryKey: ['admin', 'users', userId], queryFn: () => getAdminUser(userId) })
  const { data: teamsData } = useQuery({
    queryKey: ['admin', 'teams', 'all'],
    queryFn: () => listAdminTeams({ limit: TEAMS_LIMIT, offset: 0 }),
  })
  const teams = teamsData?.items ?? []
  const isSelf = userId === currentUser?.id

  function invalidate() {
    queryClient.invalidateQueries({ queryKey: ['admin', 'users'] })
  }

  const mutation = useMutation({
    mutationFn: (payload: Parameters<typeof updateAdminUser>[1]) => updateAdminUser(userId, payload),
    onSuccess: () => {
      invalidate()
      queryClient.invalidateQueries({ queryKey: ['admin', 'users', userId] })
      toast.show('Изменения сохранены', 'success')
    },
    onError: (err: unknown) => {
      if (err instanceof ApiError && err.status === 409) {
        toast.show('Нельзя изменить собственную учётную запись', 'error')
      } else {
        toast.show('Не удалось сохранить изменения', 'error')
      }
    },
  })

  const avatarMutation = useMutation({
    mutationFn: (file: File) => uploadAdminUserAvatar(userId, file),
    onSuccess: () => {
      invalidate()
      queryClient.invalidateQueries({ queryKey: ['admin', 'users', userId] })
      toast.show('Аватар обновлён', 'success')
    },
    onError: (err: unknown) => {
      if (err instanceof ApiError && err.status === 413) toast.show('Файл слишком большой — максимум 2 МБ', 'error')
      else if (err instanceof ApiError && err.status === 415) toast.show('Недопустимый формат — только JPEG, PNG или WEBP', 'error')
      else toast.show('Не удалось загрузить аватар', 'error')
    },
  })

  function handleFileChange(file: File | null) {
    setAvatarError(null)
    if (!file) return
    if (!ALLOWED_AVATAR_TYPES.includes(file.type)) {
      setAvatarError('Недопустимый формат — только JPEG, PNG или WEBP')
      return
    }
    if (file.size > MAX_AVATAR_BYTES) {
      setAvatarError('Файл слишком большой — максимум 2 МБ')
      return
    }
    avatarMutation.mutate(file)
  }

  function handleRoleChange(target: AdminUserOut, role: 'admin' | 'user') {
    if (role === target.role) return
    mutation.mutate({ role })
  }

  function handleToggleBlock(target: AdminUserOut) {
    mutation.mutate({ is_blocked: !target.is_blocked })
  }

  function handleTeamChange(teamId: string) {
    mutation.mutate({ team_id: teamId === '' ? null : teamId })
  }

  function handleSaveName() {
    if (name === null) return
    mutation.mutate({ name_user: name.trim() })
  }

  const displayName = name ?? data?.name_user ?? ''

  return (
    <div className="modal-overlay" role="dialog" aria-modal="true" aria-labelledby="admin-user-dialog-title" onClick={onClose}>
      <div className="modal-panel" onClick={(e) => e.stopPropagation()}>
        <div className="modal-head">
          <h2 id="admin-user-dialog-title">Профиль пользователя</h2>
          <button type="button" className="modal-close" aria-label="Закрыть" onClick={onClose}>
            <X className="lucide" style={{ width: 16, height: 16 }} aria-hidden="true" />
          </button>
        </div>

        {isLoading || !data ? (
          <p className="field-hint">Загрузка…</p>
        ) : (
          <>
            <div className="profile-avatar-block">
              <Avatar name={data.name_user} avatarUrl={data.avatar_url} size={72} />
              <div className="profile-avatar-actions">
                <button type="button" className="btn btn-secondary" onClick={() => fileInputRef.current?.click()} disabled={avatarMutation.isPending}>
                  <Upload style={{ width: 16, height: 16 }} aria-hidden="true" />
                  {avatarMutation.isPending ? 'Загружаем…' : 'Загрузить фото'}
                </button>
                <input
                  ref={fileInputRef}
                  type="file"
                  accept="image/jpeg,image/png,image/webp"
                  style={{ display: 'none' }}
                  onChange={(e) => {
                    handleFileChange(e.target.files?.[0] ?? null)
                    e.target.value = ''
                  }}
                />
              </div>
              {avatarError && <p className="field-hint" style={{ color: 'var(--color-danger)' }}>{avatarError}</p>}
            </div>

            <div className="field">
              <label htmlFor="admin-user-name">ФИО</label>
              <input id="admin-user-name" type="text" value={displayName} onChange={(e) => setName(e.target.value)} maxLength={255} />
            </div>

            <div className="field">
              <label htmlFor="admin-user-email">Email</label>
              <input id="admin-user-email" type="email" value={data.email} disabled readOnly />
            </div>

            <div className="field">
              <label id="admin-user-team-label" htmlFor="admin-user-team">
                Команда
              </label>
              <Select
                id="admin-user-team"
                aria-labelledby="admin-user-team-label"
                value={data.team_id ?? ''}
                onChange={handleTeamChange}
                disabled={mutation.isPending}
                options={[{ value: '', label: 'Без команды' }, ...teams.map((t) => ({ value: t.id, label: t.name }))]}
              />
            </div>

            <div className="field">
              <label id="admin-user-role-label" htmlFor="admin-user-role">
                Роль
              </label>
              <Select
                id="admin-user-role"
                aria-labelledby="admin-user-role-label"
                value={data.role}
                onChange={(v) => handleRoleChange(data, v as 'admin' | 'user')}
                disabled={isSelf || mutation.isPending}
                options={[
                  { value: 'user', label: 'Пользователь' },
                  { value: 'admin', label: 'Администратор' },
                ]}
              />
            </div>

            <div className="modal-actions">
              <button type="button" className="btn btn-primary" onClick={handleSaveName} disabled={mutation.isPending || !displayName.trim()}>
                Сохранить ФИО
              </button>
              <button
                type="button"
                className="btn btn-secondary"
                disabled={isSelf || mutation.isPending}
                title={isSelf ? 'Нельзя изменить собственную учётную запись' : undefined}
                onClick={() => handleToggleBlock(data)}
              >
                {data.is_blocked ? (
                  <CheckCircle2 style={{ width: 16, height: 16 }} aria-hidden="true" />
                ) : (
                  <Ban style={{ width: 16, height: 16 }} aria-hidden="true" />
                )}
                {data.is_blocked ? 'Разблокировать' : 'Заблокировать'}
              </button>
            </div>
          </>
        )}
      </div>
    </div>
  )
}
