import { useState } from 'react'
import Alert from '@mui/material/Alert'
import Box from '@mui/material/Box'
import Button from '@mui/material/Button'
import Dialog from '@mui/material/Dialog'
import DialogActions from '@mui/material/DialogActions'
import DialogContent from '@mui/material/DialogContent'
import DialogTitle from '@mui/material/DialogTitle'
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 TableHead from '@mui/material/TableHead'
import TableRow from '@mui/material/TableRow'
import TextField from '@mui/material/TextField'
import Typography from '@mui/material/Typography'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { Controller, useForm } from 'react-hook-form'
import {
  createCategory,
  deleteAdminCategory,
  fetchAdminCategories,
  updateAdminCategory,
} from '@/entities/product/api/product-api'
import type { Category } from '@/entities/product/model/types'
import { getErrorMessage } from '@/shared/lib/get-error-message'
import { invalidateQueryKeys } from '@/shared/lib/invalidate-query-keys'
import { EntityRowActions } from '@/shared/ui/EntityRowActions'

const UNSPECIFIED_CATEGORY_SLUG = 'ne-ukazano'

export function AdminCategoriesPage() {
  const queryClient = useQueryClient()
  const [catOpen, setCatOpen] = useState(false)
  const [categoryEditOpen, setCategoryEditOpen] = useState(false)
  const [editingCategory, setEditingCategory] = useState<Category | null>(null)
  const [categoryDeleteTarget, setCategoryDeleteTarget] = useState<Category | null>(null)

  const categoryForm = useForm<{ name: string; slug: string }>({
    defaultValues: { name: '', slug: '' },
    mode: 'onChange',
  })

  const categoryEditForm = useForm<{ name: string; slug: string; sort: string }>({
    defaultValues: { name: '', slug: '', sort: '0' },
    mode: 'onChange',
  })

  const adminCategoriesQuery = useQuery({
    queryKey: ['admin', 'categories'],
    queryFn: fetchAdminCategories,
  })

  const createCategoryMut = useMutation({
    mutationFn: () => {
      const v = categoryForm.getValues()
      return createCategory({
        name: v.name.trim(),
        slug: v.slug.trim() || undefined,
      })
    },
    onSuccess: () => {
      void invalidateQueryKeys(queryClient, [['categories'], ['admin', 'categories']])
      setCatOpen(false)
      categoryForm.reset({ name: '', slug: '' })
    },
  })

  const updateCategoryMut = useMutation({
    mutationFn: async () => {
      if (!editingCategory) return
      const v = categoryEditForm.getValues()
      const payload: { name: string; slug?: string; sort: number } = {
        name: v.name.trim(),
        sort: Number(v.sort),
      }
      if (!Number.isFinite(payload.sort)) throw new Error('Некорректный порядок sort')
      if (editingCategory.slug !== UNSPECIFIED_CATEGORY_SLUG) {
        payload.slug = v.slug.trim()
      }
      return updateAdminCategory(editingCategory.id, payload)
    },
    onSuccess: () => {
      void invalidateQueryKeys(queryClient, [['categories'], ['admin', 'categories'], ['admin', 'products']])
      setCategoryEditOpen(false)
      setEditingCategory(null)
    },
  })

  const deleteCategoryMut = useMutation({
    mutationFn: (id: string) => deleteAdminCategory(id),
    onSuccess: () => {
      void invalidateQueryKeys(queryClient, [['categories'], ['admin', 'categories'], ['admin', 'products']])
      setCategoryDeleteTarget(null)
    },
  })

  const mutationError = createCategoryMut.error ?? updateCategoryMut.error ?? deleteCategoryMut.error

  const openCategoryEdit = (c: Category) => {
    setEditingCategory(c)
    categoryEditForm.reset({
      name: c.name,
      slug: c.slug,
      sort: String(c.sort),
    })
    setCategoryEditOpen(true)
  }

  return (
    <Box>
      <Typography variant="h4" gutterBottom>
        Управление категориями
      </Typography>

      <Stack direction="row" spacing={2} sx={{ mb: 2 }}>
        <Button variant="contained" onClick={() => setCatOpen(true)}>
          Новая категория
        </Button>
      </Stack>

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

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

      <Table size="small">
        <TableHead>
          <TableRow>
            <TableCell>Название</TableCell>
            <TableCell>Slug</TableCell>
            <TableCell>Порядок</TableCell>
            <TableCell align="right">Действия</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {(adminCategoriesQuery.data ?? []).map((c) => (
            <TableRow key={c.id} hover>
              <TableCell>{c.name}</TableCell>
              <TableCell>{c.slug}</TableCell>
              <TableCell>{c.sort}</TableCell>
              <TableCell align="right">
                <EntityRowActions
                  onEdit={c.slug === UNSPECIFIED_CATEGORY_SLUG ? undefined : () => openCategoryEdit(c)}
                  onDelete={c.slug === UNSPECIFIED_CATEGORY_SLUG ? undefined : () => setCategoryDeleteTarget(c)}
                />
              </TableCell>
            </TableRow>
          ))}
        </TableBody>
      </Table>

      <Dialog open={catOpen} onClose={() => setCatOpen(false)} fullWidth maxWidth="xs">
        <DialogTitle>Новая категория</DialogTitle>
        <DialogContent>
          <Stack spacing={2} sx={{ mt: 1 }}>
            <Controller
              control={categoryForm.control}
              name="name"
              render={({ field }) => <TextField label="Название" fullWidth required {...field} />}
            />
            <Controller
              control={categoryForm.control}
              name="slug"
              render={({ field }) => (
                <TextField
                  label="Slug"
                  fullWidth
                  {...field}
                  helperText="Необязательно — можно сгенерировать из названия на сервере"
                />
              )}
            />
          </Stack>
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setCatOpen(false)}>Отмена</Button>
          <Button
            variant="contained"
            disabled={!categoryForm.watch('name').trim() || createCategoryMut.isPending}
            onClick={() => createCategoryMut.mutate()}
          >
            Создать
          </Button>
        </DialogActions>
      </Dialog>

      <Dialog
        open={categoryEditOpen}
        onClose={() => {
          setCategoryEditOpen(false)
          setEditingCategory(null)
        }}
        fullWidth
        maxWidth="xs"
      >
        <DialogTitle>Редактировать категорию</DialogTitle>
        <DialogContent>
          <Stack spacing={2} sx={{ mt: 1 }}>
            <Controller
              control={categoryEditForm.control}
              name="name"
              render={({ field }) => <TextField label="Название" fullWidth required {...field} />}
            />
            <Controller
              control={categoryEditForm.control}
              name="slug"
              render={({ field }) => (
                <TextField
                  label="Slug"
                  fullWidth
                  {...field}
                  disabled={editingCategory?.slug === UNSPECIFIED_CATEGORY_SLUG}
                  helperText={
                    editingCategory?.slug === UNSPECIFIED_CATEGORY_SLUG
                      ? 'Служебный slug нельзя изменить'
                      : 'Идентификатор в URL'
                  }
                />
              )}
            />
            <Controller
              control={categoryEditForm.control}
              name="sort"
              render={({ field }) => (
                <TextField
                  label="Порядок сортировки"
                  fullWidth
                  type="number"
                  {...field}
                  slotProps={{ htmlInput: { step: 1 } }}
                />
              )}
            />
          </Stack>
        </DialogContent>
        <DialogActions>
          <Button
            onClick={() => {
              setCategoryEditOpen(false)
              setEditingCategory(null)
            }}
          >
            Отмена
          </Button>
          <Button
            variant="contained"
            disabled={!categoryEditForm.watch('name').trim() || updateCategoryMut.isPending || !editingCategory}
            onClick={() => updateCategoryMut.mutate()}
          >
            Сохранить
          </Button>
        </DialogActions>
      </Dialog>

      <Dialog
        open={Boolean(categoryDeleteTarget)}
        onClose={() => setCategoryDeleteTarget(null)}
        maxWidth="xs"
        fullWidth
      >
        <DialogTitle>Удалить категорию?</DialogTitle>
        <DialogContent>
          <Typography variant="body2">
            {categoryDeleteTarget && (
              <>
                Категория «{categoryDeleteTarget.name}» будет удалена. Все товары из неё получат категорию «Не указано».
              </>
            )}
          </Typography>
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setCategoryDeleteTarget(null)}>Отмена</Button>
          <Button
            color="error"
            variant="contained"
            disabled={deleteCategoryMut.isPending}
            onClick={() => {
              if (categoryDeleteTarget) deleteCategoryMut.mutate(categoryDeleteTarget.id)
            }}
          >
            Удалить
          </Button>
        </DialogActions>
      </Dialog>
    </Box>
  )
}
