'use client'

import { useState, useEffect, useRef, Suspense } from 'react'
import { useSearchParams } from 'next/navigation'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { JefflixLogo } from '@/components/jefflix-logo'
import { SongRow } from '@/components/music/search-results'
import { useMusicPlayer, type Track } from '@/components/music/music-provider'
import { MusicBrainzResultsSection } from '@/components/music/musicbrainz-results'
import { useOffline } from '@/lib/stores/offline'
import { Search, Music, Download, Loader2, ArrowLeft, AlertCircle, ListMusic, ChevronRight, ChevronDown, WifiOff, Users, DownloadCloud, CheckCircle } from 'lucide-react'
import Link from 'next/link'

interface Playlist {
  id: string
  name: string
  songCount: number
  coverArt: string
}

interface SlskdFile {
  displayName: string
  filename: string
  size: number
  bitRate: number
  length: number
  bestPeer: {
    username: string
    freeSlots: number
    speed: number
  }
  peerCount: number
}

export default function MusicPage() {
  return (
    <Suspense>
      <MusicPageInner />
    </Suspense>
  )
}

function MusicPageInner() {
  const searchParams = useSearchParams()
  const { state } = useMusicPlayer()
  const { offlineIds, download: downloadTrack } = useOffline()
  const [query, setQuery] = useState(() => searchParams.get('q') || '')
  const [debouncedQuery, setDebouncedQuery] = useState('')
  const [songs, setSongs] = useState<Track[]>([])
  const [searching, setSearching] = useState(false)
  const [searchError, setSearchError] = useState('')
  const debounceRef = useRef<NodeJS.Timeout>(null)

  // Playlist browsing state
  const [playlists, setPlaylists] = useState<Playlist[]>([])
  const [playlistsLoading, setPlaylistsLoading] = useState(true)
  const [expandedPlaylist, setExpandedPlaylist] = useState<string | null>(null)
  const [playlistSongs, setPlaylistSongs] = useState<Track[]>([])
  const [playlistSongsLoading, setPlaylistSongsLoading] = useState(false)

  // Soulseek state
  const [slskMode, setSlskMode] = useState(false)
  const [slskSearchId, setSlskSearchId] = useState<string | null>(null)
  const [slskResults, setSlskResults] = useState<SlskdFile[]>([])
  const [slskSearching, setSlskSearching] = useState(false)
  const [downloading, setDownloading] = useState<string | null>(null)
  const pollRef = useRef<NodeJS.Timeout>(null)

  // Fetch playlists on mount
  useEffect(() => {
    fetch('/api/music/playlists')
      .then((r) => r.json())
      .then((d) => setPlaylists(d.playlists || []))
      .catch(() => {})
      .finally(() => setPlaylistsLoading(false))
  }, [])

  const togglePlaylist = async (id: string) => {
    if (expandedPlaylist === id) {
      setExpandedPlaylist(null)
      setPlaylistSongs([])
      return
    }
    setExpandedPlaylist(id)
    setPlaylistSongsLoading(true)
    try {
      const res = await fetch(`/api/music/playlist/${id}`)
      const d = await res.json()
      setPlaylistSongs(d.songs || [])
    } catch {
      setPlaylistSongs([])
    }
    setPlaylistSongsLoading(false)
  }

  // Debounced Navidrome search
  useEffect(() => {
    if (slskMode) return
    debounceRef.current = setTimeout(() => setDebouncedQuery(query), 300)
    return () => { if (debounceRef.current) clearTimeout(debounceRef.current) }
  }, [query, slskMode])

  useEffect(() => {
    if (!debouncedQuery || debouncedQuery.length < 2 || slskMode) {
      setSongs([])
      return
    }

    setSearching(true)
    setSearchError('')
    fetch(`/api/music/search?q=${encodeURIComponent(debouncedQuery)}`)
      .then((r) => r.json())
      .then((d) => {
        if (d.error) throw new Error(d.error)
        setSongs(d.songs || [])
      })
      .catch((e) => setSearchError(e.message))
      .finally(() => setSearching(false))
  }, [debouncedQuery, slskMode])

  // Cleanup slskd polling on unmount
  useEffect(() => {
    return () => { if (pollRef.current) clearTimeout(pollRef.current) }
  }, [])

  const searchSoulseek = async () => {
    setSlskMode(true)
    setSlskSearching(true)
    setSlskResults([])

    try {
      const res = await fetch('/api/music/slskd/search', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ query: query || debouncedQuery }),
      })
      const d = await res.json()
      if (d.error) throw new Error(d.error)
      setSlskSearchId(d.searchId)
      pollSlskResults(d.searchId)
    } catch {
      setSlskSearching(false)
    }
  }

  const pollSlskResults = (searchId: string) => {
    const poll = async () => {
      try {
        const res = await fetch(`/api/music/slskd/results/${searchId}`)
        const d = await res.json()
        setSlskResults(d.files || [])
        if (!d.isComplete) {
          pollRef.current = setTimeout(poll, 2000)
        } else {
          setSlskSearching(false)
        }
      } catch {
        setSlskSearching(false)
      }
    }
    poll()
  }

  const triggerDownload = async (file: SlskdFile) => {
    const key = `${file.bestPeer.username}:${file.filename}`
    setDownloading(key)
    try {
      await fetch('/api/music/slskd/download', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          username: file.bestPeer.username,
          files: [{ filename: file.filename, size: file.size }],
        }),
      })
    } catch {}
    setDownloading(null)
  }

  const exitSlsk = () => {
    setSlskMode(false)
    setSlskSearchId(null)
    setSlskResults([])
    setSlskSearching(false)
    if (pollRef.current) clearTimeout(pollRef.current)
  }

  const hasPlayer = !!state.currentTrack

  return (
    <div className={`min-h-screen bg-background ${hasPlayer ? 'pb-20' : ''}`}>
      {/* Header */}
      <div className="border-b border-border">
        <div className="container mx-auto px-4 py-4 flex items-center justify-between">
          <Link href="/" className="inline-block">
            <JefflixLogo size="small" />
          </Link>
          <div className="flex items-center gap-2">
            <Link href="/offline">
              <Button variant="ghost" size="sm">
                <WifiOff className="h-4 w-4 mr-1.5" />
                Offline
              </Button>
            </Link>
            <Link href="/">
              <Button variant="ghost" size="sm">
                <ArrowLeft className="h-4 w-4 mr-1.5" />
                Home
              </Button>
            </Link>
          </div>
        </div>
      </div>

      {/* Main */}
      <div className="container mx-auto px-4 py-12 md:py-16">
        <div className="max-w-2xl mx-auto">
          {/* Hero */}
          <div className="text-center space-y-4 mb-8">
            <div className="inline-block p-4 bg-purple-100 dark:bg-purple-900/30 rounded-full">
              <Music className="h-10 w-10 text-purple-600 dark:text-purple-400" />
            </div>
            <h1 className="text-3xl font-bold font-marker">Music</h1>
            <p className="text-muted-foreground">
              Search the library, play songs, and manage playlists.
            </p>
          </div>

          {/* Search */}
          <div className="relative mb-6">
            <Search className="absolute left-4 top-1/2 -translate-y-1/2 h-5 w-5 text-muted-foreground" />
            <input
              type="text"
              value={query}
              onChange={(e) => { setQuery(e.target.value); if (slskMode) exitSlsk() }}
              className="w-full pl-12 pr-4 py-3 rounded-lg border border-border bg-background focus:outline-none focus:ring-2 focus:ring-purple-500"
              placeholder="Search songs, artists, albums..."
              autoFocus
            />
          </div>

          {/* Soulseek mode toggle */}
          {slskMode && (
            <div className="flex items-center gap-2 mb-4">
              <Badge className="bg-yellow-600 text-white">Soulseek</Badge>
              <span className="text-sm text-muted-foreground">Searching peer-to-peer network</span>
              <button onClick={exitSlsk} className="text-sm text-primary hover:underline ml-auto">
                Back to Library
              </button>
            </div>
          )}

          {/* Navidrome Results */}
          {!slskMode && (
            <>
              {searching && (
                <div className="flex justify-center py-8">
                  <Loader2 className="h-6 w-6 animate-spin text-purple-600" />
                </div>
              )}

              {searchError && (
                <div className="flex items-center gap-2 p-4 bg-red-100 dark:bg-red-900/30 rounded-lg text-red-600 dark:text-red-400">
                  <AlertCircle className="h-5 w-5 flex-shrink-0" />
                  <p className="text-sm">{searchError}</p>
                </div>
              )}

              {!searching && songs.length > 0 && (
                <div className="border border-border rounded-lg divide-y divide-border overflow-hidden">
                  {songs.map((song, i) => (
                    <SongRow key={song.id} song={song} songs={songs} index={i} showDownload />
                  ))}
                </div>
              )}

              {!searching && debouncedQuery.length >= 2 && songs.length === 0 && !searchError && (
                <div className="text-center py-8 space-y-4">
                  <p className="text-muted-foreground">
                    No results for &ldquo;{debouncedQuery}&rdquo; in the library
                  </p>
                  <Button
                    onClick={searchSoulseek}
                    className="bg-yellow-600 hover:bg-yellow-700 text-white"
                  >
                    <Download className="h-4 w-4 mr-1.5" />
                    Search Soulseek
                  </Button>
                </div>
              )}

              {query.length > 0 && query.length < 2 && (
                <p className="text-sm text-muted-foreground text-center">
                  Type at least 2 characters to search
                </p>
              )}

              {/* MusicBrainz Discovery */}
              {debouncedQuery.length >= 2 && (
                <MusicBrainzResultsSection query={debouncedQuery} />
              )}
            </>
          )}

          {/* Soulseek Results */}
          {slskMode && (
            <>
              {slskSearching && slskResults.length === 0 && (
                <div className="flex flex-col items-center gap-2 py-8">
                  <Loader2 className="h-6 w-6 animate-spin text-yellow-600" />
                  <p className="text-sm text-muted-foreground">Searching peer-to-peer network...</p>
                </div>
              )}

              {slskResults.length > 0 && (
                <div className="space-y-1">
                  {slskSearching && (
                    <div className="flex items-center gap-2 text-sm text-muted-foreground mb-2">
                      <Loader2 className="h-3.5 w-3.5 animate-spin" />
                      Still searching...
                    </div>
                  )}

                  <div className="border border-border rounded-lg divide-y divide-border overflow-hidden">
                    {slskResults.map((file) => {
                      const sizeMB = (file.size / 1024 / 1024).toFixed(1)
                      const key = `${file.bestPeer.username}:${file.filename}`

                      return (
                        <div key={key} className="flex items-center gap-3 px-4 py-3">
                          <div className="flex-1 min-w-0">
                            <div className="text-sm font-medium truncate">{file.displayName}</div>
                            <div className="text-xs text-muted-foreground">
                              {sizeMB} MB
                              {file.bitRate > 0 && ` · ${file.bitRate} kbps`}
                              {' · '}{file.bestPeer.username}
                            </div>
                          </div>
                          {file.peerCount > 1 && (
                            <Badge variant="secondary" className="text-[10px] px-1.5 py-0 flex-shrink-0">
                              <Users className="h-3 w-3 mr-0.5" />
                              {file.peerCount}
                            </Badge>
                          )}
                          <Button
                            size="sm"
                            variant="outline"
                            onClick={() => triggerDownload(file)}
                            disabled={downloading === key}
                          >
                            {downloading === key ? (
                              <Loader2 className="h-3.5 w-3.5 animate-spin" />
                            ) : (
                              <Download className="h-3.5 w-3.5" />
                            )}
                          </Button>
                        </div>
                      )
                    })}
                  </div>
                </div>
              )}

              {!slskSearching && slskResults.length === 0 && slskSearchId && (
                <p className="text-center text-muted-foreground py-8">
                  No results found on Soulseek
                </p>
              )}
            </>
          )}

          {/* Playlists - shown when not searching */}
          {!slskMode && !debouncedQuery && (
            <div className="mt-8">
              <h2 className="text-lg font-bold flex items-center gap-2 mb-4">
                <ListMusic className="h-5 w-5 text-purple-600 dark:text-purple-400" />
                Playlists
              </h2>

              {playlistsLoading ? (
                <div className="flex justify-center py-8">
                  <Loader2 className="h-6 w-6 animate-spin text-purple-600" />
                </div>
              ) : playlists.length === 0 ? (
                <p className="text-sm text-muted-foreground text-center py-8">
                  No playlists yet
                </p>
              ) : (
                <div className="border border-border rounded-lg divide-y divide-border overflow-hidden">
                  {playlists.map((p) => {
                    // Check how many songs in this playlist are already offline
                    const allOffline = expandedPlaylist === p.id && playlistSongs.length > 0 &&
                      playlistSongs.every((s) => offlineIds.has(s.id))

                    return (
                    <div key={p.id}>
                      <div className="flex items-center hover:bg-muted/50 transition-colors">
                        <button
                          onClick={() => togglePlaylist(p.id)}
                          className="flex-1 flex items-center gap-3 px-4 py-3 text-left"
                        >
                          <div className="flex-shrink-0 w-12 h-12 rounded overflow-hidden bg-muted">
                            {p.coverArt ? (
                              <img
                                src={`/api/music/cover/${p.coverArt}?size=96`}
                                alt={p.name}
                                className="w-full h-full object-cover"
                                loading="lazy"
                              />
                            ) : (
                              <div className="w-full h-full flex items-center justify-center">
                                <ListMusic className="h-5 w-5 text-muted-foreground" />
                              </div>
                            )}
                          </div>
                          <div className="flex-1 min-w-0">
                            <div className="font-medium text-sm truncate">{p.name}</div>
                            <div className="text-xs text-muted-foreground">{p.songCount} songs</div>
                          </div>
                          {expandedPlaylist === p.id ? (
                            <ChevronDown className="h-4 w-4 text-muted-foreground flex-shrink-0" />
                          ) : (
                            <ChevronRight className="h-4 w-4 text-muted-foreground flex-shrink-0" />
                          )}
                        </button>
                        {/* Download entire playlist */}
                        {expandedPlaylist === p.id && playlistSongs.length > 0 && (
                          <button
                            onClick={(e) => {
                              e.stopPropagation()
                              playlistSongs.forEach((s) => {
                                if (!offlineIds.has(s.id)) downloadTrack(s)
                              })
                            }}
                            className={`p-2 mr-2 rounded-full transition-colors flex-shrink-0 ${
                              allOffline
                                ? 'text-green-500'
                                : 'text-muted-foreground hover:text-foreground hover:bg-muted/50'
                            }`}
                            title={allOffline ? 'All songs downloaded' : 'Download all for offline'}
                            disabled={allOffline}
                          >
                            {allOffline ? (
                              <CheckCircle className="h-5 w-5" />
                            ) : (
                              <DownloadCloud className="h-5 w-5" />
                            )}
                          </button>
                        )}
                      </div>

                      {expandedPlaylist === p.id && (
                        <div className="bg-muted/30 border-t border-border">
                          {playlistSongsLoading ? (
                            <div className="flex justify-center py-6">
                              <Loader2 className="h-5 w-5 animate-spin text-muted-foreground" />
                            </div>
                          ) : playlistSongs.length === 0 ? (
                            <p className="text-sm text-muted-foreground text-center py-6">
                              Empty playlist
                            </p>
                          ) : (
                            <div className="divide-y divide-border">
                              {playlistSongs.map((song, i) => (
                                <SongRow key={song.id} song={song} songs={playlistSongs} index={i} showDownload />
                              ))}
                            </div>
                          )}
                        </div>
                      )}
                    </div>
                  )})}
                </div>
              )}
            </div>
          )}

          {/* Info */}
          <div className="mt-12 p-6 bg-muted/50 rounded-lg space-y-3">
            <h3 className="font-bold mb-2">How does this work?</h3>
            <p className="text-sm text-muted-foreground">
              This searches your Navidrome music library. Songs play directly in the browser through a
              persistent audio player. Can&apos;t find what you&apos;re looking for? Search Soulseek to find
              and download music from the peer-to-peer network.
            </p>
          </div>
        </div>
      </div>
    </div>
  )
}
