import { useState, useEffect, useRef } from 'react';
import {
  Spin,
  Empty,
  Pagination,
  Grid,
} from 'antd';
import axios from 'axios';
import PublicVideoCard from '@/components/media/PublicVideoCard';
import PublicPhotoCard from '@/components/media/PublicPhotoCard';
import PublicAlbumCard from '@/components/media/PublicAlbumCard';
import ExpandedVideoCard from '@/components/media/ExpandedVideoCard';
import ExpandedPhotoCard from '@/components/media/ExpandedPhotoCard';
import ExpandedAlbumCard from '@/components/media/ExpandedAlbumCard';
import GalleryAdCard from '@/components/media/GalleryAdCard';
import FeaturedPlaylistCarousel from '@/components/media/FeaturedPlaylistCarousel';
import { mediaPublicApi } from '@/lib/media-public-api';
import { useParams, useSearchParams } from 'react-router-dom';
import { ExpandedVideoProvider, useExpandedVideo } from '@/contexts/ExpandedVideoContext';
import { mergeAdsIntoGrid, mergeAdsIntoMediaGrid, type GridItem } from '@/utils/galleryAdMerge';
import type { GalleryAd } from '@/types/gallery-ads';
import type { PublicPhoto, PublicAlbum } from '@/types/media';

const { useBreakpoint } = Grid;

interface Video {
  id: number;
  filename: string;
  title: string | null;
  category: string | null;
  durationSeconds: number | null;
  quality: string | null;
  orientation: string | null;
  thumbnailPath: string | null;
  viewCount: number;
  upvoteCount: number;
  commentCount: number;
  isLocked: boolean;
  createdAt: string;
}

interface PaginationInfo {
  total: number;
  limit: number;
  offset: number;
  hasMore: boolean;
}

// Unified gallery item from /public/gallery endpoint
interface GalleryApiItem {
  type: 'video' | 'photo' | 'album';
  data: any;
}

