'use client';

import { useState } from 'react';
import { toast } from 'react-hot-toast';
import { Volume2, Download, Sparkles, Play, Pause, RotateCw } from 'lucide-react';
import JobProgress from '@/components/JobProgress';
import { modulesApi, assetsApi } from '@/lib/api';
import { useStore } from '@/lib/store';

const outputFormats = [
  { id: 'mp3_44100_128', name: 'MP3 (128kbps)' },
  { id: 'mp3_44100_192', name: 'MP3 (192kbps)' },
  { id: 'pcm_48000', name: 'WAV (48kHz)' },
];

const presetPrompts = [
  { label: 'Explosion', prompt: 'Cinematic explosion with debris and fire, big impact' },
  { label: 'Footsteps', prompt: 'Footsteps walking on gravel, steady pace' },
  { label: 'Thunder', prompt: 'Deep rolling thunder with distant rumbles' },
  { label: 'Swoosh', prompt: 'Fast whoosh sound, air movement, transition effect' },
  { label: 'Rain', prompt: 'Gentle rain falling on a window, ambient background' },
  { label: 'Door', prompt: 'Heavy wooden door creaking open slowly' },
  { label: 'Heartbeat', prompt: 'Slow heartbeat, tense dramatic moment' },
  { label: 'Typing', prompt: 'Keyboard typing, mechanical keys, fast typing' },
];

