import { useState, useEffect, useRef, useCallback } from 'react';
import { motion } from 'framer-motion';
import { Search, Play, Pause, Loader2, Youtube, Heart, SkipForward, SkipBack, Volume2 } from 'lucide-react';
import { useMusicApiKeys } from '@/hooks/useMusicApiKeys';
import type { YTPlayer, YTStateChangeEvent, YTPlayerEvent } from '@/types/media-apis.d';
interface YouTubeVideo {
  id: string;
  title: string;
  channelTitle: string;
  thumbnail: string;
  duration?: string;
}

interface YouTubePlayerProps {
  playSound: (sound: string) => void;
  onOpenSettings: () => void;
}

// YouTube genres for discovery
const YOUTUBE_GENRES = [
  { label: 'Electronic', query: 'electronic music mix 2024' },
  { label: 'Lo-Fi', query: 'lofi hip hop beats to study' },
  { label: 'Synthwave', query: 'synthwave retrowave mix' },
  { label: 'Ambient', query: 'ambient relaxing music' },
  { label: 'Jazz', query: 'jazz music playlist' },
  { label: 'Classical', query: 'classical music piano' },
  { label: 'Hip Hop', query: 'hip hop beats instrumental' },
  { label: 'Chill', query: 'chill vibes music mix' },
];

const FAVORITES_KEY = 'youtube-favorites';

