// (imagens externas por URL arbitrária: <img> é a escolha correta aqui)
import { useCallback, useRef, useState } from 'react'
import { Image as ImageIcon, Pause, Play, Podcast as PodcastIcon, Volume2 } from 'lucide-react'
import { cn } from '@/lib/utils'
import { RichText } from '@/lib/blocks/richText'
import type { ImageData, VideoData, PodcastData } from '@/lib/blocks/types'
import { BlockRenderProps, formatTime } from './shared'

// ---------- Imagem ----------

export function ImageBlock({ data }: BlockRenderProps<ImageData>) {
  const [failed, setFailed] = useState(false)
  return (
    <figure>
      {data.url && !failed ? (
        <img
          src={data.url}
          alt={data.alt || ''}
          className={cn('mx-auto w-full object-cover', data.rounded && 'rounded-xl')}
          onError={() => setFailed(true)}
          loading="lazy"
        />
      ) : (
        <div
          className={cn(
            'flex h-56 w-full flex-col items-center justify-center gap-2 bg-gradient-to-br from-slate-100 to-slate-200 text-slate-400',
            data.rounded && 'rounded-xl'
          )}
        >
          <ImageIcon className="h-8 w-8" />
          <span className="text-xs">{failed ? 'Não foi possível carregar a imagem' : 'Sem imagem definida'}</span>
        </div>
      )}
      {data.caption?.trim() && (
        <figcaption className="mt-3 text-center text-sm text-slate-500">{data.caption}</figcaption>
      )}
    </figure>
  )
}

// ---------- Vídeo ----------

export function getVideoEmbed(url: string): string | null {
  if (!url) return null
  const yt = url.match(/(?:youtube\.com\/(?:watch\?v=|shorts\/|embed\/)|youtu\.be\/)([\w-]{6,})/)
  if (yt) return `https://www.youtube.com/embed/${yt[1]}`
  const vimeo = url.match(/vimeo\.com\/(?:video\/)?(\d+)/)
  if (vimeo) return `https://player.vimeo.com/video/${vimeo[1]}`
  return null
}

export function VideoBlock({ data, mode }: BlockRenderProps<VideoData>) {
  const embed = getVideoEmbed(data.url)
  return (
    <div>
      {data.title?.trim() && (
        <p className="mb-3 text-base font-semibold text-slate-900">{data.title}</p>
      )}
      {embed ? (
        <div className="relative overflow-hidden rounded-xl bg-slate-900 shadow-sm">
          <div className="aspect-video">
            <iframe
              src={embed}
              title={data.title || 'Vídeo da aula'}
              className="h-full w-full"
              allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
              allowFullScreen
            />
          </div>
          {mode === 'edit' && <div className="absolute inset-0" aria-hidden />}
        </div>
      ) : data.url ? (
        <a
          href={data.url}
          target="_blank"
          rel="noopener noreferrer"
          className="flex items-center gap-3 rounded-xl border border-slate-200 bg-slate-50 p-4 text-sm font-medium text-slate-700 hover:border-slate-300"
        >
          <Play className="h-5 w-5 text-[var(--cpd)]" />
          Abrir vídeo em nova aba
        </a>
      ) : (
        <div className="flex aspect-video w-full flex-col items-center justify-center gap-2 rounded-xl border border-dashed border-slate-300 bg-slate-50 text-slate-400">
          <Play className="h-8 w-8" />
          <span className="text-xs">Adicione a URL de um vídeo do YouTube ou Vimeo</span>
        </div>
      )}
      {data.description?.trim() && (
        <RichText text={data.description} className="mt-3 text-sm leading-relaxed text-slate-500" />
      )}
    </div>
  )
}

// ---------- Podcast ----------

const RATES = [1, 1.5, 2]

// Wrapper: reinicia o player quando a URL do áudio muda (remontagem via key)
export function PodcastBlock(props: BlockRenderProps<PodcastData>) {
  return <PodcastPlayer key={props.data.audioUrl} {...props} />
}

