import {
  Play,
  Pause,
  SkipBack,
  SkipForward,
  Shuffle,
  Repeat,
  Repeat1,
  ListMusic,
  ChevronUp,
  Volume2,
  VolumeX,
  Heart,
} from '../../lib/icons'
import { motion, AnimatePresence } from 'framer-motion'
import { useMusicStore } from '../../stores/music-store'
import { getBestImage, getStoredServerUrl } from '../../api/jellyfin'

interface MiniPlayerProps {
  onExpand: () => void
}

export default function MiniPlayer({ onExpand }: MiniPlayerProps) {
  const {
    currentTrack,
    isPlaying,
    currentTime,
    duration,
    shuffle,
    repeat,
    volume,
    isMuted,
    pause,
    resume,
    nextTrack,
    prevTrack,
    toggleShuffle,
    cycleRepeat,
    toggleMute,
    setVolume,
    seekTo,
  } = useMusicStore()

  const serverUrl = getStoredServerUrl()

  const imageUrl = currentTrack
    ? getBestImage(serverUrl, currentTrack, 'primary', 120)
    : ''

  const title = currentTrack?.Name || 'Unknown track'
  const artist = currentTrack?.AlbumArtist || currentTrack?.Artists?.[0] || ''

  const playedPercent = duration > 0 ? (currentTime / duration) * 100 : 0

  function formatTime(s: number): string {
    if (!s || !isFinite(s)) return '0:00'
    const m = Math.floor(s / 60)
    const sec = Math.floor(s % 60)
    return `${m}:${sec.toString().padStart(2, '0')}`
  }

  const RepeatIcon = repeat === 'one' ? Repeat1 : Repeat
  const VolIcon = isMuted || volume === 0 ? VolumeX : Volume2

  return (
    <AnimatePresence>
      {currentTrack && (
        <motion.div
          initial={{ y: 80, opacity: 0 }}
          animate={{ y: 0, opacity: 1 }}
          exit={{ y: 80, opacity: 0 }}
          transition={{ duration: 0.36, ease: [0.16, 1, 0.3, 1] }}
          className="relative shrink-0 z-mini-player"
        >
          {/* Top progress sliver - clickable */}
          <ProgressSliver
            playedPercent={playedPercent}
            onSeek={seekTo}
            duration={duration}
          />

          <div className="h-[72px] glass-strong border-t border-border flex items-center px-5 gap-4">
            {/* Left: Art + Info */}
            <button
              onClick={onExpand}
              className="group flex items-center gap-3 min-w-0 w-[260px] focus-ring rounded-lg p-1 -m-1"
            >
              <div className="relative w-12 h-12 shrink-0">
                <div className="absolute inset-0 rounded-md overflow-hidden bg-elevated ring-1 ring-border">
                  {imageUrl ? (
                    <img src={imageUrl} alt="" className="w-full h-full object-cover" />
                  ) : (
                    <div className="w-full h-full grid place-items-center text-text-3">
                      <ListMusic size={18} />
                    </div>
                  )}
                </div>
                {/* Hover affordance */}
                <div className="absolute inset-0 rounded-md grid place-items-center bg-black/45 opacity-0 group-hover:opacity-100 transition-opacity duration-150">
                  <ChevronUp size={16} className="text-white" />
                </div>
              </div>
              <div className="min-w-0 text-left">
                <p className="text-[13px] font-medium text-text-1 truncate tracking-tight">{title}</p>
                <p className="text-[11.5px] text-text-3 truncate">{artist || 'Unknown artist'}</p>
              </div>
            </button>

            {/* Center: Transport */}
            <div className="flex-1 flex flex-col items-center max-w-2xl gap-1">
              <div className="flex items-center gap-2.5">
                <TransportButton
                  onClick={toggleShuffle}
                  active={shuffle}
                  aria-label={shuffle ? 'Disable shuffle' : 'Enable shuffle'}
                >
                  <Shuffle size={14} />
                </TransportButton>
                <TransportButton onClick={prevTrack} aria-label="Previous track">
                  <SkipBack size={16} fill="currentColor" />
                </TransportButton>

                {/* Play/Pause */}
                <button
                  onClick={isPlaying ? pause : resume}
                  className="relative w-9 h-9 rounded-full bg-text-1 text-void grid place-items-center transition-all duration-150 hover:scale-105 active:scale-95 focus-ring"
                  aria-label={isPlaying ? 'Pause' : 'Play'}
                >
                  {isPlaying ? (
                    <Pause size={15} fill="currentColor" />
                  ) : (
                    <Play size={15} fill="currentColor" className="translate-x-0.5" />
                  )}
                </button>

                <TransportButton onClick={nextTrack} aria-label="Next track">
                  <SkipForward size={16} fill="currentColor" />
                </TransportButton>
                <TransportButton
                  onClick={cycleRepeat}
                  active={repeat !== 'off'}
                  aria-label={`Repeat: ${repeat}`}
                >
                  <RepeatIcon size={14} />
                </TransportButton>
              </div>

              {/* Inline scrubber */}
              <div className="w-full flex items-center gap-2.5 text-[10px] text-text-3 tabular-nums">
                <span className="w-9 text-right">{formatTime(currentTime)}</span>
                <Scrubber
                  playedPercent={playedPercent}
                  onSeek={(pct) => seekTo(pct * duration)}
                />
                <span className="w-9">{formatTime(duration)}</span>
              </div>
            </div>

            {/* Right: Volume + Queue */}
            <div className="flex items-center gap-1 shrink-0">
              <TransportButton
                onClick={() => {
                  if (currentTrack && currentTrack.UserData) {
                    // local optimistic - UI only
                  }
                }}
                aria-label="Favorite"
              >
                <Heart
                  size={15}
                  className={currentTrack?.UserData?.IsFavorite ? 'text-accent' : ''}
                  fill={currentTrack?.UserData?.IsFavorite ? 'currentColor' : 'none'}
                />
              </TransportButton>

              {/* Volume control */}
              <div className="group/vol flex items-center">
                <TransportButton onClick={toggleMute} aria-label={isMuted ? 'Unmute' : 'Mute'}>
                  <VolIcon size={15} />
                </TransportButton>
                <div className="w-0 group-hover/vol:w-24 transition-all duration-300 ease-out overflow-hidden">
                  <input
                    type="range"
                    min={0}
                    max={1}
                    step={0.01}
                    value={isMuted ? 0 : volume}
                    onChange={e => setVolume(Number(e.target.value))}
                    className="slider w-22 ml-1"
                    aria-label="Volume"
                  />
                </div>
              </div>

              <button
                onClick={onExpand}
                className="ml-1 w-9 h-9 grid place-items-center rounded-md text-text-3 hover:text-text-1 hover:bg-glass-light transition-colors focus-ring"
                aria-label="Expand player"
              >
                <ChevronUp size={17} />
              </button>
            </div>
          </div>
        </motion.div>
      )}
    </AnimatePresence>
  )
}