function MediaGalleryContent() {
  const screens = useBreakpoint();
  const isMobile = !screens.md;
  const { category: urlCategory } = useParams<{ category?: string }>();
  const [searchParams] = useSearchParams();
  const { state: expandedState, expandVideo, expandMedia } = useExpandedVideo();

  const search = searchParams.get('search') || '';
  const sort = (searchParams.get('sort') as 'recent' | 'popular' | 'most_viewed') || 'recent';

  // Determine if we're in photos mode
  const isPhotosMode = urlCategory === 'photos';

  // Video-only state (existing behavior)
  const [videos, setVideos] = useState<Video[]>([]);

  // Unified gallery state (photos mode or all mode)
  const [galleryItems, setGalleryItems] = useState<GalleryApiItem[]>([]);

  const [ads, setAds] = useState<GalleryAd[]>([]);
  const [loading, setLoading] = useState(true);
  const [pagination, setPagination] = useState<PaginationInfo>({
    total: 0,
    limit: 24,
    offset: 0,
    hasMore: false,
  });
  const [currentPage, setCurrentPage] = useState(1);

  // Fetch content based on mode
  const fetchContent = async () => {
    try {
      setLoading(true);
      const offset = (currentPage - 1) * pagination.limit;

      if (isPhotosMode) {
        // Fetch from unified gallery endpoint with photo filter
        const params: any = {
          limit: pagination.limit,
          offset,
          sort,
          mediaType: 'photo',
        };
        if (search) params.search = search;

        const response = await mediaPublicApi.get('/public/gallery', { params });
        setGalleryItems(response.data.items || []);
        setPagination(response.data.pagination);
        setVideos([]);
      } else {
        // Existing video-only fetch
        const params: any = {
          limit: pagination.limit,
          offset,
          sort,
        };
        if (urlCategory) params.category = urlCategory;
        if (search) params.search = search;

        const response = await mediaPublicApi.get('/public', { params });
        setVideos(response.data.videos);
        setPagination(response.data.pagination);
        setGalleryItems([]);
      }
    } catch (error) {
      console.error('Failed to fetch content:', error);
    } finally {
      setLoading(false);
    }
  };

  // Fetch ads
  const fetchAds = async () => {
    try {
      const { data } = await axios.get<GalleryAd[]>('/api/gallery-ads', {
        params: { page: currentPage, placement: 'gallery' },
      });
      setAds(data);
    } catch {
      // Silent fail
    }
  };

  useEffect(() => {
    setCurrentPage(1);
  }, [search, sort, urlCategory]);

  useEffect(() => {
    fetchContent();
    fetchAds();
  }, [urlCategory, search, sort, currentPage]);

  // Handle URL ?expanded=photo-123 or ?expanded=album-5 or ?expanded=123 on initial load
  const hasRestoredRef = useRef(false);
  useEffect(() => {
    if (hasRestoredRef.current) return;
    const expandedParam = searchParams.get('expanded');
    if (!expandedParam) return;

    if (isPhotosMode && galleryItems.length > 0) {
      // Parse expanded param: "photo-123", "album-5"
      const match = expandedParam.match(/^(photo|album)-(\d+)$/);
      if (match) {
        const mediaType = match[1]! as 'photo' | 'album';
        const id = parseInt(match[2]!, 10);
        const item = galleryItems.find(gi => gi.type === mediaType && gi.data.id === id);
        if (item) {
          hasRestoredRef.current = true;
          expandMedia(id, mediaType, item.data);
        }
      }
    } else if (!isPhotosMode && videos.length > 0) {
      const videoId = parseInt(expandedParam, 10);
      if (!isNaN(videoId)) {
        const video = videos.find(v => v.id === videoId);
        if (video) {
          hasRestoredRef.current = true;
          expandVideo(videoId, video);
        }
      }
    }
  }, [videos, galleryItems]);

  const handlePageChange = (page: number) => {
    setCurrentPage(page);
    window.scrollTo({ top: 0, behavior: 'smooth' });
  };

  // Build grid items based on mode
  const gridItems: GridItem[] = isPhotosMode
    ? mergeAdsIntoMediaGrid(
        galleryItems.map(gi => ({
          type: gi.type as 'video' | 'photo' | 'album',
          data: gi.data,
        })),
        ads
      )
    : mergeAdsIntoGrid(videos, ads);

  const totalItems = isPhotosMode ? galleryItems.length : videos.length;
  const emptyLabel = isPhotosMode ? 'photos' : 'videos';

  // Render a single grid item based on its type and expanded state
  const renderGridItem = (item: GridItem) => {
    if (item.type === 'ad') {
      return <GalleryAdCard key={`ad-${item.data.id}`} ad={item.data} />;
    }

    if (item.type === 'photo') {
      const photo = item.data as PublicPhoto;
      // Check if this photo is expanded
      if (expandedState.mediaType === 'photo' && expandedState.mediaData?.id === photo.id) {
        return <ExpandedPhotoCard key={`expanded-photo-${photo.id}`} photo={photo} />;
      }
      return <PublicPhotoCard key={`photo-${photo.id}`} photo={photo} />;
    }

    if (item.type === 'album') {
      const album = item.data as PublicAlbum;
      if (expandedState.mediaType === 'album' && expandedState.mediaData?.id === album.id) {
        return <ExpandedAlbumCard key={`expanded-album-${album.id}`} album={album} />;
      }
      return <PublicAlbumCard key={`album-${album.id}`} album={album} />;
    }

    // Default: video
    const video = item.data as Video;
    if (expandedState.videoId === video.id) {
      return <ExpandedVideoCard key={`expanded-${video.id}`} video={video} />;
    }
    return <PublicVideoCard key={video.id} video={video} />;
  };

  return (
    <div>
      {/* Featured Playlists Carousel — only on main gallery page (not photos tab) */}
      {!urlCategory && !search && <FeaturedPlaylistCarousel />}

      {loading && (
        <div style={{ textAlign: 'center', padding: 60 }}>
          <Spin size="large" />
        </div>
      )}

      {!loading && totalItems === 0 && (
        <Empty
          description={
            search
              ? `No ${emptyLabel} found for "${search}"`
              : `No ${emptyLabel} available`
          }
          style={{ padding: 60 }}
        />
      )}

      {!loading && totalItems > 0 && (
        <>
          <div
            style={{
              display: 'grid',
              gridTemplateColumns: isMobile
                ? '1fr'
                : 'repeat(auto-fill, minmax(280px, 1fr))',
              gridAutoFlow: 'dense',
              gap: 16,
            }}
          >
            {gridItems.map(renderGridItem)}
          </div>

          {pagination.total > pagination.limit && (
            <div style={{ marginTop: 32, textAlign: 'center' }}>
              <Pagination
                current={currentPage}
                pageSize={pagination.limit}
                total={pagination.total}
                onChange={handlePageChange}
                showSizeChanger={false}
                showTotal={(total) => `Total ${total} ${emptyLabel}`}
              />
            </div>
          )}
        </>
      )}
    </div>
  );
}

export default function MediaGalleryPage() {
  return (
    <ExpandedVideoProvider>
      <MediaGalleryContent />
    </ExpandedVideoProvider>
  );
}
