import { motion, AnimatePresence } from 'framer-motion';
import { useState, useEffect } from 'react';
import { Play, Pause, Volume2, Radio, Search, Loader2, ChevronDown, Link2, SkipBack, SkipForward, Zap } from 'lucide-react';
import { useSettings } from '@/contexts/SettingsContext';
import { useMusic, Station } from '@/contexts/MusicContext';

const CATEGORIES = [
  { value: '', label: 'All Genres' },
  { value: 'pop', label: 'Pop' },
  { value: 'rock', label: 'Rock' },
  { value: 'jazz', label: 'Jazz' },
  { value: 'classical', label: 'Classical' },
  { value: 'electronic', label: 'Electronic' },
  { value: 'techno', label: 'Techno' },
  { value: 'house', label: 'House' },
  { value: 'trance', label: 'Trance' },
  { value: 'drum and bass', label: 'Drum & Bass' },
  { value: 'dubstep', label: 'Dubstep' },
  { value: 'hiphop', label: 'Hip Hop' },
  { value: 'country', label: 'Country' },
  { value: 'metal', label: 'Metal' },
  { value: 'ambient', label: 'Ambient' },
  { value: 'lofi', label: 'Lo-Fi' },
  { value: 'chillout', label: 'Chillout' },
  { value: 'synthwave', label: 'Synthwave' },
  { value: 'news', label: 'News' },
  { value: 'talk', label: 'Talk' },
];

// Preset electronic music streams
const PRESET_STREAMS = [
  { name: 'SomaFM - Groove Salad', url: 'https://ice2.somafm.com/groovesalad-128-mp3', genre: 'Ambient/Downtempo' },
  { name: 'SomaFM - DEF CON Radio', url: 'https://ice2.somafm.com/defcon-128-mp3', genre: 'Electronic/Hacker' },
  { name: 'SomaFM - Space Station', url: 'https://ice2.somafm.com/spacestation-128-mp3', genre: 'Space/Ambient' },
  { name: 'SomaFM - Drone Zone', url: 'https://ice2.somafm.com/dronezone-128-mp3', genre: 'Dark Ambient' },
  { name: 'SomaFM - Beat Blender', url: 'https://ice2.somafm.com/beatblender-128-mp3', genre: 'Deep House' },
  { name: 'SomaFM - cliqhop idm', url: 'https://ice2.somafm.com/cliqhop-128-mp3', genre: 'IDM/Glitch' },
  { name: 'Nightwave Plaza', url: 'https://radio.plaza.one/mp3', genre: 'Vaporwave' },
];

interface CategoryDropdownProps {
  selectedCategory: string;
  onSelect: (value: string) => void;
  playSound: (sound: string) => void;
}

