import { useEffect, useMemo, useState } from 'react'
import Alert from '@mui/material/Alert'
import Box from '@mui/material/Box'
import Button from '@mui/material/Button'
import Collapse from '@mui/material/Collapse'
import Divider from '@mui/material/Divider'
import FormControl from '@mui/material/FormControl'
import Grid from '@mui/material/Grid'
import InputLabel from '@mui/material/InputLabel'
import MenuItem from '@mui/material/MenuItem'
import Pagination from '@mui/material/Pagination'
import Paper from '@mui/material/Paper'
import Select from '@mui/material/Select'
import type { SelectChangeEvent } from '@mui/material/Select'
import Skeleton from '@mui/material/Skeleton'
import Stack from '@mui/material/Stack'
import TextField from '@mui/material/TextField'
import ToggleButton from '@mui/material/ToggleButton'
import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'
import Typography from '@mui/material/Typography'
import { useQuery } from '@tanstack/react-query'
import { useUnit } from 'effector-react'
import { fetchCategories, fetchPublicProducts } from '@/entities/product/api/product-api'
import { ProductCard } from '@/entities/product/ui/ProductCard'
import { ToggleCartIcon } from '@/features/cart/toggle-cart-icon'
import { $user } from '@/shared/model/auth'
import { ReviewsBlock } from '@/widgets/reviews-block'

