import { useState, useRef, useEffect } from 'react';
import { api } from '../lib/api';
import type { TTSStylePreset, TTSProvider } from '../types/api';

interface VoicePreviewButtonProps {
  voiceName: string;
  language: string;
  disabled?: boolean;
  provider?: TTSProvider;
  model?: string;
  speed?: number;
  stylePreset?: TTSStylePreset;
  customStylePrompt?: string;
  stability?: number;
  similarityBoost?: number;
}

export function VoicePreviewButton({
  voiceName,
  language,
  disabled,
  provider,
  model,
  speed,
  stylePreset,
  customStylePrompt,
  stability,
  similarityBoost,
}: VoicePreviewButtonProps) {
  const [isLoading, setIsLoading] = useState(false);
  const [isPlaying, setIsPlaying] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const audioRef = useRef<HTMLAudioElement | null>(null);
  const audioUrlRef = useRef<string | null>(null);

  // Clear cached audio when any TTS setting changes
  useEffect(() => {
    // Stop any playing audio
    if (audioRef.current) {
      audioRef.current.pause();
      audioRef.current = null;
    }
    // Revoke old URL
    if (audioUrlRef.current) {
      URL.revokeObjectURL(audioUrlRef.current);
      audioUrlRef.current = null;
    }
    setIsPlaying(false);
    setError(null);
  }, [voiceName, language, provider, model, speed, stylePreset, customStylePrompt, stability, similarityBoost]);

  const handlePreview = async () => {
    setError(null);

    // If already playing, stop
    if (isPlaying && audioRef.current) {
      audioRef.current.pause();
      audioRef.current.currentTime = 0;
      setIsPlaying(false);
      return;
    }

    // If we have cached audio, play it
    if (audioUrlRef.current && audioRef.current) {
      audioRef.current.play();
      setIsPlaying(true);
      return;
    }

    // Fetch new audio
    setIsLoading(true);
    try {
      const blob = await api.previewVoice(
        voiceName,
        language,
        model,
        speed,
        stylePreset,
        customStylePrompt,
        provider,
        stability,
        similarityBoost,
      );
      const url = URL.createObjectURL(blob);

      // Clean up old URL if exists
      if (audioUrlRef.current) {
        URL.revokeObjectURL(audioUrlRef.current);
      }

      audioUrlRef.current = url;

      // Create and play audio
      const audio = new Audio(url);
      audioRef.current = audio;

      audio.onended = () => {
        setIsPlaying(false);
      };

      audio.onerror = () => {
        setError('Failed to play audio');
        setIsPlaying(false);
      };

      await audio.play();
      setIsPlaying(true);
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : 'Failed to generate preview';
      setError(errorMessage);
      console.error('Voice preview error:', err);
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <div className="inline-flex items-center gap-2">
      <button
        type="button"
        onClick={handlePreview}
        disabled={disabled || isLoading}
        className={`
          inline-flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium rounded-md
          transition-colors duration-150
          ${disabled || isLoading
            ? 'bg-gray-100 text-gray-400 cursor-not-allowed'
            : isPlaying
              ? 'bg-red-100 text-red-700 hover:bg-red-200'
              : 'bg-blue-100 text-blue-700 hover:bg-blue-200'
          }
        `}
      >
        {isLoading ? (
          <>
            <svg className="animate-spin h-4 w-4" viewBox="0 0 24 24">
              <circle
                className="opacity-25"
                cx="12"
                cy="12"
                r="10"
                stroke="currentColor"
                strokeWidth="4"
                fill="none"
              />
              <path
                className="opacity-75"
                fill="currentColor"
                d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
              />
            </svg>
            Loading...
          </>
        ) : isPlaying ? (
          <>
            <svg className="h-4 w-4" fill="currentColor" viewBox="0 0 20 20">
              <path
                fillRule="evenodd"
                d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zM7 8a1 1 0 011-1h4a1 1 0 110 2H8a1 1 0 01-1-1zm0 4a1 1 0 011-1h4a1 1 0 110 2H8a1 1 0 01-1-1z"
                clipRule="evenodd"
              />
            </svg>
            Stop
          </>
        ) : (
          <>
            <svg className="h-4 w-4" fill="currentColor" viewBox="0 0 20 20">
              <path
                fillRule="evenodd"
                d="M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8v4a1 1 0 001.555.832l3-2a1 1 0 000-1.664l-3-2z"
                clipRule="evenodd"
              />
            </svg>
            Preview
          </>
        )}
      </button>
      {error && <span className="text-xs text-red-600">{error}</span>}
    </div>
  );
}
