import type { ReactNode } from 'react'
import { useCallback, useMemo, useRef } from 'react'
import Box from '@mui/material/Box'
import Card from '@mui/material/Card'
import CardContent from '@mui/material/CardContent'
import CardMedia from '@mui/material/CardMedia'
import Chip from '@mui/material/Chip'
import Stack from '@mui/material/Stack'
import Typography from '@mui/material/Typography'
import { useNavigate } from 'react-router-dom'
import { Swiper, SwiperSlide } from 'swiper/react'
import 'swiper/css'
import type { Product } from '@/entities/product/model/types'
import { formatPriceRub } from '@/shared/lib/format-price'
import { OptimizedImage } from '@/shared/ui/OptimizedImage'
import type { Swiper as SwiperType } from 'swiper/types'

type Props = { product: Product; mediaHeight?: number; actions?: ReactNode }

export function ProductCard({ product, mediaHeight = 200, actions }: Props) {
  const navigate = useNavigate()
  const swiperRef = useRef<SwiperType | null>(null)
  const imageUrls = useMemo(() => {
    const fromImages = (product.images ?? [])
      .slice()
      .sort((a, b) => a.sort - b.sort)
      .map((x) => x.url)
    const urls = fromImages.length ? fromImages : product.imageUrl ? [product.imageUrl] : []
    return urls
  }, [product.images, product.imageUrl])

  const materials = (product.materials ?? []).slice(0, 3)
  const moreMaterials = Math.max(0, (product.materials?.length ?? 0) - materials.length)

  const onMouseMove = (e: React.MouseEvent<HTMLElement>) => {
    if (!swiperRef.current) return
    if (imageUrls.length <= 1) return
    const rect = (e.currentTarget as HTMLElement).getBoundingClientRect()
    const rel = Math.min(1, Math.max(0, (e.clientX - rect.left) / rect.width))
    const idx = Math.min(imageUrls.length - 1, Math.floor(rel * imageUrls.length))
    swiperRef.current.slideTo(idx, 0)
  }

  const goToProduct = useCallback(() => {
    navigate(`/products/${product.id}`)
  }, [navigate, product.id])

  const stockLabel = product.quantity > 0 ? null : { label: 'Нет в наличии', color: 'default' as const }

  return (
    <Card
      onClick={goToProduct}
      sx={{
        cursor: 'pointer',
        height: '100%',
        display: 'flex',
        flexDirection: 'column',
        overflow: 'hidden',
        borderRadius: 3,
        border: '1px solid',
        borderColor: 'divider',
        bgcolor: 'background.paper',
        transition: 'transform 200ms ease, box-shadow 250ms ease',
        '&:hover': {
          transform: 'translateY(-4px)',
          boxShadow: '0 8px 30px rgba(0,0,0,0.10)',
        },
        '&:hover .product-card__media': { transform: 'scale(1.06)' },
        '&:hover .product-card__title': { color: 'primary.main' },
        '@media (prefers-reduced-motion: reduce)': {
          transition: 'none',
          '&:hover': { transform: 'none' },
          '&:hover .product-card__media': { transform: 'none' },
        },
      }}
    >
      <Box sx={{ position: 'relative' }}>
        {imageUrls.length ? (
          <Box onMouseMove={onMouseMove} sx={{ height: mediaHeight, overflow: 'hidden' }}>
            <Swiper
              onSwiper={(s) => {
                swiperRef.current = s
              }}
              allowTouchMove={false}
              style={{ width: '100%', height: mediaHeight }}
            >
              {imageUrls.map((url) => (
                <SwiperSlide key={url}>
                  <Box
                    className="product-card__media"
                    sx={{
                      width: '100%',
                      height: mediaHeight,
                      transition: 'transform 320ms ease',
                      '@media (prefers-reduced-motion: reduce)': { transition: 'none' },
                      userSelect: 'none',
                      bgcolor: 'grey.50',
                    }}
                  >
                    <OptimizedImage
                      src={url}
                      alt={product.title}
                      sizes={`(max-width: 600px) ${mediaHeight}px, (max-width: 1024px) ${Math.round(mediaHeight * 1.5)}px, ${mediaHeight}px`}
                      sx={{
                        width: '100%',
                        height: '100%',
                        objectFit: 'cover',
                      }}
                    />
                  </Box>
                </SwiperSlide>
              ))}
            </Swiper>
          </Box>
        ) : (
          <CardMedia
            component="div"
            sx={{
              height: mediaHeight,
              bgcolor: 'grey.50',
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'center',
            }}
          >
            <Typography color="text.disabled" variant="body2">
              Нет фото
            </Typography>
          </CardMedia>
        )}

        {stockLabel && (
          <Chip
            label={stockLabel.label}
            size="small"
            color={stockLabel.color}
            variant="filled"
            sx={{
              position: 'absolute',
              top: 8,
              left: 8,
              fontWeight: 600,
              fontSize: '0.7rem',
              backdropFilter: 'blur(4px)',
              bgcolor: 'rgba(0,0,0,0.55)',
              color: 'common.white',
            }}
          />
        )}
      </Box>

      <CardContent sx={{ flexGrow: 1, p: 2, '&:last-child': { pb: 2 } }}>
        <Stack spacing={1.25}>
          {product.category && (
            <Chip
              label={product.category.name}
              size="small"
              color="primary"
              sx={{
                alignSelf: 'flex-start',
                fontWeight: 600,
                fontSize: '0.65rem',
                height: 22,
                letterSpacing: 0.3,
                textTransform: 'uppercase',
              }}
            />
          )}

          <Typography
            variant="subtitle1"
            className="product-card__title"
            sx={{
              textDecoration: 'none',
              color: 'text.primary',
              fontWeight: 600,
              lineHeight: 1.3,
              transition: 'color 150ms ease',
            }}
          >
            {product.title}
          </Typography>

          {(product.materials?.length ?? 0) > 0 && (
            <Stack direction="row" spacing={0.5} useFlexGap sx={{ flexWrap: 'wrap' }}>
              {materials.map((m) => (
                <Chip
                  key={m}
                  label={m}
                  size="small"
                  variant="outlined"
                  sx={{
                    bgcolor: 'chip.default',
                    color: 'text.secondary',
                    fontSize: '0.7rem',
                    height: 22,
                    fontWeight: 500,
                  }}
                />
              ))}
              {moreMaterials > 0 && (
                <Chip
                  label={`+${moreMaterials}`}
                  size="small"
                  variant="outlined"
                  sx={{
                    bgcolor: 'chip.default',
                    color: 'text.secondary',
                    fontSize: '0.7rem',
                    height: 22,
                    fontWeight: 500,
                  }}
                />
              )}
            </Stack>
          )}

          <Typography
            variant="body2"
            color="text.secondary"
            sx={{
              overflow: 'hidden',
              textOverflow: 'ellipsis',
              WebkitLineClamp: 2,
              display: '-webkit-box',
              WebkitBoxOrient: 'vertical',
              fontSize: '0.8125rem',
              lineHeight: 1.45,
            }}
          >
            {product.shortDescription ?? 'Описание появится позже.'}
          </Typography>

          <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mt: 'auto', pt: 0.5 }}>
            <Typography variant="h6" color="primary" sx={{ fontWeight: 700, fontSize: '1.1rem' }}>
              {formatPriceRub(product.priceCents)}
            </Typography>
            {actions}
          </Box>
        </Stack>
      </CardContent>
    </Card>
  )
}