export function HomePage() {
  const user = useUnit($user)
  const isAdmin = Boolean(user?.isAdmin)
  const [categorySlug, setCategorySlug] = useState<string>('')
  const [availability, setAvailability] = useState<'all' | 'in_stock' | 'made_to_order'>('all')
  const [qInput, setQInput] = useState('')
  const [q, setQ] = useState('')
  const [moreOpen, setMoreOpen] = useState(false)
  const [sort, setSort] = useState<'price_asc' | 'price_desc' | ''>('')
  const [page, setPage] = useState(1)
  const [pageSize, setPageSize] = useState(12)
  const [priceMinRub, setPriceMinRub] = useState('')
  const [priceMaxRub, setPriceMaxRub] = useState('')
  const [cardScale, setCardScale] = useState<70 | 90 | 110 | 130>(90)

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

  useEffect(() => {
    const t = window.setTimeout(() => {
      setQ(qInput.trim())
      setPage(1)
    }, 250)
    return () => window.clearTimeout(t)
  }, [qInput])

  const productsQuery = useQuery({
    queryKey: [
      'products',
      'public',
      {
        categorySlug: categorySlug || 'all',
        availability,
        q,
        sort,
        page,
        pageSize,
        priceMinRub,
        priceMaxRub,
      },
    ],
    queryFn: () => {
      const toCents = (v: string) => {
        const n = Number(String(v).trim().replace(',', '.'))
        return Number.isFinite(n) && n >= 0 ? Math.round(n * 100) : undefined
      }
      return fetchPublicProducts({
        categorySlug: categorySlug || undefined,
        availability: availability === 'all' ? undefined : availability,
        q: q || undefined,
        sort: sort || '',
        page,
        pageSize,
        priceMinCents: toCents(priceMinRub),
        priceMaxCents: toCents(priceMaxRub),
      })
    },
  })

  const handleCategoryChange = (e: SelectChangeEvent<string>) => {
    setCategorySlug(e.target.value)
    setPage(1)
  }

  const handleSortChange = (e: SelectChangeEvent<string>) => {
    const v = e.target.value
    if (v === '' || v === 'price_asc' || v === 'price_desc') {
      setSort(v)
      setPage(1)
    }
  }

  const handlePageSizeChange = (e: SelectChangeEvent<string>) => {
    const n = Number(e.target.value)
    if (Number.isFinite(n) && n > 0) {
      setPageSize(n)
      setPage(1)
    }
  }

  const title = useMemo(
    () =>
      categorySlug ? `Категория: ${categoriesQuery.data?.find((c) => c.slug === categorySlug)?.name ?? ''}` : 'Каталог',
    [categorySlug, categoriesQuery.data],
  )

  const products = productsQuery.data?.items ?? []
  const total = productsQuery.data?.total ?? 0
  const totalPages = Math.max(1, Math.ceil(total / pageSize))
  const mediaHeight = Math.round(200 * (cardScale / 100))

  return (
    <Box>
      <Typography variant="h4" component="h1" gutterBottom>
        {title}
      </Typography>
      <Typography variant="body1" color="text.secondary" sx={{ mb: 3 }}>
        Игрушки, сувениры и другие изделия ручной работы.
      </Typography>

      <Stack spacing={2} sx={{ mb: 3 }}>
        <Stack
          direction={{ xs: 'column', md: 'row' }}
          spacing={2}
          sx={{ alignItems: { md: 'center' }, flexWrap: { md: 'wrap' } }}
        >
          <FormControl sx={{ minWidth: 220 }} size="small">
            <InputLabel id="category-filter-label">Категория</InputLabel>
            <Select<string>
              labelId="category-filter-label"
              label="Категория"
              value={categorySlug}
              onChange={handleCategoryChange}
              disabled={categoriesQuery.isLoading}
            >
              <MenuItem value="">
                <em>Все</em>
              </MenuItem>
              {(categoriesQuery.data ?? []).map((c) => (
                <MenuItem key={c.id} value={c.slug}>
                  {c.name}
                </MenuItem>
              ))}
            </Select>
          </FormControl>

          <TextField
            size="small"
            label="Поиск"
            value={qInput}
            onChange={(e) => setQInput(e.target.value)}
            sx={{ flexGrow: 1, minWidth: { xs: '100%', md: 360 } }}
          />
        </Stack>

        <Paper
          variant="outlined"
          sx={{
            p: 1.5,
            borderRadius: 2,
            bgcolor: 'background.paper',
            display: 'flex',
            flexDirection: { xs: 'column', sm: 'row' },
            gap: 1.5,
            alignItems: { sm: 'center' },
            justifyContent: 'space-between',
          }}
        >
          <Box>
            <Typography variant="subtitle2">Наличие</Typography>
            <Typography variant="caption" color="text.secondary">
              Быстрый фильтр по наличию
            </Typography>
          </Box>

          <ToggleButtonGroup
            exclusive
            size="small"
            value={availability}
            onChange={(_, v) => {
              if (v === 'all' || v === 'in_stock' || v === 'made_to_order') {
                setAvailability(v)
                setPage(1)
              }
            }}
            sx={{
              alignSelf: { xs: 'flex-start', sm: 'auto' },
              '& .MuiToggleButton-root': { px: 2, fontWeight: 700, letterSpacing: 0.2, textTransform: 'none' },
              '& .MuiToggleButton-root.Mui-selected': {
                bgcolor: 'primary.main',
                color: 'primary.contrastText',
                '&:hover': { bgcolor: 'primary.dark' },
              },
            }}
          >
            <ToggleButton value="all">Все</ToggleButton>
            <ToggleButton value="in_stock">В наличии</ToggleButton>
            <ToggleButton value="made_to_order">Под заказ</ToggleButton>
          </ToggleButtonGroup>
        </Paper>

        <Stack
          direction={{ xs: 'column', sm: 'row' }}
          spacing={1.5}
          sx={{ alignItems: { sm: 'center' }, justifyContent: 'space-between', flexWrap: 'wrap' }}
        >
          <Button variant="text" onClick={() => setMoreOpen((v) => !v)} sx={{ alignSelf: { xs: 'flex-start' } }}>
            {moreOpen ? 'Скрыть фильтры' : 'Фильтры и сортировка'}
          </Button>
          <Button
            variant="outlined"
            onClick={() => {
              setCategorySlug('')
              setAvailability('all')
              setQInput('')
              setSort('')
              setPriceMinRub('')
              setPriceMaxRub('')
              setPageSize(12)
              setCardScale(90)
              setMoreOpen(false)
            }}
            sx={{ alignSelf: { xs: 'flex-start' } }}
          >
            Сбросить
          </Button>
        </Stack>

        <Collapse in={moreOpen} unmountOnExit>
          <Stack
            direction={{ xs: 'column', md: 'row' }}
            spacing={2}
            sx={{ mt: 2, alignItems: { md: 'center' }, flexWrap: { md: 'wrap' } }}
          >
            <FormControl sx={{ minWidth: 220 }} size="small">
              <InputLabel id="sort-label">Сортировка</InputLabel>
              <Select<string> labelId="sort-label" label="Сортировка" value={sort} onChange={handleSortChange}>
                <MenuItem value="">
                  <em>Сначала новые</em>
                </MenuItem>
                <MenuItem value="price_asc">Цена: по возрастанию</MenuItem>
                <MenuItem value="price_desc">Цена: по убыванию</MenuItem>
              </Select>
            </FormControl>

            <TextField
              size="small"
              label="Цена от, ₽"
              value={priceMinRub}
              onChange={(e) => {
                setPriceMinRub(e.target.value)
                setPage(1)
              }}
              sx={{ width: { xs: '100%', md: 180 } }}
            />
            <TextField
              size="small"
              label="Цена до, ₽"
              value={priceMaxRub}
              onChange={(e) => {
                setPriceMaxRub(e.target.value)
                setPage(1)
              }}
              sx={{ width: { xs: '100%', md: 180 } }}
            />

            <FormControl sx={{ minWidth: 220 }} size="small">
              <InputLabel id="page-size-label">На странице</InputLabel>
              <Select<string>
                labelId="page-size-label"
                label="На странице"
                value={String(pageSize)}
                onChange={handlePageSizeChange}
              >
                {[6, 12, 18, 24].map((n) => (
                  <MenuItem key={n} value={String(n)}>
                    {n}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>
          </Stack>

          <Divider sx={{ my: 2 }} />

          <Paper
            variant="outlined"
            sx={{
              p: 1.5,
              borderRadius: 2,
              bgcolor: 'background.paper',
              display: 'flex',
              flexDirection: { xs: 'column', sm: 'row' },
              gap: 1.5,
              alignItems: { sm: 'center' },
              justifyContent: 'space-between',
            }}
          >
            <Box>
              <Typography variant="subtitle2">Масштаб карточек</Typography>
              <Typography variant="caption" color="text.secondary">
                Выберите размер карточек в каталоге
              </Typography>
            </Box>

            <ToggleButtonGroup
              exclusive
              size="small"
              value={cardScale}
              onChange={(_, v) => {
                if (v === 70 || v === 90 || v === 110 || v === 130) setCardScale(v)
              }}
              sx={{
                alignSelf: { xs: 'flex-start', sm: 'auto' },
                '& .MuiToggleButton-root': {
                  px: 2,
                  fontWeight: 700,
                  letterSpacing: 0.2,
                  textTransform: 'none',
                },
                '& .MuiToggleButton-root.Mui-selected': {
                  bgcolor: 'primary.main',
                  color: 'primary.contrastText',
                  '&:hover': { bgcolor: 'primary.dark' },
                },
              }}
            >
              <ToggleButton value={70}>S</ToggleButton>
              <ToggleButton value={90}>M</ToggleButton>
              <ToggleButton value={110}>L</ToggleButton>
              <ToggleButton value={130}>XL</ToggleButton>
            </ToggleButtonGroup>
          </Paper>
        </Collapse>
      </Stack>

      {productsQuery.isLoading && (
        <Grid container spacing={2}>
          {[1, 2, 3].map((i) => (
            <Grid size={{ xs: 12, sm: 6, md: 4 }} key={i}>
              <Skeleton variant="rectangular" height={360} />
            </Grid>
          ))}
        </Grid>
      )}

      {productsQuery.isError && (
        <Alert severity="error">Не удалось загрузить товары. Проверьте, что API запущен.</Alert>
      )}

      {productsQuery.isSuccess && products.length === 0 && (
        <Typography color="text.secondary">Пока нет опубликованных товаров.</Typography>
      )}

      {productsQuery.isSuccess && products.length > 0 && (
        <>
          <Grid container spacing={2}>
            {products.map((p) => (
              <Grid size={{ xs: 12, sm: 6, md: 4 }} key={p.id}>
                <ProductCard
                  product={p}
                  mediaHeight={mediaHeight}
                  actions={
                    !isAdmin ? (
                      <ToggleCartIcon
                        productId={p.id}
                        disabledReason={p.inStock && p.quantity === 0 ? 'Нет в наличии' : null}
                      />
                    ) : undefined
                  }
                />
              </Grid>
            ))}
          </Grid>

          {totalPages > 1 && (
            <Stack direction="row" sx={{ mt: 3, justifyContent: 'center' }}>
              <Pagination
                page={page}
                count={totalPages}
                onChange={(_, v) => setPage(v)}
                color="primary"
                shape="rounded"
                showFirstButton
                showLastButton
              />
            </Stack>
          )}

          <Box sx={{ mt: 4 }}>
            <ReviewsBlock />
          </Box>
        </>
      )}
    </Box>
  )
}
