"use client";

import { usePlayback } from "@/contexts/PlaybackContext";
import { useQuery } from "convex/react";
import { api } from "@/convex/_generated/api";
import { Play, Pause, Volume2, RotateCcw, Loader2, Share2 } from "lucide-react";
import { useEffect, useState, useRef, useCallback } from "react";
import { Id } from "@/convex/_generated/dataModel";
import { useToast } from "@/components/toast/Toast";

export function PlayBar({ roomId }: { roomId: Id<"rooms"> | null }) {
  const {
    currentTrackId,
    isPlaying,
    pause,
    resume,
    seek,
    volume,
    setVolume,
    followMode,
    setFollowMode,
    audioRef,
  } = usePlayback();

  const { toast } = useToast();

  const [localPosition, setLocalPosition] = useState(0);
  const [isDragging, setIsDragging] = useState(false);
  const [duration, setDuration] = useState(0);
  const [hasLocalOverride, setHasLocalOverride] = useState(false);
  const pendingSeekPosition = useRef<number | null>(null);
  const lastTrackId = useRef<Id<"atoms"> | null>(null);

  // Get current track metadata
  const atom = useQuery(
    api.atoms.getByIds,
    currentTrackId ? { ids: [currentTrackId] } : "skip"
  );

  // Get room playback state to show revert option
  const roomPlaybackState = useQuery(
    api.playback.getRoomPlaybackState,
    roomId ? { roomId } : "skip"
  );

  const currentAtom = atom?.[0];
  const hasRoomPlayback = roomPlaybackState?.currentTrackId !== undefined;
  const isFollowingRoom = followMode === "ROOM";
  const canRevertToRoom = !isFollowingRoom && hasRoomPlayback;

  // Reset local override when track changes
  useEffect(() => {
    if (currentTrackId !== lastTrackId.current) {
      setHasLocalOverride(false);
      lastTrackId.current = currentTrackId;
    }
  }, [currentTrackId]);

  // Update duration when audio loads
  useEffect(() => {
    const audio = audioRef.current;
    if (!audio) return;

    const handleLoadedMetadata = () => {
      setDuration(audio.duration);
    };

    const handleTimeUpdate = () => {
      // Only update from audio element if not dragging AND no local override active
      if (!isDragging && !hasLocalOverride) {
        setLocalPosition(audio.currentTime);
      }
    };

    audio.addEventListener("loadedmetadata", handleLoadedMetadata);
    audio.addEventListener("timeupdate", handleTimeUpdate);

    return () => {
      audio.removeEventListener("loadedmetadata", handleLoadedMetadata);
      audio.removeEventListener("timeupdate", handleTimeUpdate);
    };
  }, [audioRef, isDragging, hasLocalOverride]);

  const handleScrubberChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const newPosition = parseFloat(e.target.value);
    setLocalPosition(newPosition);

    // Store the pending position but don't update anything yet
    pendingSeekPosition.current = newPosition;
  };

  const handleScrubberMouseDown = () => {
    setIsDragging(true);
    setHasLocalOverride(true); // Enable local override
  };

  const handleScrubberMouseUp = async () => {
    setIsDragging(false);

    // Only update both audio element and server when user finishes dragging
    if (pendingSeekPosition.current !== null) {
      // Update audio element position
      if (audioRef.current) {
        audioRef.current.currentTime = pendingSeekPosition.current;
      }

      // Update server
      await seek(pendingSeekPosition.current * 1000); // Convert to milliseconds
      pendingSeekPosition.current = null;

      // Clear local override after a short delay to let the server update propagate
      setTimeout(() => {
        setHasLocalOverride(false);
      }, 500);
    }
  };

  const handleRevertToRoom = () => {
    setFollowMode("ROOM");
  };

  const handleShare = async () => {
    if (!currentAtom?.metadata.sunoClipId) return;

    const shareUrl = `https://b.suno.fm/song/${currentAtom.metadata.sunoClipId}`;
    try {
      await navigator.clipboard.writeText(shareUrl);
      toast({
        title: "Link copied to clipboard!",
        status: "success",
        duration: 2000,
        isClosable: true,
      });
    } catch (error) {
      console.error("Failed to copy to clipboard:", error);
      toast({
        title: "Failed to copy link",
        status: "error",
        duration: 2000,
        isClosable: true,
      });
    }
  };

  const formatTime = (seconds: number): string => {
    if (isNaN(seconds) || seconds === 0 || !isFinite(seconds)) return "0:00";
    const mins = Math.floor(seconds / 60);
    const secs = Math.floor(seconds % 60);
    return `${mins}:${secs.toString().padStart(2, "0")}`;
  };

  // Determine if playbar should show empty state
  const hasTrack = currentTrackId && currentAtom;

  const isStreaming = hasTrack && (!isFinite(duration) || duration === 0);

  return (
    <div className="play-bar border-t border-gray-200 dark:border-gray-700 bg-white/95 dark:bg-gray-800/95 backdrop-blur-sm p-3">
      <div className="max-w-4xl mx-auto">
        <div className="flex items-center gap-4">
          {/* Album Art */}
          {hasTrack && currentAtom.metadata.albumArtUrl ? (
            <img
              src={currentAtom.metadata.albumArtUrl}
              alt={currentAtom.metadata.title || "Track"}
              className="w-12 h-12 rounded object-cover flex-shrink-0"
            />
          ) : (
            <div className="w-12 h-12 rounded bg-gray-200 dark:bg-gray-700 flex-shrink-0 flex items-center justify-center">
              <Play size={20} className="text-gray-400 dark:text-gray-500" />
            </div>
          )}

          {/* Track Info */}
          <div className="flex-1 min-w-0">
            <div className="text-sm font-medium text-gray-900 dark:text-gray-100 truncate">
              {hasTrack ? currentAtom.metadata.title || "Unknown Track" : "No track playing"}
            </div>
            {hasTrack && currentAtom.metadata.artist && (
              <div className="text-xs text-gray-600 dark:text-gray-400 truncate">
                {currentAtom.metadata.artist}
              </div>
            )}
          </div>

          {/* Playback Controls */}
          <div className="flex items-center gap-3">
            {/* Play/Pause Button */}
            <button
              onClick={hasTrack ? (isPlaying ? pause : resume) : undefined}
              disabled={!hasTrack}
              className={`p-2 rounded-full transition-colors ${
                hasTrack
                  ? "bg-blue-500 hover:bg-blue-600 text-white cursor-pointer"
                  : "bg-gray-300 dark:bg-gray-700 text-gray-500 dark:text-gray-600 cursor-not-allowed"
              }`}
              aria-label={isPlaying ? "Pause" : "Play"}
            >
              {isPlaying ? <Pause size={20} /> : <Play size={20} />}
            </button>

            {/* Time Display */}
            <div className="text-xs text-gray-600 dark:text-gray-400 tabular-nums w-20 text-center flex items-center justify-center gap-1">
              {hasTrack ? (
                isStreaming ? (
                  <div className="flex items-center gap-1">
                    <span>{formatTime(localPosition)}</span>
                    <Loader2 size={12} className="animate-spin" />
                  </div>
                ) : (
                  `${formatTime(localPosition)} / ${formatTime(duration)}`
                )
              ) : (
                "0:00 / 0:00"
              )}
            </div>

            {/* Scrubber */}
            <input
              type="range"
              min="0"
              max={duration || 0}
              value={hasTrack ? localPosition : 0}
              onChange={handleScrubberChange}
              onMouseDown={handleScrubberMouseDown}
              onMouseUp={handleScrubberMouseUp}
              onTouchStart={handleScrubberMouseDown}
              onTouchEnd={handleScrubberMouseUp}
              disabled={!hasTrack}
              className="w-48 h-1 bg-gray-200 dark:bg-gray-700 rounded-lg appearance-none disabled:cursor-not-allowed disabled:opacity-50 cursor-pointer [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-3 [&::-webkit-slider-thumb]:h-3 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-blue-500 [&::-webkit-slider-thumb]:cursor-pointer [&::-moz-range-thumb]:w-3 [&::-moz-range-thumb]:h-3 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-blue-500 [&::-moz-range-thumb]:border-0 [&::-moz-range-thumb]:cursor-pointer"
            />

            {/* Volume Control */}
            <div className="flex items-center gap-2">
              <Volume2 size={16} className="text-gray-600 dark:text-gray-400" />
              <input
                type="range"
                min="0"
                max="1"
                step="0.01"
                value={volume}
                onChange={(e) => setVolume(parseFloat(e.target.value))}
                className="w-20 h-1 bg-gray-200 dark:bg-gray-700 rounded-lg appearance-none cursor-pointer [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-3 [&::-webkit-slider-thumb]:h-3 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-blue-500 [&::-webkit-slider-thumb]:cursor-pointer [&::-moz-range-thumb]:w-3 [&::-moz-range-thumb]:h-3 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-blue-500 [&::-moz-range-thumb]:border-0 [&::-moz-range-thumb]:cursor-pointer"
              />
            </div>

            {/* Share Button */}
            {hasTrack && (
              <button
                onClick={handleShare}
                className="p-2 rounded-full transition-colors text-gray-400 hover:text-blue-600 dark:text-gray-500 dark:hover:text-blue-400 cursor-pointer"
                aria-label="Share song"
                title="Copy link to clipboard"
              >
                <Share2 size={16} />
              </button>
            )}

            {/* Revert to Room Button */}
            {canRevertToRoom && (
              <button
                onClick={handleRevertToRoom}
                className="flex items-center gap-1 px-3 py-1.5 text-xs bg-blue-50 dark:bg-blue-900/30 text-blue-600 dark:text-blue-400 hover:bg-blue-100 dark:hover:bg-blue-900/50 rounded-full transition-colors"
                title="Switch to room playback"
              >
                <RotateCcw size={14} />
                <span>Join Room</span>
              </button>
            )}

            {/* Following Room Indicator */}
            {isFollowingRoom && (
              <div className="px-3 py-1.5 text-xs bg-green-50 dark:bg-green-900/30 text-green-600 dark:text-green-400 rounded-full">
                Following Room
              </div>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}
