import { useState, useEffect, useRef } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { Typography, Button, Tag, Spin, App, Input, Grid } from 'antd';
import { ShoppingCartOutlined, ArrowLeftOutlined, PlayCircleOutlined } from '@ant-design/icons';
import axios from 'axios';
import { useAuthStore } from '@/stores/auth.store';
import { useSettingsStore } from '@/stores/settings.store';
import { useHls } from '@/lib/use-hls';
import type { Product, ProductType } from '@/types/api';

const { Title, Text, Paragraph } = Typography;

export default function ProductDetailPage() {
  const { slug } = useParams<{ slug: string }>();
  const navigate = useNavigate();
  const [product, setProduct] = useState<Product | null>(null);
  const [loading, setLoading] = useState(true);
  const [notFound, setNotFound] = useState(false);
  const [buyerEmail, setBuyerEmail] = useState('');
  const [purchasing, setPurchasing] = useState(false);
  const { user, isAuthenticated } = useAuthStore();
  const { message } = App.useApp();
  const { settings: siteSettings } = useSettingsStore();
  const screens = Grid.useBreakpoint();
  const isMobile = !screens.md;

  // Hero image — defaults to resolvedImageUrl, switchable via gallery strip
  const [heroImage, setHeroImage] = useState<string | null>(null);

  useEffect(() => {
    if (!slug) return;
    setLoading(true);
    axios.get(`/api/payments/products/${slug}`)
      .then(({ data }) => {
        setProduct(data);
        setHeroImage(data.resolvedImageUrl || data.imageUrl || null);
      })
      .catch((err) => {
        if (err.response?.status === 404) {
          setNotFound(true);
        } else {
          message.error('Failed to load product');
        }
      })
      .finally(() => setLoading(false));
  }, [slug]); // eslint-disable-line react-hooks/exhaustive-deps

  useEffect(() => {
    if (product) {
      document.title = `${product.title} | ${siteSettings?.organizationName || 'Shop'}`;
    }
  }, [product, siteSettings?.organizationName]);

  const handlePurchase = async () => {
    if (!product) return;
    const email = isAuthenticated && user ? user.email : buyerEmail;
    if (!email) {
      message.warning('Please enter your email');
      return;
    }

    setPurchasing(true);
    try {
      const { data } = await axios.post('/api/payments/purchase', {
        productId: product.id,
        buyerEmail: email,
        buyerName: user?.name || undefined,
      });
      if (data.url) {
        window.location.href = data.url;
      }
    } catch (err: unknown) {
      const msg = (err as { response?: { data?: { error?: { message?: string } } } })?.response?.data?.error?.message || 'Failed to start checkout';
      message.error(msg);
    } finally {
      setPurchasing(false);
    }
  };

  const typeColors: Record<ProductType, string> = {
    DIGITAL: 'blue',
    EVENT: 'green',
    DONATION: 'purple',
  };

  if (loading) return <Spin size="large" style={{ display: 'block', margin: '80px auto' }} />;

  if (notFound || !product) {
    return (
      <div style={{ textAlign: 'center', padding: '80px 16px' }}>
        <Title level={3}>Product not found</Title>
        <Button onClick={() => navigate('/shop')}>Back to Shop</Button>
      </div>
    );
  }

  const isSoldOut = !!(product.maxPurchases && product.purchaseCount >= product.maxPurchases);
  const hasGallery = product.galleryImages && product.galleryImages.length > 0;
  const hasVideo = !!(product.videoStreamUrl);

  return (
    <div style={{ maxWidth: 900, margin: '0 auto', padding: isMobile ? '16px' : '24px 16px' }}>
      {/* Back link */}
      <Button
        type="link"
        icon={<ArrowLeftOutlined />}
        onClick={() => navigate('/shop')}
        style={{ padding: 0, marginBottom: 16 }}
      >
        Back to Shop
      </Button>

      <div style={{ display: 'flex', flexDirection: isMobile ? 'column' : 'row', gap: 32 }}>
        {/* Left column — media */}
        <div style={{ flex: isMobile ? undefined : '0 0 50%', maxWidth: isMobile ? '100%' : '50%' }}>
          {/* Hero image */}
          {heroImage ? (
            <div
              style={{
                position: 'relative',
                paddingBottom: '66.67%',
                overflow: 'hidden',
                borderRadius: 8,
                background: '#1b2838',
              }}
            >
              <img
                src={heroImage}
                alt={product.title}
                style={{
                  position: 'absolute',
                  top: 0,
                  left: 0,
                  width: '100%',
                  height: '100%',
                  objectFit: 'cover',
                }}
              />
            </div>
          ) : (
            <div
              style={{
                paddingBottom: '66.67%',
                position: 'relative',
                borderRadius: 8,
                background: 'linear-gradient(135deg, #1b2838 0%, #2a3f5f 100%)',
              }}
            >
              <div
                style={{
                  position: 'absolute',
                  top: '50%',
                  left: '50%',
                  transform: 'translate(-50%, -50%)',
                }}
              >
                <ShoppingCartOutlined style={{ fontSize: 56, opacity: 0.2, color: '#fff' }} />
              </div>
            </div>
          )}

          {/* Gallery strip */}
          {hasGallery && (
            <div
              style={{
                display: 'flex',
                gap: 8,
                marginTop: 12,
                overflowX: 'auto',
                paddingBottom: 4,
              }}
            >
              {/* Include the main image as first thumbnail if it's from gallery */}
              {product.photoId && product.thumbnailUrl && (
                <div
                  onClick={() => setHeroImage(product.resolvedImageUrl || product.imageUrl || null)}
                  style={{
                    flex: '0 0 72px',
                    height: 54,
                    borderRadius: 4,
                    overflow: 'hidden',
                    cursor: 'pointer',
                    border: heroImage === (product.resolvedImageUrl || product.imageUrl) ? '2px solid #3498db' : '2px solid transparent',
                  }}
                >
                  <img
                    src={product.thumbnailUrl}
                    alt="Main"
                    style={{ width: '100%', height: '100%', objectFit: 'cover' }}
                  />
                </div>
              )}
              {product.galleryImages!.map((img) => (
                <div
                  key={img.photoId}
                  onClick={() => setHeroImage(img.imageUrl)}
                  style={{
                    flex: '0 0 72px',
                    height: 54,
                    borderRadius: 4,
                    overflow: 'hidden',
                    cursor: 'pointer',
                    border: heroImage === img.imageUrl ? '2px solid #3498db' : '2px solid transparent',
                  }}
                >
                  <img
                    src={img.thumbnailUrl}
                    alt=""
                    style={{ width: '100%', height: '100%', objectFit: 'cover' }}
                  />
                </div>
              ))}
            </div>
          )}

          {/* Video */}
          {hasVideo && product.videoId && (
            <div style={{ marginTop: 16 }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 }}>
                <PlayCircleOutlined />
                <Text strong>Product Video</Text>
              </div>
              <ProductVideoPlayer
                videoId={product.videoId}
                streamUrl={product.videoStreamUrl!}
                poster={product.videoThumbnailUrl || undefined}
              />
            </div>
          )}
        </div>

        {/* Right column — product info + buy */}
        <div style={{ flex: 1 }}>
          <Tag color={typeColors[product.type]} style={{ marginBottom: 12 }}>{product.type}</Tag>
          <Title level={2} style={{ marginTop: 0 }}>{product.title}</Title>

          {product.description && (
            <Paragraph style={{ fontSize: 16, lineHeight: 1.7, opacity: 0.85, whiteSpace: 'pre-wrap' }}>
              {product.description}
            </Paragraph>
          )}

          <div style={{ marginTop: 24, padding: 20, borderRadius: 8, background: 'rgba(255,255,255,0.04)', border: '1px solid rgba(255,255,255,0.08)' }}>
            <Text strong style={{ fontSize: 28 }}>
              ${(product.priceCAD / 100).toFixed(2)} CAD
            </Text>

            {product.maxPurchases && (
              <div style={{ marginTop: 8 }}>
                <Text type="secondary">
                  {product.purchaseCount} / {product.maxPurchases} sold
                </Text>
              </div>
            )}

            {isSoldOut ? (
              <Tag color="red" style={{ marginTop: 16, fontSize: 16, padding: '4px 16px' }}>Sold Out</Tag>
            ) : (
              <div style={{ marginTop: 16 }}>
                {!isAuthenticated && (
                  <Input
                    placeholder="Your email address"
                    value={buyerEmail}
                    onChange={(e) => setBuyerEmail(e.target.value)}
                    style={{ marginBottom: 12 }}
                    size="large"
                  />
                )}
                <Button
                  type="primary"
                  size="large"
                  icon={<ShoppingCartOutlined />}
                  onClick={handlePurchase}
                  loading={purchasing}
                  block
                >
                  {product.type === 'EVENT' ? 'Get Tickets' : product.type === 'DONATION' ? 'Donate' : 'Buy Now'}
                </Button>
              </div>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

// Product video player. Optimistically attempts the public HLS manifest; if
// the video isn't transcoded yet, hls.js fails fast (after 2 retries) and we
// fall back to the MP4 stream. This avoids needing the API to expose
// hlsStatus on the Product serializer for v1.
function ProductVideoPlayer({
  videoId,
  streamUrl,
  poster,
}: {
  videoId: number;
  streamUrl: string;
  poster?: string;
}) {
  const videoRef = useRef<HTMLVideoElement>(null);
  const hlsManifestUrl = `/media/public/${videoId}/hls/master.m3u8`;
  const { error: hlsError } = useHls(videoRef, hlsManifestUrl);
  const useMp4Src = !!hlsError;

  return (
    <video
      ref={videoRef}
      src={useMp4Src ? streamUrl : undefined}
      controls
      preload="metadata"
      poster={poster}
      style={{
        width: '100%',
        borderRadius: 8,
        background: '#000',
        maxHeight: 360,
      }}
    />
  );
}
