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 FormControlLabel from '@mui/material/FormControlLabel'
import Stack from '@mui/material/Stack'
import Switch from '@mui/material/Switch'
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 {
  createInfoBlock,
  deleteInfoBlock,
  fetchAdminInfoBlocks,
  type InfoPageBlock,
  updateInfoBlock,
} from '@/entities/info'
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'

type FormState = {
  key: string
  title: string
  body: string
  sort: string
  published: boolean
}

const emptyForm = (): FormState => ({ key: '', title: '', body: '', sort: '0', published: true })

export function AdminInfoPage() {
  const qc = useQueryClient()
  const { dialogOpen, editing, openCreateDialog, openEditDialog, closeDialog } = useEditDialogState<InfoPageBlock>()
  const form = useForm<FormState>({ defaultValues: emptyForm(), mode: 'onChange' })

  const blocksQuery = useQuery({
    queryKey: ['admin', 'info-page', 'blocks'],
    queryFn: fetchAdminInfoBlocks,
  })

  const saveMut = useMutation({
    mutationFn: async () => {
      const values = form.getValues()
      const payload = {
        key: values.key.trim(),
        title: values.title.trim(),
        body: values.body.trim(),
        sort: Number(values.sort || 0),
        published: values.published,
      }
      if (editing) return updateInfoBlock(editing.id, payload)
      return createInfoBlock(payload)
    },
    onSuccess: async () => {
      closeDialog()
      form.reset(emptyForm())
      await invalidateQueryKeys(qc, [
        ['admin', 'info-page', 'blocks'],
        ['info-page', 'public', 'blocks'],
      ])
    },
  })

  const deleteMut = useMutation({
    mutationFn: (id: string) => deleteInfoBlock(id),
    onSuccess: async () => {
      await invalidateQueryKeys(qc, [
        ['admin', 'info-page', 'blocks'],
        ['info-page', 'public', 'blocks'],
      ])
    },
  })

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

  const openEdit = (item: InfoPageBlock) => {
    openEditDialog(item)
    form.reset({
      key: item.key,
      title: item.title,
      body: item.body,
      sort: String(item.sort),
      published: item.published,
    })
  }

  const items = blocksQuery.data?.items ?? []
  const err = saveMut.error ?? deleteMut.error

  return (
    <Box>
      <Stack direction="row" sx={{ mb: 2, alignItems: 'center', justifyContent: 'space-between' }}>
        <Typography variant="h4">Информационная страница</Typography>
        <Button variant="contained" onClick={openCreate}>
          Новый блок
        </Button>
      </Stack>

      <Typography color="text.secondary" sx={{ mb: 2 }}>
        Управление блоками страницы с процессом покупки, оплаты и доставки.
      </Typography>

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

      <Table size="small">
        <TableHead>
          <TableRow>
            <TableCell>Key</TableCell>
            <TableCell>Заголовок</TableCell>
            <TableCell>Порядок</TableCell>
            <TableCell>Опубликован</TableCell>
            <TableCell align="right">Действия</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {items.map((item) => (
            <TableRow key={item.id} hover>
              <TableCell>{item.key}</TableCell>
              <TableCell>{item.title}</TableCell>
              <TableCell>{item.sort}</TableCell>
              <TableCell>{item.published ? 'Да' : 'Нет'}</TableCell>
              <TableCell align="right">
                <EntityRowActions
                  onEdit={() => openEdit(item)}
                  onDelete={() => deleteMut.mutate(item.id)}
                  deleteDisabled={deleteMut.isPending}
                />
              </TableCell>
            </TableRow>
          ))}
          {items.length === 0 && !blocksQuery.isLoading && (
            <TableRow>
              <TableCell colSpan={5} sx={{ color: 'text.secondary' }}>
                Блоков пока нет.
              </TableCell>
            </TableRow>
          )}
        </TableBody>
      </Table>

      <Dialog open={dialogOpen} onClose={closeDialog} fullWidth maxWidth="md">
        <DialogTitle>{editing ? 'Редактировать блок' : 'Новый блок'}</DialogTitle>
        <DialogContent>
          <Stack spacing={2} sx={{ mt: 1 }}>
            <Controller
              control={form.control}
              name="key"
              render={({ field }) => <TextField label="Key (латиница, цифры, _-)" fullWidth required {...field} />}
            />
            <Controller
              control={form.control}
              name="title"
              render={({ field }) => <TextField label="Заголовок" fullWidth required {...field} />}
            />
            <Controller
              control={form.control}
              name="body"
              render={({ field }) => (
                <TextField label="Содержимое" fullWidth multiline minRows={5} required {...field} />
              )}
            />
            <Controller
              control={form.control}
              name="sort"
              render={({ field }) => <TextField label="Порядок сортировки" fullWidth {...field} />}
            />
            <Controller
              control={form.control}
              name="published"
              render={({ field }) => (
                <FormControlLabel
                  control={<Switch checked={field.value} onChange={(_, v) => field.onChange(v)} />}
                  label="Показывать на публичной странице"
                />
              )}
            />
          </Stack>
        </DialogContent>
        <DialogActions>
          <Button onClick={closeDialog}>Отмена</Button>
          <Button
            variant="contained"
            onClick={() => saveMut.mutate()}
            disabled={
              saveMut.isPending ||
              !form.watch('key').trim() ||
              !form.watch('title').trim() ||
              !form.watch('body').trim()
            }
          >
            {editing ? 'Сохранить' : 'Создать'}
          </Button>
        </DialogActions>
      </Dialog>
    </Box>
  )
}
