import { useState, useEffect, useRef, useCallback } from 'react'
import { X, Play, Pause, Music, Check, Ban, Upload, Loader2 } from 'lucide-react'

export interface Track {
  id: string
  nome: string
  mood: string
  duracao: number
  fonte?: string
  creditos?: string
  preview_url: string
}

interface Props {
  open: boolean
  onClose: () => void
  apiUrl: string
  selectedId: string | null
  onSelect: (track: Track | null) => void
}

const UPLOAD_MAX_MB = 20
const UPLOAD_EXTS = ['.mp3', '.m4a', '.aac', '.wav', '.ogg']

const MOOD_LABELS: Record<string, string> = {
  upbeat: 'Energético',
  corporate: 'Profissional',
  inspiring: 'Inspirador',
  calm: 'Calmo',
  cinematic: 'Cinematográfico',
}

const MOOD_COLORS: Record<string, string> = {
  upbeat: 'from-amber-500/20 to-orange-500/20 border-amber-500/40 text-amber-300',
  corporate: 'from-blue-500/20 to-cyan-500/20 border-blue-500/40 text-blue-300',
  inspiring: 'from-violet-500/20 to-fuchsia-500/20 border-violet-500/40 text-violet-300',
  calm: 'from-emerald-500/20 to-teal-500/20 border-emerald-500/40 text-emerald-300',
  cinematic: 'from-slate-500/20 to-zinc-500/20 border-slate-400/40 text-slate-300',
  uploaded: 'from-yellow-500/25 to-amber-500/25 border-yellow-400/50 text-yellow-200',
}

const MOOD_LABELS_EXTRA: Record<string, string> = {
  uploaded: 'Minha música',
}

const PREVIEW_DURATION = 15 // segundos de auto-pause
const PREVIEW_START = 10    // pula a "intro" silenciosa

