'use client';

import { useState, useEffect, useRef } from 'react';
import { toast } from 'react-hot-toast';
import {
  Mic,
  Search,
  Play,
  Pause,
  Trash2,
  Edit2,
  Plus,
  Volume2,
  User,
  Building2,
  RefreshCw,
  BookmarkPlus
} from 'lucide-react';
import AdminGuard from '@/components/AdminGuard';
import api from '@/lib/api';

interface Voice {
  voice_id: string;
  name: string;
  category: string;
  description?: string;
  labels?: {
    accent?: string;
    gender?: string;
    age?: string;
    description?: string;
    use_case?: string;
  };
  preview_url?: string;
  settings?: {
    stability: number;
    similarity_boost: number;
    style?: number;
    use_speaker_boost?: boolean;
  };
  samples?: { sample_id: string; file_name: string; mime_type: string }[];
}

export default function VoicesAdminPage() {
  const [voices, setVoices] = useState<Voice[]>([]);
  const [loading, setLoading] = useState(true);
  const [searchQuery, setSearchQuery] = useState('');
  const [categoryFilter, setCategoryFilter] = useState('');
  const [playingVoiceId, setPlayingVoiceId] = useState<string | null>(null);
  const [editingVoice, setEditingVoice] = useState<Voice | null>(null);
  const [newName, setNewName] = useState('');
  const [newDescription, setNewDescription] = useState('');
  const [savedVoices, setSavedVoices] = useState<Set<string>>(new Set());
  const audioRef = useRef<HTMLAudioElement | null>(null);

  useEffect(() => {
    // Load saved voices from localStorage
    const saved = localStorage.getItem('savedVoices');
    if (saved) {
      setSavedVoices(new Set(JSON.parse(saved)));
    }
  }, []);

  useEffect(() => {
    fetchVoices();
  }, []);

  const fetchVoices = async () => {
    setLoading(true);
    try {
      const response = await api.get('/admin/voices');
      setVoices(response.data.voices || []);
    } catch (err: any) {
      console.error('Failed to fetch voices:', err);
      toast.error(err.response?.data?.detail || 'Failed to fetch voices');
      // Mock data for demo
      setVoices([
        {
          voice_id: '21m00Tcm4TlvDq8ikWAM',
          name: 'Rachel',
          category: 'premade',
          description: 'Calm, professional female voice',
          labels: { accent: 'american', gender: 'female', age: 'young' },
          preview_url: 'https://api.elevenlabs.io/v1/voices/21m00Tcm4TlvDq8ikWAM/preview',
        },
        {
          voice_id: 'ErXwobaYiN019PkySvjV',
          name: 'Antoni',
          category: 'premade',
          description: 'Well-rounded male voice',
          labels: { accent: 'american', gender: 'male', age: 'middle_aged' },
        },
      ]);
    } finally {
      setLoading(false);
    }
  };

  const handlePlayPreview = (voice: Voice) => {
    if (playingVoiceId === voice.voice_id) {
      // Stop playing
      if (audioRef.current) {
        audioRef.current.pause();
        audioRef.current = null;
      }
      setPlayingVoiceId(null);
    } else {
      // Stop any current playback
      if (audioRef.current) {
        audioRef.current.pause();
      }

      // Start new playback
      if (voice.preview_url) {
        const audio = new Audio(voice.preview_url);
        audio.onended = () => {
          setPlayingVoiceId(null);
          audioRef.current = null;
        };
        audio.onerror = () => {
          toast.error('Failed to play preview');
          setPlayingVoiceId(null);
        };
        audio.play();
        audioRef.current = audio;
        setPlayingVoiceId(voice.voice_id);
      } else {
        toast.error('No preview available for this voice');
      }
    }
  };

  const handleDeleteVoice = async (voice: Voice) => {
    if (voice.category === 'premade') {
      toast.error('Cannot delete premade voices');
      return;
    }

    if (!confirm(`Are you sure you want to delete the voice "${voice.name}"?`)) {
      return;
    }

    try {
      await api.delete(`/admin/voices/${voice.voice_id}`);
      toast.success('Voice deleted successfully');
      fetchVoices();
    } catch (err: any) {
      toast.error(err.response?.data?.detail || 'Failed to delete voice');
    }
  };

  const handleUpdateVoice = async () => {
    if (!editingVoice) return;

    try {
      await api.patch(`/admin/voices/${editingVoice.voice_id}/settings`, {
        name: newName || undefined,
        description: newDescription || undefined,
      });
      toast.success('Voice updated successfully');
      setEditingVoice(null);
      fetchVoices();
    } catch (err: any) {
      toast.error(err.response?.data?.detail || 'Failed to update voice');
    }
  };

  const handleSaveVoice = (voiceId: string) => {
    const newSaved = new Set(savedVoices);
    if (newSaved.has(voiceId)) {
      newSaved.delete(voiceId);
      toast.success('Removed from library');
    } else {
      newSaved.add(voiceId);
      toast.success('Added to library');
    }
    setSavedVoices(newSaved);
    localStorage.setItem('savedVoices', JSON.stringify(Array.from(newSaved)));
  };

  const filteredVoices = voices.filter((voice) => {
    const matchesSearch =
      voice.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
      voice.description?.toLowerCase().includes(searchQuery.toLowerCase()) ||
      voice.labels?.accent?.toLowerCase().includes(searchQuery.toLowerCase()) ||
      voice.labels?.gender?.toLowerCase().includes(searchQuery.toLowerCase()) ||
      voice.labels?.age?.toLowerCase().replace('_', ' ').includes(searchQuery.toLowerCase()) ||
      voice.labels?.use_case?.toLowerCase().includes(searchQuery.toLowerCase()) ||
      voice.voice_id.toLowerCase().includes(searchQuery.toLowerCase());

    const matchesCategory = !categoryFilter || voice.category === categoryFilter;

    return matchesSearch && matchesCategory;
  });

  const getCategoryBadgeColor = (category: string) => {
    switch (category) {
      case 'cloned':
        return 'bg-purple-900/50 text-purple-400';
      case 'generated':
        return 'bg-blue-900/50 text-blue-400';
      case 'professional':
        return 'bg-green-900/50 text-green-400';
      default:
        return 'bg-gray-700 text-gray-400';
    }
  };

  const getGenderIcon = (gender?: string) => {
    if (gender === 'female') return <User className="w-4 h-4 text-pink-400" />;
    if (gender === 'male') return <User className="w-4 h-4 text-blue-400" />;
    return <User className="w-4 h-4 text-gray-400" />;
  };

  const categories = [...new Set(voices.map((v) => v.category))];

  return (
    <AdminGuard>
      <div className="space-y-6">
        {/* Header */}
        <div className="flex items-center justify-between">
          <div className="flex items-center gap-4">
            <div className="w-12 h-12 bg-purple-900/30 rounded-lg flex items-center justify-center">
              <Mic className="w-6 h-6 text-purple-400" />
            </div>
            <div>
              <h1 className="text-2xl font-bold text-white">Voice Management</h1>
              <p className="text-gray-500">Manage ElevenLabs voices and custom clones</p>
            </div>
          </div>
          <div className="flex items-center gap-3">
            <button
              onClick={fetchVoices}
              className="btn-secondary flex items-center gap-2"
            >
              <RefreshCw className="w-4 h-4" />
              Refresh
            </button>
            <button
              onClick={() => toast('Voice cloning coming soon!')}
              className="btn-primary flex items-center gap-2"
            >
              <Plus className="w-4 h-4" />
              Clone Voice
            </button>
          </div>
        </div>

        {/* Filters */}
        <div className="flex gap-4">
          <div className="flex-1">
            <div className="relative">
              <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-500" />
              <input
                type="text"
                value={searchQuery}
                onChange={(e) => setSearchQuery(e.target.value)}
                placeholder="Search by name, accent, gender, age, use case, or ID..."
                className="input-field pl-10"
              />
            </div>
          </div>
          <select
            value={categoryFilter}
            onChange={(e) => setCategoryFilter(e.target.value)}
            className="select-field w-40"
          >
            <option value="">All Categories</option>
            {categories.map((cat) => (
              <option key={cat} value={cat}>
                {cat.charAt(0).toUpperCase() + cat.slice(1)}
              </option>
            ))}
          </select>
        </div>

        {/* Results Counter */}
        {searchQuery && (
          <div className="text-sm text-gray-400">
            Showing <span className="text-forge-yellow font-medium">{filteredVoices.length}</span> of {voices.length} voices
          </div>
        )}

        {/* Stats */}
        <div className="grid grid-cols-4 gap-4">
          <div className="bg-forge-dark rounded-xl border border-gray-800 p-4">
            <div className="flex items-center gap-3">
              <div className="w-10 h-10 bg-purple-900/30 rounded-lg flex items-center justify-center">
                <Volume2 className="w-5 h-5 text-purple-400" />
              </div>
              <div>
                <p className="text-2xl font-bold text-white">{voices.length}</p>
                <p className="text-sm text-gray-500">Total Voices</p>
              </div>
            </div>
          </div>
          <div className="bg-forge-dark rounded-xl border border-gray-800 p-4">
            <div className="flex items-center gap-3">
              <div className="w-10 h-10 bg-blue-900/30 rounded-lg flex items-center justify-center">
                <Building2 className="w-5 h-5 text-blue-400" />
              </div>
              <div>
                <p className="text-2xl font-bold text-white">
                  {voices.filter((v) => v.category === 'premade').length}
                </p>
                <p className="text-sm text-gray-500">Premade</p>
              </div>
            </div>
          </div>
          <div className="bg-forge-dark rounded-xl border border-gray-800 p-4">
            <div className="flex items-center gap-3">
              <div className="w-10 h-10 bg-green-900/30 rounded-lg flex items-center justify-center">
                <User className="w-5 h-5 text-green-400" />
              </div>
              <div>
                <p className="text-2xl font-bold text-white">
                  {voices.filter((v) => v.category === 'cloned').length}
                </p>
                <p className="text-sm text-gray-500">Cloned</p>
              </div>
            </div>
          </div>
          <div className="bg-forge-dark rounded-xl border border-gray-800 p-4">
            <div className="flex items-center gap-3">
              <div className="w-10 h-10 bg-orange-900/30 rounded-lg flex items-center justify-center">
                <Mic className="w-5 h-5 text-orange-400" />
              </div>
              <div>
                <p className="text-2xl font-bold text-white">
                  {voices.filter((v) => v.category === 'professional').length}
                </p>
                <p className="text-sm text-gray-500">Professional</p>
              </div>
            </div>
          </div>
        </div>

        {/* Voices Grid */}
        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
          {loading ? (
            <div className="col-span-full p-8 text-center text-gray-500">
              Loading voices...
            </div>
          ) : filteredVoices.length === 0 ? (
            <div className="col-span-full p-8 text-center text-gray-500">
              No voices found
            </div>
          ) : (
            filteredVoices.map((voice) => (
              <div
                key={voice.voice_id}
                className="bg-forge-dark rounded-xl border border-gray-800 p-4 hover:border-gray-700 transition-colors"
              >
                <div className="flex items-start justify-between mb-3">
                  <div className="flex items-center gap-3">
                    <div className="w-10 h-10 bg-forge-gray rounded-lg flex items-center justify-center">
                      {getGenderIcon(voice.labels?.gender)}
                    </div>
                    <div>
                      <h3 className="text-white font-medium">{voice.name}</h3>
                      <span className={`badge text-xs ${getCategoryBadgeColor(voice.category)}`}>
                        {voice.category}
                      </span>
                    </div>
                  </div>
                  <button
                    onClick={() => handlePlayPreview(voice)}
                    className={`p-2 rounded-lg transition-colors ${playingVoiceId === voice.voice_id
                      ? 'bg-forge-yellow text-black'
                      : 'bg-forge-gray text-gray-400 hover:text-white'
                      }`}
                  >
                    {playingVoiceId === voice.voice_id ? (
                      <Pause className="w-4 h-4" />
                    ) : (
                      <Play className="w-4 h-4" />
                    )}
                  </button>
                </div>

                {voice.description && (
                  <p className="text-sm text-gray-500 mb-3 line-clamp-2">
                    {voice.description}
                  </p>
                )}

                {voice.labels && (
                  <div className="flex flex-wrap gap-1 mb-3">
                    {voice.labels.accent && (
                      <span className="px-2 py-0.5 text-xs bg-forge-gray rounded text-gray-400">
                        {voice.labels.accent}
                      </span>
                    )}
                    {voice.labels.age && (
                      <span className="px-2 py-0.5 text-xs bg-forge-gray rounded text-gray-400">
                        {voice.labels.age.replace('_', ' ')}
                      </span>
                    )}
                    {voice.labels.use_case && (
                      <span className="px-2 py-0.5 text-xs bg-forge-gray rounded text-gray-400">
                        {voice.labels.use_case}
                      </span>
                    )}
                  </div>
                )}

                <div className="flex items-center justify-between pt-3 border-t border-gray-800">
                  <code className="text-xs text-gray-500 font-mono">
                    {voice.voice_id.substring(0, 12)}...
                  </code>
                  <div className="flex items-center gap-1">
                    <button
                      onClick={() => handleSaveVoice(voice.voice_id)}
                      className={`p-1.5 transition-colors ${savedVoices.has(voice.voice_id)
                        ? 'text-forge-yellow'
                        : 'text-gray-400 hover:text-forge-yellow'
                        }`}
                      title={savedVoices.has(voice.voice_id) ? 'Remove from library' : 'Add to library'}
                    >
                      <BookmarkPlus className="w-4 h-4" />
                    </button>
                    {voice.category !== 'premade' && (
                      <>
                        <button
                          onClick={() => {
                            setEditingVoice(voice);
                            setNewName(voice.name);
                            setNewDescription(voice.description || '');
                          }}
                          className="p-1.5 text-gray-400 hover:text-forge-yellow transition-colors"
                          title="Edit voice"
                        >
                          <Edit2 className="w-4 h-4" />
                        </button>
                        <button
                          onClick={() => handleDeleteVoice(voice)}
                          className="p-1.5 text-gray-400 hover:text-red-400 transition-colors"
                          title="Delete voice"
                        >
                          <Trash2 className="w-4 h-4" />
                        </button>
                      </>
                    )}
                  </div>
                </div>
              </div>
            ))
          )}
        </div>

        {/* Edit Voice Modal */}
        {editingVoice && (
          <div className="fixed inset-0 bg-black/60 flex items-center justify-center z-50 p-4">
            <div className="bg-forge-dark rounded-xl border border-gray-800 w-full max-w-md">
              <div className="p-6 border-b border-gray-800 flex items-center justify-between">
                <h3 className="text-lg font-semibold text-white">Edit Voice</h3>
                <button
                  onClick={() => setEditingVoice(null)}
                  className="text-gray-400 hover:text-white text-2xl"
                >
                  &times;
                </button>
              </div>
              <div className="p-6 space-y-4">
                <div>
                  <label className="block text-sm font-medium text-gray-300 mb-2">
                    Voice Name
                  </label>
                  <input
                    type="text"
                    value={newName}
                    onChange={(e) => setNewName(e.target.value)}
                    className="input-field"
                    placeholder="Enter voice name"
                  />
                </div>
                <div>
                  <label className="block text-sm font-medium text-gray-300 mb-2">
                    Description
                  </label>
                  <textarea
                    value={newDescription}
                    onChange={(e) => setNewDescription(e.target.value)}
                    className="input-field min-h-[80px]"
                    placeholder="Enter voice description"
                  />
                </div>
                <div className="flex gap-3">
                  <button
                    onClick={() => setEditingVoice(null)}
                    className="btn-secondary flex-1"
                  >
                    Cancel
                  </button>
                  <button
                    onClick={handleUpdateVoice}
                    className="btn-primary flex-1"
                  >
                    Save Changes
                  </button>
                </div>
              </div>
            </div>
          </div>
        )}
      </div>
    </AdminGuard>
  );
}