function PodcastPlayer({ data }: BlockRenderProps<PodcastData>) {
  const audioRef = useRef<HTMLAudioElement | null>(null)
  const [playing, setPlaying] = useState(false)
  const [current, setCurrent] = useState(0)
  const [duration, setDuration] = useState(0)
  const [rateIndex, setRateIndex] = useState(0)
  const [failed, setFailed] = useState(false)
  const [coverFailed, setCoverFailed] = useState(false)

  const toggle = useCallback(() => {
    const el = audioRef.current
    if (!el) return
    if (el.paused) {
      void el.play()
    } else {
      el.pause()
    }
  }, [])

  const seek = useCallback((e: React.MouseEvent<HTMLDivElement>) => {
    const el = audioRef.current
    if (!el || !Number.isFinite(el.duration)) return
    const rect = e.currentTarget.getBoundingClientRect()
    const ratio = Math.min(1, Math.max(0, (e.clientX - rect.left) / rect.width))
    el.currentTime = ratio * el.duration
    setCurrent(el.currentTime)
  }, [])

  const cycleRate = useCallback(() => {
    const next = (rateIndex + 1) % RATES.length
    setRateIndex(next)
    if (audioRef.current) audioRef.current.playbackRate = RATES[next]
  }, [rateIndex])

  return (
    <div className="overflow-hidden rounded-2xl border border-slate-200 bg-white shadow-sm">
      <div className="flex flex-col gap-4 p-5 sm:flex-row sm:items-start md:p-6">
        {data.coverUrl && !coverFailed ? (
          <img
            src={data.coverUrl}
            alt={data.title ? `Capa de ${data.title}` : 'Capa do podcast'}
            className="h-24 w-24 shrink-0 rounded-xl object-cover"
            onError={() => setCoverFailed(true)}
          />
        ) : (
          <div
            className="flex h-24 w-24 shrink-0 items-center justify-center rounded-xl text-white"
            style={{ background: 'var(--cg)' }}
            aria-hidden
          >
            <PodcastIcon className="h-9 w-9" />
          </div>
        )}
        <div className="min-w-0 flex-1">
          <p className="text-xs font-bold tracking-widest text-[var(--cpd)] uppercase">Podcast</p>
          <h4 className="mt-1 text-lg leading-snug font-bold text-slate-900">{data.title || 'Episódio sem título'}</h4>
          {data.speaker && <p className="mt-0.5 text-sm font-medium text-slate-500">{data.speaker}</p>}
          {data.description?.trim() && (
            <RichText text={data.description} className="mt-2 text-sm leading-relaxed text-slate-600" />
          )}
        </div>
      </div>

      <div className="border-t border-slate-100 bg-slate-50/70 px-5 py-4 md:px-6">
        {data.audioUrl && !failed ? (
          <div className="flex items-center gap-4">
            <button
              type="button"
              onClick={toggle}
              className="flex h-11 w-11 shrink-0 items-center justify-center rounded-full text-white shadow-sm transition-transform hover:scale-105 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2"
              style={{ backgroundColor: 'var(--cp)' }}
              aria-label={playing ? 'Pausar' : 'Reproduzir'}
            >
              {playing ? <Pause className="h-5 w-5" /> : <Play className="ml-0.5 h-5 w-5" />}
            </button>

            <div className="min-w-0 flex-1">
              <div
                className="group h-2 w-full cursor-pointer rounded-full bg-slate-200"
                onClick={seek}
                role="progressbar"
                aria-label="Progresso do áudio"
                aria-valuenow={Math.round(current)}
                aria-valuemin={0}
                aria-valuemax={Math.round(duration)}
              >
                <div
                  className="h-full rounded-full transition-[width] duration-150"
                  style={{
                    width: `${duration > 0 ? (current / duration) * 100 : 0}%`,
                    backgroundColor: 'var(--cp)',
                  }}
                />
              </div>
              <div className="mt-1.5 flex items-center justify-between text-xs tabular-nums text-slate-500">
                <span>{formatTime(current)}</span>
                <span>{duration > 0 ? formatTime(duration) : '—:—'}</span>
              </div>
            </div>

            <button
              type="button"
              onClick={cycleRate}
              className="shrink-0 rounded-full border border-slate-300 bg-white px-2.5 py-1 text-xs font-semibold text-slate-600 hover:border-slate-400 focus-visible:outline-none focus-visible:ring-2"
              aria-label="Velocidade de reprodução"
            >
              {RATES[rateIndex]}x
            </button>
          </div>
        ) : (
          <p className="flex items-center gap-2 text-sm text-slate-400">
            <Volume2 className="h-4 w-4" />
            {failed ? 'Não foi possível carregar o áudio desta URL.' : 'Adicione a URL do áudio (mp3).'}
          </p>
        )}

        <audio
          ref={audioRef}
          src={data.audioUrl || undefined}
          preload="metadata"
          onPlay={() => setPlaying(true)}
          onPause={() => setPlaying(false)}
          onEnded={() => setPlaying(false)}
          onTimeUpdate={(e) => setCurrent(e.currentTarget.currentTime)}
          onLoadedMetadata={(e) => setDuration(e.currentTarget.duration)}
          onError={() => setFailed(true)}
          className="hidden"
        />
      </div>
    </div>
  )
}