const CategoryDropdown = ({ selectedCategory, onSelect, playSound }: CategoryDropdownProps) => {
  const [isOpen, setIsOpen] = useState(false);
  const dropdownRef = useState<HTMLDivElement | null>(null);

  useEffect(() => {
    const handleClickOutside = (e: MouseEvent) => {
      if (dropdownRef[0] && !dropdownRef[0].contains(e.target as Node)) {
        setIsOpen(false);
      }
    };
    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, [dropdownRef]);

  const selectedLabel = CATEGORIES.find(c => c.value === selectedCategory)?.label || 'All Genres';

  return (
    <div ref={(el) => { dropdownRef[1](el); }} className="relative">
      <button
        onClick={() => {
          playSound('click');
          setIsOpen(!isOpen);
        }}
        className="w-full flex items-center justify-between px-4 py-2 bg-background border border-primary/30 hover:border-primary font-pixel text-sm text-primary transition-colors"
      >
        <span>{selectedLabel}</span>
        <ChevronDown className={`w-4 h-4 transition-transform ${isOpen ? 'rotate-180' : ''}`} />
      </button>
      
      <AnimatePresence>
        {isOpen && (
          <motion.div
            initial={{ opacity: 0, y: -5 }}
            animate={{ opacity: 1, y: 0 }}
            exit={{ opacity: 0, y: -5 }}
            transition={{ duration: 0.15 }}
            className="absolute top-full left-0 right-0 z-50 mt-1 bg-background border border-primary/50 box-glow max-h-60 overflow-y-auto"
          >
            {CATEGORIES.map((cat) => (
              <button
                key={cat.value}
                onClick={() => {
                  playSound('click');
                  onSelect(cat.value);
                  setIsOpen(false);
                }}
                className={`w-full px-4 py-2 text-left font-pixel text-sm transition-colors hover:bg-primary/20 ${
                  selectedCategory === cat.value ? 'bg-primary/30 text-primary' : 'text-primary/80'
                }`}
              >
                {cat.label}
              </button>
            ))}
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
};

// URL validation helper
const isValidStreamUrl = (url: string): { valid: boolean; error?: string } => {
  if (!url.trim()) {
    return { valid: false, error: 'Please enter a URL' };
  }
  
  try {
    const parsed = new URL(url.trim());
    
    // Only allow http/https protocols
    if (!['http:', 'https:'].includes(parsed.protocol)) {
      return { valid: false, error: 'URL must use http or https protocol' };
    }
    
    // Basic format check
    if (!parsed.hostname || parsed.hostname.length < 3) {
      return { valid: false, error: 'Invalid hostname' };
    }
    
    return { valid: true };
  } catch {
    return { valid: false, error: 'Invalid URL format' };
  }
};

const Music = () => {
  const [searchQuery, setSearchQuery] = useState('');
  const [selectedCategory, setSelectedCategory] = useState('');
  const [customUrl, setCustomUrl] = useState('');
  const [customUrlError, setCustomUrlError] = useState<string | null>(null);
  const [activeTab, setActiveTab] = useState<'browse' | 'presets' | 'custom'>('browse');
  const [filteredStations, setFilteredStations] = useState<Station[]>([]);
  const { playSound } = useSettings();
  
  const {
    isPlaying,
    isBuffering,
    volume,
    stations,
    selectedStation,
    hasFetched,
    setVolume,
    playStation,
    togglePlay,
    playNext,
    playPrevious,
    fetchStations,
  } = useMusic();

  // Fetch stations on mount
  useEffect(() => {
    fetchStations();
  }, [fetchStations]);

  // Filter stations based on search and category
  useEffect(() => {
    const filtered = stations.filter(station => {
      const matchesSearch = station.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
        station.tags.toLowerCase().includes(searchQuery.toLowerCase()) ||
        station.country.toLowerCase().includes(searchQuery.toLowerCase());
      
      const matchesCategory = !selectedCategory || 
        station.tags.toLowerCase().includes(selectedCategory.toLowerCase());
      
      return matchesSearch && matchesCategory;
    });
    setFilteredStations(filtered);
  }, [searchQuery, selectedCategory, stations]);

  const handlePlayStation = (station: Station, index: number) => {
    playSound('click');
    playStation(station, index);
  };

  // Clear error when URL changes
  useEffect(() => {
    if (customUrlError) setCustomUrlError(null);
  }, [customUrl]);

  const playCustomUrl = () => {
    const validation = isValidStreamUrl(customUrl);
    
    if (!validation.valid) {
      setCustomUrlError(validation.error || 'Invalid URL');
      playSound('error');
      return;
    }
    
    setCustomUrlError(null);
    playSound('click');
    
    const customStation: Station = {
      stationuuid: 'custom-' + Date.now(),
      name: 'Custom Stream',
      url: customUrl.trim(),
      favicon: '',
      country: 'Custom',
      tags: 'custom',
      bitrate: 0,
    };
    
    playStation(customStation, -1);
  };

  const playPreset = (preset: typeof PRESET_STREAMS[0]) => {
    playSound('click');
    
    const presetStation: Station = {
      stationuuid: 'preset-' + preset.name,
      name: preset.name,
      url: preset.url,
      favicon: '',
      country: preset.genre,
      tags: preset.genre.toLowerCase(),
      bitrate: 128,
    };
    
    playStation(presetStation, -1);
  };

  const handleTogglePlay = () => {
    playSound('click');
    togglePlay();
  };

  const handlePlayNext = () => {
    playSound('click');
    playNext();
  };

  const handlePlayPrevious = () => {
    playSound('click');
    playPrevious();
  };

  const isLoading = !hasFetched;

  return (
    <motion.div
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
      transition={{ duration: 0.5 }}
      className="space-y-6"
    >
      <h1 className="font-minecraft text-3xl md:text-4xl text-primary text-glow-strong">
        Radio Player
      </h1>
      
      <p className="font-pixel text-foreground/80">
        Stream radio stations from around the world or add your own stream URL.
      </p>

      {/* Now Playing */}
      {selectedStation && (
        <motion.div
          initial={{ opacity: 0, y: -10 }}
          animate={{ opacity: 1, y: 0 }}
          className="border border-primary p-4 bg-primary/5 box-glow space-y-4"
        >
          <div className="flex items-center gap-4">
            <div className="w-12 h-12 border border-primary/50 flex items-center justify-center bg-background">
              {selectedStation.favicon ? (
                <img 
                  src={selectedStation.favicon} 
                  alt={selectedStation.name}
                  className="w-full h-full object-cover"
                  onError={(e) => {
                    (e.target as HTMLImageElement).style.display = 'none';
                  }}
                />
              ) : (
                <Radio className="w-6 h-6 text-primary" />
              )}
            </div>
            <div className="flex-1 min-w-0">
              <h2 className="font-minecraft text-lg text-primary text-glow truncate">
                {selectedStation.name}
              </h2>
              <p className="font-pixel text-xs text-foreground/60 truncate">
                {selectedStation.country} {selectedStation.bitrate > 0 && `• ${selectedStation.bitrate}kbps`}
              </p>
              {isBuffering && (
                <p className="font-pixel text-xs text-primary/60">Buffering...</p>
              )}
            </div>
            {/* Playback Controls */}
            <div className="flex items-center gap-2">
              <button
                onClick={handlePlayPrevious}
                className="p-2 border border-primary/50 text-primary hover:bg-primary hover:text-background transition-all duration-300"
                title="Previous station"
              >
                <SkipBack size={16} />
              </button>
              <button
                onClick={handleTogglePlay}
                className="p-3 border border-primary text-primary hover:bg-primary hover:text-background transition-all duration-300"
                disabled={isBuffering}
              >
                {isBuffering ? (
                  <Loader2 size={20} className="animate-spin" />
                ) : isPlaying ? (
                  <Pause size={20} />
                ) : (
                  <Play size={20} />
                )}
              </button>
              <button
                onClick={handlePlayNext}
                className="p-2 border border-primary/50 text-primary hover:bg-primary hover:text-background transition-all duration-300"
                title="Next station"
              >
                <SkipForward size={16} />
              </button>
            </div>
          </div>

          <div className="flex items-center gap-3">
            <Volume2 size={16} className="text-primary" />
            <input
              type="range"
              min="0"
              max="100"
              value={volume}
              onChange={(e) => setVolume(Number(e.target.value))}
              className="flex-1 h-1.5 bg-primary/30 appearance-none cursor-pointer [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-3 [&::-webkit-slider-thumb]:h-3 [&::-webkit-slider-thumb]:bg-primary [&::-webkit-slider-thumb]:shadow-[0_0_5px_hsl(var(--glow-color)/0.8)]"
            />
            <span className="font-pixel text-xs text-primary min-w-[40px]">
              {volume}%
            </span>
          </div>
        </motion.div>
      )}

      {/* Tabs */}
      <div className="flex gap-2 border-b border-primary/30">
        {(['browse', 'presets', 'custom'] as const).map((tab) => (
          <button
            key={tab}
            onClick={() => {
              playSound('click');
              setActiveTab(tab);
            }}
            className={`px-4 py-2 font-pixel text-sm transition-all ${
              activeTab === tab 
                ? 'text-primary border-b-2 border-primary text-glow' 
                : 'text-foreground/60 hover:text-primary'
            }`}
          >
            {tab === 'browse' && 'Browse'}
            {tab === 'presets' && 'Electronic'}
            {tab === 'custom' && 'Custom URL'}
          </button>
        ))}
      </div>

      {/* Browse Tab */}
      {activeTab === 'browse' && (
        <>
          {/* Filters */}
          <div className="flex flex-col sm:flex-row gap-3">
            <div className="sm:w-48">
              <CategoryDropdown
                selectedCategory={selectedCategory}
                onSelect={setSelectedCategory}
                playSound={playSound}
              />
            </div>
            <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 stations..."
                value={searchQuery}
                onChange={(e) => setSearchQuery(e.target.value)}
                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>
          </div>

          {/* Station List */}
          <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">Loading stations...</span>
              </div>
            ) : filteredStations.length === 0 ? (
              <div className="p-4 text-center">
                <p className="font-pixel text-sm text-foreground/60">No stations found</p>
              </div>
            ) : (
              filteredStations.map((station, index) => (
                <motion.button
                  key={station.stationuuid}
                  initial={{ opacity: 0 }}
                  animate={{ opacity: 1 }}
                  transition={{ delay: index * 0.02 }}
                  onClick={() => handlePlayStation(station, index)}
                  className={`w-full flex items-center gap-3 p-3 border-b border-primary/10 hover:bg-primary/10 transition-all duration-200 text-left ${
                    selectedStation?.stationuuid === station.stationuuid ? 'bg-primary/20' : ''
                  }`}
                >
                  <div className="w-8 h-8 border border-primary/30 flex items-center justify-center flex-shrink-0 bg-background">
                    {station.favicon ? (
                      <img 
                        src={station.favicon} 
                        alt=""
                        className="w-full h-full object-cover"
                        onError={(e) => {
                          (e.target as HTMLImageElement).style.display = 'none';
                        }}
                      />
                    ) : (
                      <Radio className="w-4 h-4 text-primary/50" />
                    )}
                  </div>
                  <div className="flex-1 min-w-0">
                    <p className="font-pixel text-sm text-primary truncate">{station.name}</p>
                    <p className="font-pixel text-xs text-foreground/50 truncate">
                      {station.country} {station.tags && `• ${station.tags.split(',')[0]}`}
                    </p>
                  </div>
                  {selectedStation?.stationuuid === station.stationuuid && isPlaying && (
                    <div className="flex gap-0.5">
                      <span className="w-1 h-3 bg-primary animate-pulse" style={{ animationDelay: '0ms' }} />
                      <span className="w-1 h-3 bg-primary animate-pulse" style={{ animationDelay: '150ms' }} />
                      <span className="w-1 h-3 bg-primary animate-pulse" style={{ animationDelay: '300ms' }} />
                    </div>
                  )}
                </motion.button>
              ))
            )}
          </div>

          <p className="font-pixel text-xs text-foreground/50 text-center">
            {filteredStations.length} stations available
          </p>
        </>
      )}

      {/* Electronic Presets Tab */}
      {activeTab === 'presets' && (
        <div className="space-y-4">
          <div className="flex items-center gap-2 text-primary mb-4">
            <Zap size={16} />
            <span className="font-pixel text-sm">Curated Electronic Streams</span>
          </div>
          <div className="border border-primary/30 max-h-[300px] overflow-y-auto">
            {PRESET_STREAMS.map((preset, index) => (
              <motion.button
                key={preset.name}
                initial={{ opacity: 0 }}
                animate={{ opacity: 1 }}
                transition={{ delay: index * 0.05 }}
                onClick={() => playPreset(preset)}
                className={`w-full flex items-center gap-3 p-3 border-b border-primary/10 hover:bg-primary/10 transition-all duration-200 text-left ${
                  selectedStation?.name === preset.name ? 'bg-primary/20' : ''
                }`}
              >
                <div className="w-8 h-8 border border-primary/30 flex items-center justify-center flex-shrink-0 bg-background">
                  <Zap className="w-4 h-4 text-primary/70" />
                </div>
                <div className="flex-1 min-w-0">
                  <p className="font-pixel text-sm text-primary truncate">{preset.name}</p>
                  <p className="font-pixel text-xs text-foreground/50 truncate">{preset.genre}</p>
                </div>
                {selectedStation?.name === preset.name && isPlaying && (
                  <div className="flex gap-0.5">
                    <span className="w-1 h-3 bg-primary animate-pulse" style={{ animationDelay: '0ms' }} />
                    <span className="w-1 h-3 bg-primary animate-pulse" style={{ animationDelay: '150ms' }} />
                    <span className="w-1 h-3 bg-primary animate-pulse" style={{ animationDelay: '300ms' }} />
                  </div>
                )}
              </motion.button>
            ))}
          </div>
          <p className="font-pixel text-xs text-foreground/50 text-center">
            High-quality electronic music streams from SomaFM and others
          </p>
        </div>
      )}

      {/* Custom URL Tab */}
      {activeTab === 'custom' && (
        <div className="space-y-4">
          <div className="flex items-center gap-2 text-primary mb-4">
            <Link2 size={16} />
            <span className="font-pixel text-sm">Play Custom Stream URL</span>
          </div>
          <p className="font-pixel text-xs text-foreground/60">
            Enter a direct URL to an audio stream (MP3, AAC, OGG, etc.)
          </p>
          <div className="flex gap-2">
            <input
              type="url"
              placeholder="https://stream.example.com/radio.mp3"
              value={customUrl}
              onChange={(e) => setCustomUrl(e.target.value)}
              onKeyDown={(e) => e.key === 'Enter' && playCustomUrl()}
              className={`flex-1 px-4 py-2 bg-background border font-pixel text-sm text-foreground placeholder:text-foreground/40 outline-none transition-colors ${
                customUrlError ? 'border-destructive focus:border-destructive' : 'border-primary/30 focus:border-primary'
              }`}
            />
            <button
              onClick={playCustomUrl}
              disabled={!customUrl.trim()}
              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 disabled:cursor-not-allowed"
            >
              Play
            </button>
          </div>
          {customUrlError && (
            <p className="font-pixel text-xs text-destructive">{customUrlError}</p>
          )}
          <div className="border border-primary/20 p-3 bg-primary/5">
            <p className="font-pixel text-xs text-primary mb-2">Tips:</p>
            <ul className="font-pixel text-xs text-foreground/60 space-y-1 list-disc list-inside">
              <li>Use direct stream URLs (not webpage URLs)</li>
              <li>Supported formats: MP3, AAC, OGG, FLAC</li>
              <li>Look for .m3u or .pls files on radio sites</li>
              <li>SomaFM, Radio.co, and Icecast streams work well</li>
            </ul>
          </div>
        </div>
      )}
    </motion.div>
  );
};

export default Music;
