import { useRef, useState } from 'react'
import Box from '@mui/material/Box'
import Button from '@mui/material/Button'
import Chip from '@mui/material/Chip'
import Stack from '@mui/material/Stack'
import Table from '@mui/material/Table'
import TableBody from '@mui/material/TableBody'
import TableCell from '@mui/material/TableCell'
import TableContainer from '@mui/material/TableContainer'
import TableHead from '@mui/material/TableHead'
import TableRow from '@mui/material/TableRow'
import ToggleButton from '@mui/material/ToggleButton'
import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'
import Typography from '@mui/material/Typography'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import {
  deleteGalleryImage,
  fetchAdminGallery,
  GalleryGrid,
  resizeGalleryImage,
  uploadGalleryImages,
} from '@/entities/gallery'
import type { GalleryImageItem } from '@/entities/gallery'
import { formatAdminImageMaxSizeHint } from '@/shared/constants/upload-limits'
import { invalidateQueryKeys } from '@/shared/lib/invalidate-query-keys'
import type { AxiosError } from 'axios'
import { Grid3x3, List } from 'lucide-react'

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

function formatDate(iso: string): string {
  try {
    return new Date(iso).toLocaleDateString('ru-RU', { day: '2-digit', month: '2-digit', year: 'numeric' })
  } catch {
    return ''
  }
}

function fileNameFromUrl(url: string): string {
  const parts = url.split('/')
  return parts[parts.length - 1] || url
}