export default function MusicDrawer({ open, onClose, apiUrl, selectedId, onSelect }: Props) {
  const [tracks, setTracks] = useState<Track[]>([])
  const [uploadedTracks, setUploadedTracks] = useState<Track[]>([])
  const [moods, setMoods] = useState<string[]>([])
  const [moodAtivo, setMoodAtivo] = useState<string | null>(null)
  const [carregando, setCarregando] = useState(false)
  const [erro, setErro] = useState('')
  const [uploadErro, setUploadErro] = useState('')
  const [enviandoUpload, setEnviandoUpload] = useState(false)
  const [playingId, setPlayingId] = useState<string | null>(null)
  const [progresso, setProgresso] = useState(0)
  const audioRef = useRef<HTMLAudioElement | null>(null)
  const stopTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
  const fileInputRef = useRef<HTMLInputElement | null>(null)

  // Carrega tracks ao abrir
  useEffect(() => {
    if (!open || tracks.length > 0) return
    const carregar = async () => {
      setCarregando(true)
      setErro('')
      try {
        const r = await fetch(`${apiUrl}/api/musicas`)
        if (!r.ok) throw new Error('Falha ao buscar trilhas')
        const data = await r.json()
        setTracks(data.tracks || [])
        setMoods(data.moods || [])
      } catch (e) {
        setErro(e instanceof Error ? e.message : 'Erro ao carregar trilhas')
      } finally {
        setCarregando(false)
      }
    }
    carregar()
  }, [open, apiUrl, tracks.length])

  // Pausa qualquer áudio ao fechar
  useEffect(() => {
    if (!open) {
      pararPreview()
    }
  }, [open])

  // Cleanup
  useEffect(() => {
    return () => {
      pararPreview()
    }
  }, [])

  const pararPreview = useCallback(() => {
    if (stopTimerRef.current) {
      clearTimeout(stopTimerRef.current)
      stopTimerRef.current = null
    }
    if (audioRef.current) {
      audioRef.current.pause()
      audioRef.current.src = ''
      audioRef.current = null
    }
    setPlayingId(null)
    setProgresso(0)
  }, [])

  const tocarPreview = useCallback((track: Track) => {
    // se já está tocando essa, pausa
    if (playingId === track.id) {
      pararPreview()
      return
    }

    pararPreview()

    const audio = new Audio(`${apiUrl}${track.preview_url}`)
    audio.preload = 'auto'
    audioRef.current = audio
    setPlayingId(track.id)
    setProgresso(0)

    const start = Math.min(PREVIEW_START, Math.max(0, (track.duracao || 0) - PREVIEW_DURATION - 1))

    const onMeta = () => {
      try {
        audio.currentTime = start
      } catch {
        // ignora
      }
      audio.play().catch(() => {
        setErro('Falha ao iniciar áudio (autoplay bloqueado?)')
        setPlayingId(null)
      })
    }

    audio.addEventListener('loadedmetadata', onMeta, { once: true })

    audio.addEventListener('timeupdate', () => {
      const elapsed = audio.currentTime - start
      const pct = Math.min(100, Math.max(0, (elapsed / PREVIEW_DURATION) * 100))
      setProgresso(pct)
    })

    audio.addEventListener('ended', () => {
      pararPreview()
    })

    audio.addEventListener('error', () => {
      setErro('Erro ao tocar preview')
      pararPreview()
    })

    // Auto pause depois de PREVIEW_DURATION
    stopTimerRef.current = setTimeout(() => {
      pararPreview()
    }, PREVIEW_DURATION * 1000 + 500)
  }, [apiUrl, playingId, pararPreview])

  const selecionar = (t: Track | null) => {
    pararPreview()
    onSelect(t)
    onClose()
  }

  const abrirSeletor = () => {
    setUploadErro('')
    fileInputRef.current?.click()
  }

  const onArquivoEscolhido = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]
    // limpa o input pra permitir reescolher o mesmo arquivo depois
    if (e.target) e.target.value = ''
    if (!file) return

    // Valida extensão e tamanho client-side
    const nome = file.name.toLowerCase()
    const extOk = UPLOAD_EXTS.some(ext => nome.endsWith(ext))
    if (!extOk) {
      setUploadErro(`Formato não aceito. Use: ${UPLOAD_EXTS.join(', ')}`)
      return
    }
    if (file.size > UPLOAD_MAX_MB * 1024 * 1024) {
      setUploadErro(`Arquivo maior que ${UPLOAD_MAX_MB}MB.`)
      return
    }

    setUploadErro('')
    setEnviandoUpload(true)
    pararPreview()

    try {
      const fd = new FormData()
      fd.append('arquivo', file)
      const r = await fetch(`${apiUrl}/api/musicas/upload`, {
        method: 'POST',
        body: fd,
      })
      const data = await r.json()
      if (!r.ok) throw new Error(data.erro || 'Falha no upload.')

      const nova: Track = {
        id: data.id,
        nome: data.nome,
        mood: data.mood || 'uploaded',
        duracao: data.duracao || 0,
        preview_url: data.preview_url,
      }
      // adiciona no topo da lista de uploads (e impede duplicatas pelo id)
      setUploadedTracks(prev => [nova, ...prev.filter(t => t.id !== nova.id)])
      // seleciona automaticamente
      onSelect(nova)
    } catch (err) {
      setUploadErro(err instanceof Error ? err.message : 'Erro no upload.')
    } finally {
      setEnviandoUpload(false)
    }
  }

  const tracksDaLib = moodAtivo
    ? tracks.filter(t => t.mood === moodAtivo)
    : tracks

  // Uploads aparecem sempre no topo (não filtrados por mood "uploaded" — eles têm mood próprio)
  const uploadsFiltrados = moodAtivo && moodAtivo !== 'uploaded' ? [] : uploadedTracks

  return (
    <>
      {/* Overlay */}
      {open && (
        <div
          className="fixed inset-0 bg-black/60 z-40 transition-opacity"
          onClick={onClose}
        />
      )}

      {/* Drawer */}
      <aside
        className={`fixed right-0 top-0 h-full w-full sm:w-[420px] bg-slate-950 border-l border-white/10 z-50 transform transition-transform duration-300 ease-out shadow-2xl flex flex-col ${
          open ? 'translate-x-0' : 'translate-x-full'
        }`}
        aria-hidden={!open}
      >
        {/* Header */}
        <div className="flex items-center justify-between px-5 py-4 border-b border-white/10">
          <div className="flex items-center gap-2">
            <div className="w-8 h-8 rounded-lg bg-indigo-600/20 border border-indigo-500/30 flex items-center justify-center">
              <Music size={15} className="text-indigo-400" />
            </div>
            <div>
              <h2 className="text-sm font-bold text-white leading-none">Trilha sonora</h2>
              <p className="text-[10px] text-slate-500 mt-0.5">Royalty-free, uso comercial liberado</p>
            </div>
          </div>
          <button
            onClick={onClose}
            className="p-2 text-slate-400 hover:text-white transition-colors"
            aria-label="Fechar"
          >
            <X size={18} />
          </button>
        </div>

        {/* Filtros de mood */}
        <div className="px-5 py-3 border-b border-white/8 flex flex-wrap gap-1.5">
          <button
            onClick={() => setMoodAtivo(null)}
            className={`px-3 py-1.5 rounded-full text-xs font-medium transition-all ${
              moodAtivo === null
                ? 'bg-indigo-600 text-white'
                : 'bg-white/5 text-slate-400 hover:bg-white/10 hover:text-slate-200'
            }`}
          >
            Todos
          </button>
          {moods.map(m => (
            <button
              key={m}
              onClick={() => setMoodAtivo(m === moodAtivo ? null : m)}
              className={`px-3 py-1.5 rounded-full text-xs font-medium transition-all ${
                moodAtivo === m
                  ? 'bg-indigo-600 text-white'
                  : 'bg-white/5 text-slate-400 hover:bg-white/10 hover:text-slate-200'
              }`}
            >
              {MOOD_LABELS[m] || m}
            </button>
          ))}
        </div>

        {/* Lista */}
        <div className="flex-1 overflow-y-auto px-4 py-3 space-y-2">
          {/* Opção sem música */}
          <button
            onClick={() => selecionar(null)}
            className={`w-full text-left bg-white/3 hover:bg-white/5 border rounded-xl p-3 flex items-center gap-3 transition-all ${
              selectedId === null
                ? 'border-indigo-500/60 bg-indigo-600/10'
                : 'border-white/10'
            }`}
          >
            <div className="w-9 h-9 rounded-lg bg-white/5 flex items-center justify-center">
              <Ban size={16} className="text-slate-400" />
            </div>
            <div className="flex-1">
              <p className="text-sm font-medium text-slate-200">Sem música</p>
              <p className="text-[11px] text-slate-500">Manter só o áudio original</p>
            </div>
            {selectedId === null && <Check size={16} className="text-indigo-400" />}
          </button>

          {/* Upload de música do dispositivo */}
          <input
            ref={fileInputRef}
            type="file"
            accept="audio/*,.mp3,.m4a,.aac,.wav,.ogg"
            onChange={onArquivoEscolhido}
            className="hidden"
          />
          <button
            onClick={abrirSeletor}
            disabled={enviandoUpload}
            className={`w-full text-left border rounded-xl p-3 flex items-center gap-3 transition-all ${
              enviandoUpload
                ? 'border-yellow-400/40 bg-yellow-500/5 cursor-wait'
                : 'border-yellow-400/40 bg-gradient-to-r from-yellow-500/10 to-amber-500/10 hover:from-yellow-500/15 hover:to-amber-500/15'
            }`}
          >
            <div className="w-9 h-9 rounded-lg bg-yellow-500/20 border border-yellow-400/30 flex items-center justify-center">
              {enviandoUpload
                ? <Loader2 size={15} className="text-yellow-300 animate-spin" />
                : <Upload size={15} className="text-yellow-300" />}
            </div>
            <div className="flex-1 min-w-0">
              <p className="text-sm font-semibold text-yellow-100">
                {enviandoUpload ? 'Enviando...' : 'Subir minha música'}
              </p>
              <p className="text-[11px] text-yellow-200/60">
                {enviandoUpload
                  ? 'Processando arquivo no servidor'
                  : `MP3, M4A, AAC, WAV ou OGG (até ${UPLOAD_MAX_MB}MB)`}
              </p>
            </div>
          </button>

          {uploadErro && (
            <p className="text-center text-red-400 text-xs py-1">{uploadErro}</p>
          )}

          {/* Uploads do usuário */}
          {uploadsFiltrados.map(t => {
            const isPlaying = playingId === t.id
            const isSelected = selectedId === t.id
            const moodClasses = MOOD_COLORS.uploaded
            return (
              <div
                key={t.id}
                className={`bg-white/3 border rounded-xl p-3 transition-all ${
                  isSelected ? 'border-yellow-400/60 bg-yellow-500/10' : 'border-yellow-400/25'
                }`}
              >
                <div className="flex items-center gap-3">
                  <button
                    onClick={() => tocarPreview(t)}
                    className={`w-9 h-9 rounded-lg flex items-center justify-center transition-all ${
                      isPlaying
                        ? 'bg-yellow-500 text-slate-900'
                        : 'bg-white/5 text-slate-300 hover:bg-white/10'
                    }`}
                    aria-label={isPlaying ? 'Pausar' : 'Tocar'}
                  >
                    {isPlaying ? <Pause size={14} /> : <Play size={14} className="ml-0.5" />}
                  </button>

                  <div className="flex-1 min-w-0">
                    <p className="text-sm font-medium text-slate-100 truncate">{t.nome}</p>
                    <div className="flex items-center gap-2 mt-0.5">
                      <span className={`text-[9px] px-1.5 py-0.5 rounded-md border bg-gradient-to-r font-semibold uppercase tracking-wide ${moodClasses}`}>
                        {MOOD_LABELS_EXTRA.uploaded}
                      </span>
                      <span className="text-[10px] text-slate-500">{Math.round(t.duracao)}s</span>
                    </div>
                  </div>

                  <button
                    onClick={() => selecionar(t)}
                    className={`px-3 py-1.5 rounded-lg text-xs font-medium transition-all ${
                      isSelected
                        ? 'bg-yellow-500 text-slate-900'
                        : 'bg-white/5 text-slate-300 hover:bg-yellow-500 hover:text-slate-900'
                    }`}
                  >
                    {isSelected ? 'Selecionada' : 'Selecionar'}
                  </button>
                </div>

                {isPlaying && (
                  <div className="mt-2 h-1 bg-white/5 rounded-full overflow-hidden">
                    <div
                      className="h-full bg-yellow-400 transition-all"
                      style={{ width: `${progresso}%` }}
                    />
                  </div>
                )}
              </div>
            )
          })}

          {carregando && (
            <p className="text-center text-slate-500 text-xs py-6">Carregando trilhas...</p>
          )}
          {erro && (
            <p className="text-center text-red-400 text-xs py-3">{erro}</p>
          )}
          {!carregando && tracksDaLib.length === 0 && tracks.length > 0 && (
            <p className="text-center text-slate-500 text-xs py-6">Nenhuma trilha nesse mood.</p>
          )}

          {tracksDaLib.map(t => {
            const isPlaying = playingId === t.id
            const isSelected = selectedId === t.id
            const moodClasses = MOOD_COLORS[t.mood] || MOOD_COLORS.cinematic
            return (
              <div
                key={t.id}
                className={`bg-white/3 border rounded-xl p-3 transition-all ${
                  isSelected ? 'border-indigo-500/60 bg-indigo-600/10' : 'border-white/10'
                }`}
              >
                <div className="flex items-center gap-3">
                  <button
                    onClick={() => tocarPreview(t)}
                    className={`w-9 h-9 rounded-lg flex items-center justify-center transition-all ${
                      isPlaying
                        ? 'bg-indigo-600 text-white'
                        : 'bg-white/5 text-slate-300 hover:bg-white/10'
                    }`}
                    aria-label={isPlaying ? 'Pausar' : 'Tocar'}
                  >
                    {isPlaying ? <Pause size={14} /> : <Play size={14} className="ml-0.5" />}
                  </button>

                  <div className="flex-1 min-w-0">
                    <p className="text-sm font-medium text-slate-200 truncate">{t.nome}</p>
                    <div className="flex items-center gap-2 mt-0.5">
                      <span className={`text-[9px] px-1.5 py-0.5 rounded-md border bg-gradient-to-r font-semibold uppercase tracking-wide ${moodClasses}`}>
                        {MOOD_LABELS[t.mood] || t.mood}
                      </span>
                      <span className="text-[10px] text-slate-500">{Math.round(t.duracao)}s</span>
                    </div>
                  </div>

                  <button
                    onClick={() => selecionar(t)}
                    className={`px-3 py-1.5 rounded-lg text-xs font-medium transition-all ${
                      isSelected
                        ? 'bg-indigo-600 text-white'
                        : 'bg-white/5 text-slate-300 hover:bg-indigo-600 hover:text-white'
                    }`}
                  >
                    {isSelected ? 'Selecionada' : 'Selecionar'}
                  </button>
                </div>

                {isPlaying && (
                  <div className="mt-2 h-1 bg-white/5 rounded-full overflow-hidden">
                    <div
                      className="h-full bg-indigo-500 transition-all"
                      style={{ width: `${progresso}%` }}
                    />
                  </div>
                )}
              </div>
            )
          })}
        </div>

        {/* Footer info */}
        <div className="px-5 py-3 border-t border-white/8 text-[10px] text-slate-500">
          Preview de até {PREVIEW_DURATION}s. A música mixa no volume baixo do Reel.
        </div>
      </aside>
    </>
  )
}
