"use client";

import Link from "next/link";
import { useEffect, useRef, useState } from "react";
import { useAudio } from "./AudioContext";

function PlaybarInner({ currentSong }: { currentSong: any }) {
  const { isPlaying, audioRef, togglePlayPause } = useAudio();
  const [currentTime, setCurrentTime] = useState(0);
  const [duration, setDuration] = useState(0);
  const [waveform, setWaveform] = useState<number[] | null>(null);
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const [isSeeking, setIsSeeking] = useState(false);
  const [isLoading, setIsLoading] = useState(false);

  // Fetch/generate waveform data when song changes
  useEffect(() => {
    if (!currentSong || !currentSong.audio_url) {
      setWaveform(null);
      return;
    }
    let cancelled = false;
    async function getWaveform() {
      try {
        const ctx = new (window.AudioContext ||
          (window as any).webkitAudioContext)();
        const res = await fetch(currentSong.audio_url);
        const arrayBuffer = await res.arrayBuffer();
        const audioBuffer = await ctx.decodeAudioData(arrayBuffer);
        const raw = audioBuffer.getChannelData(0);
        const samples = 80;
        const blockSize = Math.floor(raw.length / samples);
        const waveformData = Array(samples)
          .fill(0)
          .map((_, i) => {
            let sum = 0;
            for (let j = 0; j < blockSize; j++) {
              sum += Math.abs(raw[i * blockSize + j] || 0);
            }
            return sum / blockSize;
          });
        if (!cancelled) setWaveform(waveformData);
      } catch (e) {
        setWaveform(null);
      }
    }
    getWaveform();
    return () => {
      cancelled = true;
    };
  }, [currentSong?.audio_url]);

  // Sync current time and duration
  useEffect(() => {
    const audio = audioRef.current;
    if (!audio) return;
    const updateTime = () => setCurrentTime(audio.currentTime);
    const updateDuration = () => setDuration(audio.duration);
    const handleLoadStart = () => setIsLoading(true);
    const handleLoadedMetadata = () => setIsLoading(false);
    audio.addEventListener("timeupdate", updateTime);
    audio.addEventListener("loadedmetadata", updateDuration);
    audio.addEventListener("loadstart", handleLoadStart);
    audio.addEventListener("loadedmetadata", handleLoadedMetadata);
    return () => {
      audio.removeEventListener("timeupdate", updateTime);
      audio.removeEventListener("loadedmetadata", updateDuration);
      audio.removeEventListener("loadstart", handleLoadStart);
      audio.removeEventListener("loadedmetadata", handleLoadedMetadata);
    };
  }, [audioRef]);

  // Helper: is duration unknown/streaming?
  const isStreaming = !duration || isNaN(duration) || duration === Infinity;
  const seekDuration = isStreaming ? 240 : duration; // 4min fallback

  // Draw waveform (mirrored and full height)
  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas || !waveform) return;
    const ctx = canvas.getContext("2d");
    if (!ctx) return;
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    const w = canvas.width;
    const h = canvas.height;
    const barWidth = w / waveform.length;
    const barActualWidth = barWidth * 0.8;
    waveform.forEach((v, i) => {
      const x = i * barWidth;
      const barHeight = v * h * 1.15;
      const barX = x + (barWidth - barActualWidth) / 2;
      ctx.fillStyle = "#fff";
      ctx.globalAlpha = 0.7;
      // Top half
      ctx.fillRect(barX, h / 2 - barHeight, barActualWidth, barHeight);
      // Bottom half (mirrored)
      ctx.fillRect(barX, h / 2, barActualWidth, barHeight);
    });
    // Draw playhead
    if (duration > 0) {
      const playheadX = (currentTime / duration) * w;
      ctx.globalAlpha = 1;
      ctx.fillStyle = "#1F8BFF";
      ctx.fillRect(playheadX - 1, 0, 3, h);
    }
  }, [waveform, currentTime, duration]);

  // Seek on click/drag
  const handleSeek = (e: React.MouseEvent<HTMLCanvasElement, MouseEvent>) => {
    if (!audioRef.current || !seekDuration) return;
    const rect = (e.target as HTMLCanvasElement).getBoundingClientRect();
    const x = e.clientX - rect.left;
    const percent = Math.max(0, Math.min(1, x / rect.width));
    const newTime = percent * seekDuration;
    audioRef.current.currentTime = newTime;
    setCurrentTime(newTime);
  };

  // Drag seek
  const handleMouseDown = (
    e: React.MouseEvent<HTMLCanvasElement, MouseEvent>
  ) => {
    setIsSeeking(true);
    handleSeek(e);
  };
  const handleMouseMove = (
    e: React.MouseEvent<HTMLCanvasElement, MouseEvent>
  ) => {
    if (isSeeking) handleSeek(e);
  };
  const handleMouseUp = () => setIsSeeking(false);

  const formatTime = (time: number) => {
    const minutes = Math.floor(time / 60);
    const seconds = Math.floor(time % 60);
    return `${minutes}:${seconds.toString().padStart(2, "0")}`;
  };

  return (
    <div className="fixed bottom-4 left-1/2 transform -translate-x-1/2 w-full max-w-[960px] mx-4 bg-gray-500/30 backdrop-blur-2xl border border-white/[.15] dark:border-white/[.15] rounded-[40px] p-4 shadow-[0_8px_32px_0_rgba(0,0,0,0.15)] dark:shadow-[0_8px_32px_0_rgba(0,0,0,0.3)] z-50">
      <div className="flex items-center gap-4">
        {/* Play/Pause Button */}
        <button
          onClick={togglePlayPause}
          className="w-12 h-12 rounded-full bg-foreground text-background flex items-center justify-center hover:bg-[#383838] dark:hover:bg-[#ccc] transition-colors"
        >
          {isPlaying ? (
            <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
              <path d="M6 4h4v16H6V4zm8 0h4v16h-4V4z" />
            </svg>
          ) : (
            <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
              <path d="M8 5v14l11-7z" />
            </svg>
          )}
        </button>

        {/* Album Art */}
        <div className="w-10 h-10 rounded-lg overflow-hidden bg-black/[.05] dark:bg-white/[.05] flex-shrink-0">
          {currentSong.image_url ? (
            <img
              src={currentSong.image_url}
              alt={currentSong.title}
              className="w-full h-full object-cover"
            />
          ) : (
            <div className="w-full h-full flex items-center justify-center text-foreground/30">
              <svg
                width="20"
                height="20"
                viewBox="0 0 24 24"
                fill="currentColor"
              >
                <path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z" />
              </svg>
            </div>
          )}
        </div>

        {/* Song Info */}
        <div className="flex-1 min-w-0">
          <div className="text-sm font-medium text-foreground truncate">
            {currentSong.title}
          </div>
          {currentSong.handle ? (
            <Link href={`/@${currentSong.handle}`}>
              <div className="text-xs text-foreground/60 truncate hover:text-blue-500 transition-colors cursor-pointer">
                {currentSong.display_name}
              </div>
            </Link>
          ) : (
            <div className="text-xs text-foreground/60 truncate">
              {currentSong.display_name}
            </div>
          )}
        </div>

        {/* Waveform Progress Bar */}
        <div className="flex-1 max-w-xs flex flex-col items-center">
          <div className="flex items-center w-full">
            <span className="text-xs text-foreground/60 mr-2 whitespace-nowrap">
              {formatTime(currentTime)}
            </span>
            <div className="flex-1 flex justify-center">
              <canvas
                ref={canvasRef}
                width={400}
                height={32}
                className="w-full h-8 cursor-pointer"
                style={{ display: "block" }}
                onMouseDown={handleMouseDown}
                onMouseMove={handleMouseMove}
                onMouseUp={handleMouseUp}
                onMouseLeave={handleMouseUp}
              />
            </div>
            <span className="text-xs text-foreground/60 ml-2 whitespace-nowrap">
              {isStreaming || isLoading ? (
                <span className="inline-block align-middle w-4 h-4 animate-spin border-2 border-gray-300 border-t-blue-500 rounded-full"></span>
              ) : (
                formatTime(duration)
              )}
            </span>
          </div>
        </div>
      </div>
    </div>
  );
}

export default function Playbar() {
  const { currentSong } = useAudio();
  if (!currentSong) return null;
  return <PlaybarInner currentSong={currentSong} />;
}
