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 Typography from '@mui/material/Typography'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { useForm } from 'react-hook-form'
import {
  createProduct,
  deleteProduct,
  fetchAdminProducts,
  updateProduct,
} from '@/entities/product/api/admin-product-api'
import { fetchCategories } from '@/entities/product/api/product-api'
import type { Product } from '@/entities/product/model/types'
import { emptyForm, type FormState } from '@/features/product-form'
import { GalleryImagePicker } from '@/features/product-form/ui/GalleryImagePicker'
import { ProductFormFields } from '@/features/product-form/ui/ProductFormFields'
import { formatPriceRub } from '@/shared/lib/format-price'
import { getErrorMessage } from '@/shared/lib/get-error-message'
import { invalidateQueryKeys } from '@/shared/lib/invalidate-query-keys'
import { useEditDialogState } from '@/shared/lib/use-edit-dialog-state'
import { EntityRowActions } from '@/shared/ui/EntityRowActions'

export function AdminProductsPage() {
  const queryClient = useQueryClient()
  const { dialogOpen, editing, openCreateDialog, openEditDialog, closeDialog } = useEditDialogState<Product>()
  const [galleryPickOpen, setGalleryPickOpen] = useState(false)

  const productForm = useForm<FormState>({
    defaultValues: emptyForm(),
    mode: 'onChange',
  })

  const titleValue = productForm.watch('title')

  const categoriesQuery = useQuery({
    queryKey: ['categories'],
    queryFn: () => fetchCategories(),
  })

  const productsQuery = useQuery({
    queryKey: ['admin', 'products'],
    queryFn: fetchAdminProducts,
  })

  const openCreate = () => {
    productForm.reset(emptyForm())
    openCreateDialog()
  }

  const openEdit = (p: Product) => {
    openEditDialog(p)
    const urls =
      (p.images ?? [])
        .slice()
        .sort((a, b) => a.sort - b.sort)
        .map((x) => x.url) ?? (p.imageUrl ? [p.imageUrl] : [])
    productForm.reset({
      title: p.title,
      slug: p.slug,
      shortDescription: p.shortDescription ?? '',
      description: p.description ?? '',
      quantity: String(p.quantity),
      materials: (p.materials ?? []).join(', '),
      priceRub: String(p.priceCents / 100),
      imageUrls: urls,
      published: p.published,
      categoryId: p.categoryId,
    })
  }

  const createMut = useMutation({
    mutationFn: async () => {
      const form = productForm.getValues()
      const priceCents = Math.round(Number(form.priceRub.replace(',', '.')) * 100)
      if (!Number.isFinite(priceCents) || priceCents <= 0) throw new Error('Цена должна быть больше 0')
      if (priceCents > 10_000_00) throw new Error('Цена не может превышать 10 000 ₽')
      if (!form.categoryId) throw new Error('Выберите категорию')
      const qty = form.quantity.trim()
      if (!qty) throw new Error('Укажите количество')
      const qtyNum = Number(qty)
      if (!Number.isInteger(qtyNum) || qtyNum < 0 || qtyNum > 10) throw new Error('Количество — целое число от 0 до 10')
      const materials = form.materials
        .split(',')
        .map((x) => x.trim())
        .filter(Boolean)
      await createProduct({
        title: form.title.trim(),
        slug: form.slug.trim() || undefined,
        shortDescription: form.shortDescription.trim() || null,
        description: form.description.trim() || null,
        quantity: Math.floor(qtyNum),
        materials,
        priceCents,
        imageUrls: form.imageUrls,
        published: form.published,
        categoryId: form.categoryId,
      })
    },
    onSuccess: () => {
      void invalidateQueryKeys(queryClient, [['admin', 'products'], ['products']])
      closeDialog()
    },
  })

  const updateMut = useMutation({
    mutationFn: async () => {
      const form = productForm.getValues()
      const priceCents = Math.round(Number(form.priceRub.replace(',', '.')) * 100)
      if (!Number.isFinite(priceCents) || priceCents <= 0) throw new Error('Цена должна быть больше 0')
      if (priceCents > 10_000_00) throw new Error('Цена не может превышать 10 000 ₽')
      if (!form.categoryId) throw new Error('Выберите категорию')
      const qty = form.quantity.trim()
      if (!qty) throw new Error('Укажите количество')
      const qtyNum = Number(qty)
      if (!Number.isInteger(qtyNum) || qtyNum < 0 || qtyNum > 10) throw new Error('Количество — целое число от 0 до 10')
      const materials = form.materials
        .split(',')
        .map((x) => x.trim())
        .filter(Boolean)
      await updateProduct(editing!.id, {
        title: form.title.trim(),
        slug: form.slug.trim(),
        shortDescription: form.shortDescription.trim() || null,
        description: form.description.trim() || null,
        quantity: Math.floor(qtyNum),
        materials,
        priceCents,
        imageUrls: form.imageUrls,
        published: form.published,
        categoryId: form.categoryId,
      })
    },
    onSuccess: () => {
      void invalidateQueryKeys(queryClient, [['admin', 'products'], ['products']])
      closeDialog()
    },
  })

  const deleteMut = useMutation({
    mutationFn: (id: string) => deleteProduct(id),
    onSuccess: () => {
      void invalidateQueryKeys(queryClient, [['admin', 'products'], ['products']])
    },
  })

  const handleSubmit = () => {
    if (editing) updateMut.mutate()
    else createMut.mutate()
  }

  const mutationError = createMut.error ?? updateMut.error ?? deleteMut.error

  const removeImage = (url: string) => {
    const current = productForm.getValues('imageUrls')
    productForm.setValue(
      'imageUrls',
      current.filter((u) => u !== url),
      { shouldDirty: true },
    )
  }

  const handleGallerySelect = (urls: string[]) => {
    const current = productForm.getValues('imageUrls')
    const merged = [...current]
    for (const url of urls) {
      if (!merged.includes(url)) {
        merged.push(url)
      }
    }
    productForm.setValue('imageUrls', merged, { shouldDirty: true })
  }

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

      <Stack direction="row" spacing={2} sx={{ mb: 2 }}>
        <Button variant="contained" onClick={openCreate}>
          Новый товар
        </Button>
      </Stack>

      {productsQuery.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>Категория</TableCell>
            <TableCell>Цена</TableCell>
            <TableCell>Витрина</TableCell>
            <TableCell align="right">Действия</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {(productsQuery.data ?? []).map((p) => (
            <TableRow key={p.id} hover>
              <TableCell>{p.title}</TableCell>
              <TableCell>{p.category?.name ?? '—'}</TableCell>
              <TableCell>{formatPriceRub(p.priceCents)}</TableCell>
              <TableCell>{p.published ? 'да' : 'нет'}</TableCell>
              <TableCell align="right">
                <EntityRowActions onEdit={() => openEdit(p)} onDelete={() => deleteMut.mutate(p.id)} />
              </TableCell>
            </TableRow>
          ))}
        </TableBody>
      </Table>

      <Dialog open={dialogOpen} onClose={closeDialog} fullWidth maxWidth="sm">
        <DialogTitle>{editing ? 'Редактировать товар' : 'Новый товар'}</DialogTitle>
        <DialogContent>
          <ProductFormFields
            form={productForm}
            categories={categoriesQuery.data ?? []}
            onRemoveImage={removeImage}
            onPickFromGallery={() => setGalleryPickOpen(true)}
          />
        </DialogContent>
        <DialogActions>
          <Button onClick={closeDialog}>Отмена</Button>
          <Button
            variant="contained"
            onClick={handleSubmit}
            disabled={
              !titleValue.trim() ||
              !productForm.watch('categoryId') ||
              !productForm.watch('quantity').trim() ||
              !productForm.watch('priceRub').trim() ||
              !productForm.formState.isValid ||
              createMut.isPending ||
              updateMut.isPending
            }
          >
            {editing ? 'Сохранить' : 'Создать'}
          </Button>
        </DialogActions>
      </Dialog>

      <GalleryImagePicker
        open={galleryPickOpen}
        onClose={() => setGalleryPickOpen(false)}
        onSelect={handleGallerySelect}
        currentUrls={productForm.watch('imageUrls')}
      />
    </Box>
  )
}
