import { useRef, useState, useEffect, memo } from 'react'
import { useTheme } from '@/contexts/ThemeContext'
import WaveformPlayer from '@arraypress/waveform-player'
import '@arraypress/waveform-player/dist/waveform-player.css'
import { Button } from '@/components/ui/button'
import { X, Loader2 } from 'lucide-react'
import apiClient from '@/lib/api'
import { audiobookApi, type AudiobookSegment } from '@/lib/api/audiobook'
import styles from './ChapterPlayer.module.css'

interface TimelineItem {
  seg: AudiobookSegment
  startTime: number
  endTime: number
}

const ChapterPlayer = memo(({
  projectId,
  chapterIndex,
  chapterTitle,
  segments,
  onClose,
}: {
  projectId: number
  chapterIndex: number
  chapterTitle: string
  segments: AudiobookSegment[]
  onClose: () => void
}) => {
  const { theme } = useTheme()
  const [blobUrl, setBlobUrl] = useState<string>('')
  const [isLoadingChapter, setIsLoadingChapter] = useState(true)
  const [isLoadingTimeline, setIsLoadingTimeline] = useState(false)
  const [currentSeg, setCurrentSeg] = useState<AudiobookSegment | null>(null)

  const containerRef = useRef<HTMLDivElement>(null)
  const playerRef = useRef<WaveformPlayer | null>(null)
  const timelineRef = useRef<TimelineItem[]>([])
  const blobUrlRef = useRef<string>('')

  const doneSegs = segments.filter(s => s.status === 'done')
  const doneSegIds = doneSegs.map(s => s.id).join(',')

  useEffect(() => {
    let active = true
    setIsLoadingChapter(true)
    setCurrentSeg(null)
    timelineRef.current = []

    if (blobUrlRef.current) {
      URL.revokeObjectURL(blobUrlRef.current)
      blobUrlRef.current = ''
      setBlobUrl('')
    }

    apiClient.get(audiobookApi.getDownloadUrl(projectId, chapterIndex), { responseType: 'blob' })
      .then(res => {
        if (!active) return
        const url = URL.createObjectURL(res.data)
        blobUrlRef.current = url
        setBlobUrl(url)
        setIsLoadingChapter(false)
      })
      .catch(() => {
        if (active) setIsLoadingChapter(false)
      })

    return () => { active = false }
  }, [projectId, chapterIndex])

  useEffect(() => {
    if (!doneSegIds) return
    let active = true
    setIsLoadingTimeline(true)
    timelineRef.current = []

    const build = async () => {
      let cumTime = 0
      const result: TimelineItem[] = []
      for (const seg of doneSegs) {
        if (!active) break
        try {
          const res = await apiClient.get(
            audiobookApi.getSegmentAudioUrl(projectId, seg.id),
            { responseType: 'blob' }
          )
          const url = URL.createObjectURL(res.data)
          const duration = await new Promise<number>(resolve => {
            const a = new Audio(url)
            a.addEventListener('loadedmetadata', () => { URL.revokeObjectURL(url); resolve(a.duration || 0) })
            a.addEventListener('error', () => { URL.revokeObjectURL(url); resolve(0) })
          })
          result.push({ seg, startTime: cumTime, endTime: cumTime + duration })
          cumTime += duration
        } catch {
          result.push({ seg, startTime: cumTime, endTime: cumTime + 1 })
          cumTime += 1
        }
      }
      if (active) {
        timelineRef.current = result
        setIsLoadingTimeline(false)
      }
    }

    build()
    return () => { active = false }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [doneSegIds, projectId])

  useEffect(() => {
    if (!containerRef.current || !blobUrl) return

    if (playerRef.current) {
      playerRef.current.destroy()
      playerRef.current = null
    }

    const waveformColor = theme === 'dark' ? '#4b5563' : '#d1d5db'
    const progressColor = '#f97316'

    const player = new WaveformPlayer(containerRef.current, {
      url: blobUrl,
      waveformStyle: 'mirror',
      height: 56,
      barWidth: 2,
      barSpacing: 1,
      samples: 260,
      waveformColor,
      progressColor,
      showTime: true,
      showPlaybackSpeed: false,
      autoplay: false,
      enableMediaSession: true,
      onTimeUpdate: (ct: number) => {
        const tl = timelineRef.current
        const item = tl.find(t => ct >= t.startTime && ct < t.endTime)
        setCurrentSeg(item?.seg ?? null)
      },
    })
    playerRef.current = player

    setTimeout(() => {
      containerRef.current?.querySelectorAll('button').forEach(btn => {
        if (!btn.hasAttribute('type')) btn.setAttribute('type', 'button')
      })
    }, 0)

    return () => {
      if (playerRef.current) {
        playerRef.current.destroy()
        playerRef.current = null
      }
    }
  }, [blobUrl, theme])

  useEffect(() => {
    return () => {
      if (blobUrlRef.current) URL.revokeObjectURL(blobUrlRef.current)
    }
  }, [])

  return (
    <div className={styles.panel}>
      <div className={styles.header}>
        <span className={styles.title}>正在播放</span>
        <span className={styles.chapterName}>{chapterTitle}</span>
        {isLoadingTimeline && !isLoadingChapter && (
          <span className="inline-flex items-center gap-1 text-[11px] text-muted-foreground shrink-0 ml-auto">
            <Loader2 className="h-2.5 w-2.5 animate-spin" />字幕轨道加载中…
          </span>
        )}
        <Button type="button" size="icon" variant="ghost" className="h-5 w-5 shrink-0" onClick={onClose}>
          <X className="h-3 w-3" />
        </Button>
      </div>

      {isLoadingChapter ? (
        <div className="flex items-center gap-2 text-xs text-muted-foreground py-3">
          <Loader2 className="h-3 w-3 animate-spin" />合并音频中…
        </div>
      ) : (
        <>
          <div className={styles.waveformWrapper}>
            <div ref={containerRef} className={styles.waveformInner} />
          </div>
          {currentSeg && (
            <div className={styles.subtitle}>
              <span className={styles.subtitleName}>{currentSeg.character_name || '旁白'}</span>
              <span className={styles.subtitleText}>{currentSeg.text}</span>
            </div>
          )}
        </>
      )}
    </div>
  )
})
ChapterPlayer.displayName = 'ChapterPlayer'
export { ChapterPlayer }