function GalleryTable({
  items,
  deleting,
  resizing,
  onDelete,
  onResize,
}: {
  items: GalleryImageItem[]
  deleting: boolean
  resizing: string | null
  onDelete: (id: string) => void
  onResize: (id: string) => void
}) {
  return (
    <TableContainer>
      <Table size="small">
        <TableHead>
          <TableRow>
            <TableCell>Миниатюра</TableCell>
            <TableCell>Имя файла</TableCell>
            <TableCell>Статус</TableCell>
            <TableCell>Дата</TableCell>
            <TableCell>Действия</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {items.map((item) => (
            <TableRow key={item.id}>
              <TableCell>
                <Box
                  component="img"
                  src={item.url}
                  alt=""
                  sx={{ width: 48, height: 48, objectFit: 'cover', borderRadius: 1, display: 'block' }}
                />
              </TableCell>
              <TableCell sx={{ maxWidth: 200, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                {fileNameFromUrl(item.url)}
              </TableCell>
              <TableCell>
                <Chip
                  label={item.isResized ? 'Готово' : 'Не обработано'}
                  size="small"
                  color={item.isResized ? 'success' : 'warning'}
                />
              </TableCell>
              <TableCell>{formatDate(item.createdAt)}</TableCell>
              <TableCell>
                <Stack direction="row" spacing={0.5}>
                  {!item.isResized && (
                    <Button
                      size="small"
                      variant="outlined"
                      disabled={resizing === item.id}
                      onClick={() => onResize(item.id)}
                    >
                      Resize
                    </Button>
                  )}
                  <Button
                    size="small"
                    variant="outlined"
                    color="error"
                    disabled={deleting}
                    onClick={() => onDelete(item.id)}
                  >
                    Удалить
                  </Button>
                </Stack>
              </TableCell>
            </TableRow>
          ))}
        </TableBody>
      </Table>
    </TableContainer>
  )
}

export function AdminGalleryPage() {
  const queryClient = useQueryClient()
  const fileInputRef = useRef<HTMLInputElement>(null)
  const [resizingId, setResizingId] = useState<string | null>(null)
  const [viewMode, setViewMode] = useState<'grid' | 'table'>('grid')

  const galleryQuery = useQuery({
    queryKey: ['admin', 'gallery'],
    queryFn: fetchAdminGallery,
  })

  const uploadMut = useMutation({
    mutationFn: (files: File[]) => uploadGalleryImages(files),
    onSuccess: () => {
      void invalidateQueryKeys(queryClient, [['admin', 'gallery']])
      if (fileInputRef.current) {
        fileInputRef.current.value = ''
      }
    },
  })

  const deleteMut = useMutation({
    mutationFn: (id: string) => deleteGalleryImage(id),
    onSuccess: () => {
      void invalidateQueryKeys(queryClient, [['admin', 'gallery'], ['admin', 'catalog-slider'], ['catalog-slider']])
    },
  })

  const resizeMut = useMutation({
    mutationFn: async (id: string) => {
      setResizingId(id)
      try {
        return await resizeGalleryImage(id)
      } finally {
        setResizingId(null)
      }
    },
    onSuccess: () => {
      void invalidateQueryKeys(queryClient, [['admin', 'gallery'], ['admin', 'catalog-slider'], ['catalog-slider']])
    },
  })

  const items = galleryQuery.data?.items ?? []

  return (
    <Box>
      <Typography variant="h4" gutterBottom>
        Галерея
      </Typography>
      <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
        Изображения загружаются без обработки. После загрузки нажмите «Resize» для подготовки к публикации. Обработанные
        изображения доступны для добавления в карточку товара и слайдер.
      </Typography>

      <Typography variant="body2" color="text.secondary" sx={{ mb: 1 }}>
        Форматы: PNG, JPEG, WebP. На один файл — до {formatAdminImageMaxSizeHint()}.
      </Typography>

      <Stack direction="row" spacing={2} sx={{ mb: 3, alignItems: 'center', flexWrap: 'wrap' }}>
        <Button variant="contained" component="label" disabled={uploadMut.isPending}>
          Загрузить файлы
          <input
            ref={fileInputRef}
            hidden
            type="file"
            accept="image/png,image/jpeg,image/webp"
            multiple
            onChange={(e) => {
              const files = e.target.files
              if (!files?.length) return
              uploadMut.mutate(Array.from(files))
            }}
          />
        </Button>
        <ToggleButtonGroup
          value={viewMode}
          exclusive
          onChange={(_, v) => v && setViewMode(v)}
          size="small"
        >
          <ToggleButton value="grid" aria-label="Сетка">
            <Grid3x3 size={16} />
          </ToggleButton>
          <ToggleButton value="table" aria-label="Таблица">
            <List size={16} />
          </ToggleButton>
        </ToggleButtonGroup>
        {uploadMut.isPending && <Typography color="text.secondary">Загрузка…</Typography>}
        {uploadMut.isError && (
          <Typography color="error">
            {uploadMut.error instanceof Error ? uploadMut.error.message : 'Ошибка загрузки'}
          </Typography>
        )}
        {deleteMut.isError && (
          <Typography color="error">{getApiErrorMessage(deleteMut.error) ?? 'Ошибка удаления'}</Typography>
        )}
        {resizeMut.isError && (
          <Typography color="error">{getApiErrorMessage(resizeMut.error) ?? 'Ошибка обработки'}</Typography>
        )}
      </Stack>

      {galleryQuery.isError && (
        <Typography color="error" sx={{ mb: 2 }}>
          Не удалось загрузить список.
        </Typography>
      )}

      {viewMode === 'grid' ? (
        <GalleryGrid
          items={items}
          deleting={deleteMut.isPending}
          resizing={resizingId}
          onDelete={(id) => deleteMut.mutate(id)}
          onResize={(id) => resizeMut.mutate(id)}
        />
      ) : (
        <GalleryTable
          items={items}
          deleting={deleteMut.isPending}
          resizing={resizingId}
          onDelete={(id) => deleteMut.mutate(id)}
          onResize={(id) => resizeMut.mutate(id)}
        />
      )}

      {!galleryQuery.isLoading && items.length === 0 && (
        <Typography color="text.secondary">Пока нет загруженных изображений.</Typography>
      )}
    </Box>
  )
}