function TransportButton({
  active,
  children,
  ...props
}: React.ButtonHTMLAttributes<HTMLButtonElement> & { active?: boolean }) {
  return (
    <button
      {...props}
      className={`w-8 h-8 grid place-items-center rounded-md transition-all duration-150 hover:bg-glass-light focus-ring ${
        active ? 'text-accent' : 'text-text-2 hover:text-text-1'
      }`}
    >
      {children}
    </button>
  )
}

function Scrubber({
  playedPercent,
  onSeek,
}: {
  playedPercent: number
  onSeek: (pct: number) => void
}) {
  function handleClick(e: React.MouseEvent<HTMLDivElement>) {
    const rect = e.currentTarget.getBoundingClientRect()
    const pct = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width))
    onSeek(pct)
  }

  return (
    <div
      onClick={handleClick}
      className="relative flex-1 h-3 cursor-pointer group/scrub"
    >
      <div className="absolute left-0 right-0 top-1/2 -translate-y-1/2 h-[3px] group-hover/scrub:h-1.5 rounded-full bg-white/10 transition-all duration-150 overflow-hidden">
        <div
          className="absolute left-0 top-0 bottom-0 bg-accent rounded-full"
          style={{ width: `${playedPercent}%` }}
        />
      </div>
      <div
        className="absolute top-1/2 -translate-y-1/2 -translate-x-1/2 w-3 h-3 rounded-full bg-accent shadow-[0_0_8px_rgba(245,182,66,0.6)] opacity-0 group-hover/scrub:opacity-100 transition-opacity duration-150 pointer-events-none"
        style={{ left: `${playedPercent}%` }}
      />
    </div>
  )
}

function ProgressSliver({
  playedPercent,
  onSeek,
  duration,
}: {
  playedPercent: number
  onSeek: (time: number) => void
  duration: number
}) {
  function handleClick(e: React.MouseEvent<HTMLDivElement>) {
    const rect = e.currentTarget.getBoundingClientRect()
    const pct = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width))
    onSeek(pct * duration)
  }
  return (
    <div
      onClick={handleClick}
      className="absolute left-0 right-0 -top-px h-0.5 cursor-pointer group/sliver hover:h-1 transition-all duration-150"
    >
      <div className="w-full h-full bg-white/5">
        <div
          className="h-full bg-accent transition-all duration-100"
          style={{ width: `${playedPercent}%` }}
        />
      </div>
    </div>
  )
}