export const YouTubePlayer = ({ playSound, onOpenSettings }: YouTubePlayerProps) => {
  const { apiKeys, hasYoutubeKey } = useMusicApiKeys();
  const [searchQuery, setSearchQuery] = useState('');
  const [videos, setVideos] = useState<YouTubeVideo[]>([]);
  const [favorites, setFavorites] = useState<YouTubeVideo[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [currentVideo, setCurrentVideo] = useState<YouTubeVideo | null>(null);
  const [isPlaying, setIsPlaying] = useState(false);
  const [volume, setVolume] = useState(80);
  const [selectedGenre, setSelectedGenre] = useState<string | null>(null);
  const [showFavorites, setShowFavorites] = useState(false);
  const playerRef = useRef<YTPlayer | null>(null);
  const playerContainerRef = useRef<HTMLDivElement>(null);

  // Load favorites from localStorage
  useEffect(() => {
    const stored = localStorage.getItem(FAVORITES_KEY);
    if (stored) {
      try {
        setFavorites(JSON.parse(stored));
      } catch (e) {
        console.error('Failed to parse favorites');
      }
    }
  }, []);

  // Load YouTube IFrame API
  useEffect(() => {
    if (!window.YT) {
      const tag = document.createElement('script');
      tag.src = 'https://www.youtube.com/iframe_api';
      const firstScriptTag = document.getElementsByTagName('script')[0];
      firstScriptTag.parentNode?.insertBefore(tag, firstScriptTag);
    }
  }, []);

  const searchVideos = useCallback(async (query: string) => {
    if (!hasYoutubeKey || !query.trim()) return;
    
    setIsLoading(true);
    setError(null);
    
    try {
      const response = await fetch(
        `https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=15&type=video&videoCategoryId=10&q=${encodeURIComponent(query)}&key=${apiKeys.youtubeApiKey}`
      );
      
      if (!response.ok) {
        const data = await response.json();
        throw new Error(data.error?.message || 'Failed to search YouTube');
      }
      
      const data = await response.json();
      
      const results: YouTubeVideo[] = data.items.map((item: any) => ({
        id: item.id.videoId,
        title: item.snippet.title,
        channelTitle: item.snippet.channelTitle,
        thumbnail: item.snippet.thumbnails.medium?.url || item.snippet.thumbnails.default?.url,
      }));
      
      setVideos(results);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to search');
      console.error('YouTube search error:', err);
    } finally {
      setIsLoading(false);
    }
  }, [hasYoutubeKey, apiKeys.youtubeApiKey]);

  const handleSearch = () => {
    playSound('click');
    setSelectedGenre(null);
    setShowFavorites(false);
    searchVideos(searchQuery);
  };

  const handleGenreClick = (genre: typeof YOUTUBE_GENRES[0]) => {
    playSound('click');
    setSelectedGenre(genre.label);
    setShowFavorites(false);
    setSearchQuery(genre.query);
    searchVideos(genre.query);
  };

  const playVideo = (video: YouTubeVideo) => {
    playSound('click');
    setCurrentVideo(video);
    setIsPlaying(true);
    
    // Save to recent for recommendations
    const recentKey = 'youtube-recent';
    const recent = JSON.parse(localStorage.getItem(recentKey) || '[]');
    const updated = [video, ...recent.filter((v: YouTubeVideo) => v.id !== video.id)].slice(0, 20);
    localStorage.setItem(recentKey, JSON.stringify(updated));
    
    if (playerRef.current) {
      playerRef.current.loadVideoById(video.id);
    } else if (playerContainerRef.current && window.YT?.Player) {
      playerRef.current = new window.YT.Player(playerContainerRef.current, {
        height: '0',
        width: '0',
        videoId: video.id,
        playerVars: {
          autoplay: 1,
          controls: 0,
        },
        events: {
          onStateChange: (event: YTStateChangeEvent) => {
            if (event.data === window.YT.PlayerState.PLAYING) {
              setIsPlaying(true);
            } else if (event.data === window.YT.PlayerState.PAUSED) {
              setIsPlaying(false);
            } else if (event.data === window.YT.PlayerState.ENDED) {
              playNext();
            }
          },
          onReady: (event: YTPlayerEvent) => {
            event.target.setVolume(volume);
          },
        },
      });
    }
  };

  const togglePlay = () => {
    playSound('click');
    if (!playerRef.current) return;
    
    if (isPlaying) {
      playerRef.current.pauseVideo();
    } else {
      playerRef.current.playVideo();
    }
    setIsPlaying(!isPlaying);
  };

  const playNext = () => {
    if (!currentVideo || videos.length === 0) return;
    const currentIndex = videos.findIndex(v => v.id === currentVideo.id);
    const nextIndex = (currentIndex + 1) % videos.length;
    playVideo(videos[nextIndex]);
  };

  const playPrevious = () => {
    if (!currentVideo || videos.length === 0) return;
    const currentIndex = videos.findIndex(v => v.id === currentVideo.id);
    const prevIndex = currentIndex <= 0 ? videos.length - 1 : currentIndex - 1;
    playVideo(videos[prevIndex]);
  };

  const handleVolumeChange = (newVolume: number) => {
    setVolume(newVolume);
    if (playerRef.current) {
      playerRef.current.setVolume(newVolume);
    }
  };

  const toggleFavorite = (video: YouTubeVideo) => {
    playSound('click');
    const isFavorite = favorites.some(f => f.id === video.id);
    let updated: YouTubeVideo[];
    
    if (isFavorite) {
      updated = favorites.filter(f => f.id !== video.id);
    } else {
      updated = [video, ...favorites];
    }
    
    setFavorites(updated);
    localStorage.setItem(FAVORITES_KEY, JSON.stringify(updated));
  };

  const displayVideos = showFavorites ? favorites : videos;

  if (!hasYoutubeKey) {
    return (
      <div className="flex flex-col items-center justify-center p-8 space-y-4 border border-primary/30 bg-primary/5">
        <Youtube className="w-12 h-12 text-primary/50" />
        <p className="font-pixel text-sm text-foreground/60 text-center">
          YouTube API key required to search and play music
        </p>
        <button
          onClick={() => {
            playSound('click');
            onOpenSettings();
          }}
          className="px-4 py-2 border border-primary text-primary font-pixel text-sm hover:bg-primary hover:text-background transition-colors"
        >
          Add API Key
        </button>
      </div>
    );
  }

  return (
    <div className="space-y-4">
      {/* Hidden player container */}
      <div ref={playerContainerRef} className="hidden" />
      
      {/* Search */}
      <div className="flex gap-2">
        <div className="relative flex-1">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-primary/50" />
          <input
            type="text"
            placeholder="Search YouTube music..."
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            onKeyDown={(e) => e.key === 'Enter' && handleSearch()}
            className="w-full pl-10 pr-4 py-2 bg-background border border-primary/30 focus:border-primary font-pixel text-sm text-foreground placeholder:text-foreground/40 outline-none transition-colors"
          />
        </div>
        <button
          onClick={handleSearch}
          disabled={!searchQuery.trim() || isLoading}
          className="px-4 py-2 border border-primary text-primary hover:bg-primary hover:text-background transition-all duration-300 font-pixel text-sm disabled:opacity-50"
        >
          {isLoading ? <Loader2 className="w-4 h-4 animate-spin" /> : 'Search'}
        </button>
      </div>

      {/* Genre pills */}
      <div className="flex flex-wrap gap-2">
        <button
          onClick={() => {
            playSound('click');
            setShowFavorites(!showFavorites);
            setSelectedGenre(null);
          }}
          className={`px-3 py-1 border font-pixel text-xs transition-all flex items-center gap-1 ${
            showFavorites
              ? 'border-primary bg-primary text-background'
              : 'border-primary/30 text-primary/70 hover:border-primary hover:text-primary'
          }`}
        >
          <Heart size={12} /> Favorites
        </button>
        {YOUTUBE_GENRES.map((genre) => (
          <button
            key={genre.label}
            onClick={() => handleGenreClick(genre)}
            className={`px-3 py-1 border font-pixel text-xs transition-all ${
              selectedGenre === genre.label
                ? 'border-primary bg-primary text-background'
                : 'border-primary/30 text-primary/70 hover:border-primary hover:text-primary'
            }`}
          >
            {genre.label}
          </button>
        ))}
      </div>

      {/* Now Playing */}
      {currentVideo && (
        <motion.div
          initial={{ opacity: 0, y: -10 }}
          animate={{ opacity: 1, y: 0 }}
          className="border border-primary p-3 bg-primary/10"
        >
          <div className="flex items-center gap-3">
            <img
              src={currentVideo.thumbnail}
              alt={currentVideo.title}
              className="w-16 h-12 object-cover border border-primary/30"
            />
            <div className="flex-1 min-w-0">
              <p className="font-pixel text-sm text-primary truncate">{currentVideo.title}</p>
              <p className="font-pixel text-xs text-foreground/50 truncate">{currentVideo.channelTitle}</p>
            </div>
            <div className="flex items-center gap-2">
              <button onClick={playPrevious} className="p-1 text-primary hover:text-primary/80">
                <SkipBack size={16} />
              </button>
              <button onClick={togglePlay} className="p-2 border border-primary text-primary hover:bg-primary hover:text-background">
                {isPlaying ? <Pause size={16} /> : <Play size={16} />}
              </button>
              <button onClick={playNext} className="p-1 text-primary hover:text-primary/80">
                <SkipForward size={16} />
              </button>
              <button
                onClick={() => toggleFavorite(currentVideo)}
                className={`p-1 ${favorites.some(f => f.id === currentVideo.id) ? 'text-red-500' : 'text-primary/50 hover:text-red-500'}`}
              >
                <Heart size={16} fill={favorites.some(f => f.id === currentVideo.id) ? 'currentColor' : 'none'} />
              </button>
            </div>
          </div>
          <div className="flex items-center gap-2 mt-2">
            <Volume2 size={14} className="text-primary/70" />
            <input
              type="range"
              min="0"
              max="100"
              value={volume}
              onChange={(e) => handleVolumeChange(Number(e.target.value))}
              className="flex-1 h-1 bg-primary/30 appearance-none cursor-pointer [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-2 [&::-webkit-slider-thumb]:h-2 [&::-webkit-slider-thumb]:bg-primary"
            />
            <span className="font-pixel text-xs text-primary/70 w-8">{volume}%</span>
          </div>
        </motion.div>
      )}

      {/* Error */}
      {error && (
        <div className="p-3 border border-destructive/50 bg-destructive/10">
          <p className="font-pixel text-xs text-destructive">{error}</p>
        </div>
      )}

      {/* Results */}
      <div className="border border-primary/30 max-h-[250px] overflow-y-auto">
        {isLoading ? (
          <div className="flex items-center justify-center p-8">
            <Loader2 className="w-6 h-6 text-primary animate-spin" />
            <span className="font-pixel text-sm text-primary ml-2">Searching...</span>
          </div>
        ) : displayVideos.length === 0 ? (
          <div className="p-8 text-center">
            <Youtube className="w-8 h-8 text-primary/30 mx-auto mb-2" />
            <p className="font-pixel text-sm text-foreground/60">
              {showFavorites ? 'No favorites yet' : 'Search for music or select a genre'}
            </p>
          </div>
        ) : (
          displayVideos.map((video, index) => (
            <motion.button
              key={video.id}
              initial={{ opacity: 0 }}
              animate={{ opacity: 1 }}
              transition={{ delay: index * 0.03 }}
              onClick={() => playVideo(video)}
              className={`w-full flex items-center gap-3 p-2 border-b border-primary/10 hover:bg-primary/10 transition-all text-left ${
                currentVideo?.id === video.id ? 'bg-primary/20' : ''
              }`}
            >
              <img
                src={video.thumbnail}
                alt=""
                className="w-16 h-12 object-cover border border-primary/20"
              />
              <div className="flex-1 min-w-0">
                <p className="font-pixel text-xs text-primary truncate">{video.title}</p>
                <p className="font-pixel text-[10px] text-foreground/50 truncate">{video.channelTitle}</p>
              </div>
              <button
                onClick={(e) => {
                  e.stopPropagation();
                  toggleFavorite(video);
                }}
                className={`p-1 ${favorites.some(f => f.id === video.id) ? 'text-red-500' : 'text-primary/30 hover:text-red-500'}`}
              >
                <Heart size={14} fill={favorites.some(f => f.id === video.id) ? 'currentColor' : 'none'} />
              </button>
            </motion.button>
          ))
        )}
      </div>

      <p className="font-pixel text-xs text-foreground/50 text-center">
        {showFavorites ? `${favorites.length} favorites` : `${videos.length} results`} • Audio-only playback
      </p>
    </div>
  );
};