export default function SoundEffectsPage() {
  const { addJob, updateJob } = useStore();
  const [prompt, setPrompt] = useState('');
  const [duration, setDuration] = useState<number | null>(null);
  const [promptInfluence, setPromptInfluence] = useState(0.3);
  const [loop, setLoop] = useState(false);
  const [outputFormat, setOutputFormat] = useState('mp3_44100_128');
  const [jobId, setJobId] = useState<string | null>(null);
  const [generatedAudio, setGeneratedAudio] = useState<any>(null);
  const [loading, setLoading] = useState(false);
  const [playing, setPlaying] = useState(false);
  const [audioElement, setAudioElement] = useState<HTMLAudioElement | null>(null);

  const handleGenerate = async () => {
    if (!prompt.trim()) {
      toast.error('Please describe the sound effect');
      return;
    }

    setLoading(true);
    setGeneratedAudio(null);

    try {
      const response = await modulesApi.generateSoundEffect({
        text: prompt,
        duration_seconds: duration,
        prompt_influence: promptInfluence,
        loop,
        output_format: outputFormat,
      });

      const job = response.data;
      setJobId(job.id);
      addJob({
        id: job.id,
        module: 'sound_effects',
        status: job.status,
        progress: job.progress,
        created_at: job.created_at,
      });

      toast.success('Sound effect generation started!');
    } catch (err: any) {
      toast.error(err.response?.data?.detail || 'Failed to start generation');
      setLoading(false);
    }
  };

  const handleJobComplete = async (job: any) => {
    setLoading(false);
    updateJob(job.id, { status: 'completed', progress: 100 });

    if (job.output_asset_ids?.[0]) {
      const asset = await assetsApi.get(job.output_asset_ids[0]);
      setGeneratedAudio(asset.data);
      toast.success('Sound effect generated successfully!');
    }
  };

  const handleJobError = (error: string) => {
    setLoading(false);
    toast.error(error);
  };

  const handleDownload = async () => {
    if (!generatedAudio) return;
    try {
      const response = await assetsApi.download(generatedAudio.id);
      const url = window.URL.createObjectURL(response.data);
      const a = document.createElement('a');
      a.href = url;
      a.download = generatedAudio.original_filename;
      a.click();
      window.URL.revokeObjectURL(url);
    } catch (err) {
      toast.error('Failed to download audio');
    }
  };

  const handlePlayPause = () => {
    if (!generatedAudio) return;

    if (audioElement) {
      if (playing) {
        audioElement.pause();
      } else {
        audioElement.play();
      }
      setPlaying(!playing);
    } else {
      const audio = new Audio(`/api/v1/assets/${generatedAudio.id}/download`);
      audio.onended = () => setPlaying(false);
      audio.play();
      setAudioElement(audio);
      setPlaying(true);
    }
  };

  const applyPreset = (preset: typeof presetPrompts[0]) => {
    setPrompt(preset.prompt);
  };

  return (
    <div className="max-w-6xl mx-auto space-y-8">
      <div className="flex items-center gap-4">
        <div className="w-12 h-12 bg-forge-yellow/10 rounded-lg flex items-center justify-center">
          <Volume2 className="w-6 h-6 text-forge-yellow" />
        </div>
        <div>
          <h1 className="text-2xl font-bold text-white">Sound Effects Generator</h1>
          <p className="text-gray-500">Create custom sound effects with AI</p>
        </div>
      </div>

      <div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
        {/* Controls */}
        <div className="space-y-6">
          {/* Preset Buttons */}
          <div>
            <label className="block text-sm font-medium text-gray-300 mb-2">
              Quick Presets
            </label>
            <div className="flex flex-wrap gap-2">
              {presetPrompts.map((preset) => (
                <button
                  key={preset.label}
                  onClick={() => applyPreset(preset)}
                  className="px-3 py-1.5 text-sm bg-forge-gray border border-gray-700 rounded-lg text-gray-300 hover:text-white hover:border-forge-yellow transition-colors"
                >
                  {preset.label}
                </button>
              ))}
            </div>
          </div>

          {/* Prompt */}
          <div>
            <label className="block text-sm font-medium text-gray-300 mb-2">
              Sound Description
            </label>
            <textarea
              value={prompt}
              onChange={(e) => setPrompt(e.target.value)}
              placeholder="Describe the sound effect you want to create... e.g., 'Cinematic whoosh with reverb tail'"
              className="input-field min-h-[120px] resize-none"
              maxLength={500}
            />
            <p className="mt-1 text-xs text-gray-500">{prompt.length}/500 characters</p>
          </div>

          {/* Duration */}
          <div>
            <label className="block text-sm font-medium text-gray-300 mb-2">
              Duration (Optional)
            </label>
            <div className="flex items-center gap-4">
              <input
                type="number"
                min={1}
                max={22}
                value={duration || ''}
                onChange={(e) => setDuration(e.target.value ? parseInt(e.target.value) : null)}
                placeholder="Auto"
                className="input-field w-24"
              />
              <span className="text-gray-500 text-sm">seconds (max 22)</span>
            </div>
            <p className="mt-1 text-xs text-gray-500">
              Leave empty for automatic duration based on the sound
            </p>
          </div>

          {/* Prompt Influence */}
          <div>
            <label className="block text-sm font-medium text-gray-300 mb-2">
              Prompt Influence: {promptInfluence.toFixed(1)}
            </label>
            <input
              type="range"
              min={0}
              max={1}
              step={0.1}
              value={promptInfluence}
              onChange={(e) => setPromptInfluence(parseFloat(e.target.value))}
              className="w-full accent-forge-yellow"
            />
            <p className="text-xs text-gray-500 mt-1">
              Higher = closer match to description
            </p>
          </div>

          {/* Options */}
          <div className="grid grid-cols-2 gap-4">
            <div>
              <label className="block text-sm font-medium text-gray-300 mb-2">
                Output Format
              </label>
              <select
                value={outputFormat}
                onChange={(e) => setOutputFormat(e.target.value)}
                className="select-field"
              >
                {outputFormats.map((format) => (
                  <option key={format.id} value={format.id}>
                    {format.name}
                  </option>
                ))}
              </select>
            </div>
            <div>
              <label className="block text-sm font-medium text-gray-300 mb-2">
                Loop
              </label>
              <label className="flex items-center gap-2 cursor-pointer mt-2">
                <input
                  type="checkbox"
                  checked={loop}
                  onChange={(e) => setLoop(e.target.checked)}
                  className="w-4 h-4 accent-forge-yellow rounded"
                />
                <span className="text-gray-300">Create seamless loop</span>
              </label>
            </div>
          </div>

          {/* Generate Button */}
          <button
            onClick={handleGenerate}
            disabled={loading || !prompt.trim()}
            className="btn-primary w-full flex items-center justify-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed"
          >
            <Sparkles className="w-5 h-5" />
            {loading ? 'Generating...' : 'Generate Sound Effect'}
          </button>

          {/* Job Progress */}
          {jobId && loading && (
            <JobProgress
              jobId={jobId}
              onComplete={handleJobComplete}
              onError={handleJobError}
            />
          )}
        </div>

        {/* Results */}
        <div>
          <h2 className="text-lg font-semibold text-white mb-4">Generated Sound</h2>
          {generatedAudio ? (
            <div className="bg-forge-dark rounded-xl overflow-hidden border border-gray-800">
              <div className="p-6">
                <div className="flex items-center justify-center gap-4 mb-6">
                  <button
                    onClick={handlePlayPause}
                    className="w-16 h-16 bg-forge-yellow rounded-full flex items-center justify-center text-black hover:bg-yellow-400 transition-colors"
                  >
                    {playing ? (
                      <Pause className="w-8 h-8" />
                    ) : (
                      <Play className="w-8 h-8 ml-1" />
                    )}
                  </button>
                </div>
                <audio
                  src={`/api/v1/assets/${generatedAudio.id}/download`}
                  controls
                  className="w-full"
                  onPlay={() => setPlaying(true)}
                  onPause={() => setPlaying(false)}
                  onEnded={() => setPlaying(false)}
                />
              </div>
              <div className="p-4 border-t border-gray-800">
                <div className="flex items-center justify-between">
                  <div>
                    <p className="text-white font-medium">{generatedAudio.original_filename}</p>
                    <p className="text-sm text-gray-500">
                      {(generatedAudio.file_size_bytes / 1024).toFixed(1)} KB
                      {loop && ' (looping)'}
                    </p>
                  </div>
                  <div className="flex items-center gap-2">
                    <button
                      onClick={() => {
                        setGeneratedAudio(null);
                        setAudioElement(null);
                        setPlaying(false);
                      }}
                      className="p-2 text-gray-400 hover:text-white transition-colors"
                      title="Generate new"
                    >
                      <RotateCw className="w-5 h-5" />
                    </button>
                    <button
                      onClick={handleDownload}
                      className="btn-primary flex items-center gap-2"
                    >
                      <Download className="w-4 h-4" />
                      Download
                    </button>
                  </div>
                </div>
              </div>
            </div>
          ) : (
            <div className="bg-forge-dark rounded-xl border border-gray-800 p-8 text-center">
              <Volume2 className="w-12 h-12 text-gray-600 mx-auto mb-3" />
              <p className="text-gray-500">Generated sound effects will appear here</p>
            </div>
          )}

          {/* Tips */}
          <div className="mt-6 p-4 bg-forge-dark rounded-lg border border-gray-800">
            <h3 className="text-white font-medium mb-2">Tips for better results:</h3>
            <ul className="text-sm text-gray-400 space-y-1">
              <li>- Be specific about the type of sound (e.g., "metallic clang" vs just "impact")</li>
              <li>- Include acoustic qualities (reverb, echo, muffled, crisp)</li>
              <li>- Mention context (cinematic, game, UI, ambient)</li>
              <li>- Use loop option for ambient sounds and backgrounds</li>
            </ul>
          </div>
        </div>
      </div>
    </div>
  );
}
