"use client";

import { useEffect, useState } from "react";
import { useQuery, useMutation } from "convex/react";
import { api } from "@/convex/_generated/api";
import { Id } from "@/convex/_generated/dataModel";
import { usePlayback } from "@/contexts/PlaybackContext";
import { Share2, Heart, MessageSquarePlus } from "lucide-react";
import { useToast } from "@/components/toast/Toast";

interface RadioPlayBarProps {
  roomId: Id<"rooms">;
  currentUserId?: Id<"users">;
  onReferenceAtom?: (atomId: Id<"atoms">) => void;
}

function formatTime(seconds: number): string {
  const mins = Math.floor(seconds / 60);
  const secs = Math.floor(seconds % 60);
  return `${mins}:${secs.toString().padStart(2, "0")}`;
}

function RadioProgressBar({
  startedAt,
  duration,
}: {
  startedAt?: number;
  duration?: number;
}) {
  const [progress, setProgress] = useState(0);

  useEffect(() => {
    if (!startedAt || !duration) return;

    const interval = setInterval(() => {
      const elapsed = Date.now() - startedAt;
      const progressPercent = Math.min((elapsed / duration) * 100, 100);
      setProgress(progressPercent);
    }, 100);

    return () => clearInterval(interval);
  }, [startedAt, duration]);

  if (!duration || !startedAt) return null;

  // Both startedAt and duration are in milliseconds
  const elapsedMs = Date.now() - startedAt;
  const elapsed = Math.floor(elapsedMs / 1000); // Convert ms to seconds
  const totalSeconds = Math.floor(duration / 1000); // Convert ms to seconds

  return (
    <div className="flex-1 max-w-md">
      <div className="h-1 bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden">
        <div
          className="h-full bg-blue-500 transition-all duration-100"
          style={{ width: `${progress}%` }}
        />
      </div>
      <div className="flex justify-between text-xs text-gray-500 dark:text-gray-400 mt-1">
        <span>{formatTime(elapsed)}</span>
        <span>{formatTime(totalSeconds)}</span>
      </div>
    </div>
  );
}

function RadioQueuePreview({
  queue,
  generatingNewSongs,
}: {
  queue: any[];
  generatingNewSongs: boolean;
}) {
  const [isExpanded, setIsExpanded] = useState(false);
  const { toast } = useToast();

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

  if (queue.length === 0 && !generatingNewSongs) {
    return (
      <div className="px-4 pb-3 text-sm text-gray-500 dark:text-gray-400">
        Queue is empty
      </div>
    );
  }

  return (
    <div className="border-t border-gray-200 dark:border-gray-700">
      <button
        onClick={() => setIsExpanded(!isExpanded)}
        className="w-full px-4 py-2 text-left text-sm font-medium text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors flex items-center justify-between"
      >
        <span>
          Up Next: {queue.length} song{queue.length !== 1 ? "s" : ""} in queue
        </span>
        <svg
          className={`w-4 h-4 transition-transform ${
            isExpanded ? "rotate-180" : ""
          }`}
          fill="none"
          stroke="currentColor"
          viewBox="0 0 24 24"
        >
          <path
            strokeLinecap="round"
            strokeLinejoin="round"
            strokeWidth={2}
            d="M19 9l-7 7-7-7"
          />
        </svg>
      </button>

      {isExpanded && (
        <div className="px-4 pb-3 space-y-2 max-h-64 overflow-y-auto">
          {queue.map((atom, index) => (
            <div
              key={atom._id}
              className="flex items-center gap-3 p-2 rounded bg-gray-50 dark:bg-gray-800"
            >
              <div className="text-xs text-gray-500 dark:text-gray-400 w-6">{index + 1}</div>
              {atom.metadata?.albumArtUrl && (
                <img
                  src={atom.metadata.albumArtUrl}
                  alt=""
                  className="w-10 h-10 rounded"
                />
              )}
              <div className="flex-1 min-w-0">
                <div className="text-sm font-medium text-gray-900 dark:text-gray-100 truncate">
                  {atom.metadata?.title || "Untitled"}
                </div>
                <div className="text-xs text-gray-500 dark:text-gray-400">
                  {atom.status === "completed"
                    ? "Ready"
                    : atom.status === "streaming"
                    ? "Streaming"
                    : "Processing..."}
                </div>
              </div>
              {/* Share button */}
              {atom.metadata?.sunoClipId && (
                <button
                  onClick={(e) => {
                    e.stopPropagation();
                    handleShare(atom.metadata.sunoClipId);
                  }}
                  className="p-1.5 rounded-full transition-colors text-gray-400 hover:text-blue-600 dark:text-gray-500 dark:hover:text-blue-400"
                  aria-label="Share song"
                  title="Copy link to clipboard"
                >
                  <Share2 size={14} />
                </button>
              )}
            </div>
          ))}
          {generatingNewSongs && (
            <div className="flex items-center gap-2 p-2 text-sm text-gray-600 dark:text-gray-400">
              <svg
                className="animate-spin h-4 w-4"
                xmlns="http://www.w3.org/2000/svg"
                fill="none"
                viewBox="0 0 24 24"
              >
                <circle
                  className="opacity-25"
                  cx="12"
                  cy="12"
                  r="10"
                  stroke="currentColor"
                  strokeWidth="4"
                ></circle>
                <path
                  className="opacity-75"
                  fill="currentColor"
                  d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
                ></path>
              </svg>
              <span>Generating more songs...</span>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

export function RadioPlayBar({ roomId, currentUserId, onReferenceAtom }: RadioPlayBarProps) {
  const radioState = useQuery(api.radioRooms.getRadioRoomState, { roomId });
  const skipToNext = useMutation(api.radioPlayback.skipToNextTrack);
  const toggleLike = useMutation(api.atoms.toggleLike);
  const incrementPlayCount = useMutation(api.atoms.incrementPlayCount);
  const updatePrompt = useMutation(api.radioRooms.updateRadioPrompt);
  const { play, audioRef, volume: playbackVolume, setVolume: setPlaybackVolume } = usePlayback();
  const [volume, setVolume] = useState(playbackVolume);
  const [lastPlayedTrackId, setLastPlayedTrackId] = useState<string | null>(null);
  const [isEditingPrompt, setIsEditingPrompt] = useState(false);
  const [editedPrompt, setEditedPrompt] = useState("");
  const { toast } = useToast();

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

  // Update playback context when radio room track changes
  useEffect(() => {
    if (!radioState?.currentTrack || !radioState.room.playbackState?.isPlaying) {
      return;
    }

    const currentTrackId = radioState.currentTrack._id;
    const audioUrl = radioState.currentTrack.metadata?.audioUrl;

    // Only play if this is a new track we haven't played yet
    if (currentTrackId === lastPlayedTrackId) {
      return;
    }

    if (!audioUrl) {
      console.log("[RadioPlayBar] No audio URL available for track:", currentTrackId);
      return;
    }

    // Set audio source and play
    if (audioRef.current) {
      audioRef.current.src = audioUrl;
      audioRef.current.play().catch((error) => {
        console.error("[RadioPlayBar] Failed to play audio:", error);
      });
    }

    // Update playback context
    console.log("[RadioPlayBar] Playing new track:", {
      currentTrackId,
      trackTitle: radioState.currentTrack.metadata?.title,
      audioUrl,
      fullMetadata: radioState.currentTrack.metadata,
      atomStatus: radioState.currentTrack.status
    });
    play(currentTrackId);
    setLastPlayedTrackId(currentTrackId);

    // Increment play count when song starts
    incrementPlayCount({ atomId: currentTrackId as Id<"atoms"> }).catch((error) => {
      console.error("Failed to increment play count:", error);
    });
  }, [radioState?.currentTrack?._id, radioState?.room.playbackState?.isPlaying, lastPlayedTrackId, play, roomId, audioRef, incrementPlayCount]);

  // Sync volume changes to playback context
  useEffect(() => {
    if (volume !== playbackVolume) {
      setPlaybackVolume(volume);
    }
  }, [volume]);

  // Update local volume when playback volume changes
  useEffect(() => {
    setVolume(playbackVolume);
  }, [playbackVolume]);

  if (!radioState) return null;

  const { currentTrack, queueAtoms, isGenerating } = radioState;
  const playbackState = radioState.room.playbackState;

  const handleSkip = async () => {
    try {
      await skipToNext({ roomId });
    } catch (error) {
      console.error("Failed to skip track:", error);
    }
  };

  const handleLike = async () => {
    if (!currentTrack) return;
    try {
      await toggleLike({ atomId: currentTrack._id as Id<"atoms"> });
    } catch (error) {
      console.error("Failed to toggle like:", error);
    }
  };

  const handleEditPrompt = () => {
    setEditedPrompt(radioState.room.radioConfig?.prompt || "");
    setIsEditingPrompt(true);
  };

  const handleSavePrompt = async () => {
    if (!editedPrompt.trim()) return;
    try {
      await updatePrompt({ roomId, prompt: editedPrompt.trim() });
      setIsEditingPrompt(false);
      toast({
        title: "Prompt updated!",
        status: "success",
        duration: 2000,
        isClosable: true,
      });
    } catch (error) {
      console.error("Failed to update prompt:", error);
      toast({
        title: "Failed to update prompt",
        status: "error",
        duration: 2000,
        isClosable: true,
      });
    }
  };

  const handleCancelEdit = () => {
    setIsEditingPrompt(false);
    setEditedPrompt("");
  };

  return (
    <div className="border-t border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800">
      {/* Playbar UI - always visible */}
      <div className="flex items-center gap-4 p-4">
        {/* Album art - only show if current track exists */}
        {currentTrack?.metadata?.albumArtUrl && (
          <img
            src={currentTrack.metadata.albumArtUrl}
            alt={currentTrack.metadata.title || ""}
            className="w-16 h-16 rounded shadow-sm"
          />
        )}

        <div className="flex-1 min-w-0">
          {/* Track title - only show if current track exists */}
          {currentTrack && (
            <div className="font-semibold text-gray-900 dark:text-gray-100 truncate">
              {currentTrack.metadata?.title || "Untitled"}
            </div>
          )}

          {/* Empty state message when no track */}
          {!currentTrack && (
            <div className="text-sm text-gray-600 dark:text-gray-400">
              {isGenerating
                ? "Generating your first songs..."
                : queueAtoms.length > 0
                ? "Waiting for next song..."
                : "No songs in queue"}
            </div>
          )}

          <div className="flex items-center gap-3 mt-1 text-sm">
            {/* Live indicator - only show if playing */}
            {currentTrack && playbackState?.isPlaying && (
              <div className="flex items-center gap-1 text-xs text-green-600 dark:text-green-400">
                <div className="w-2 h-2 bg-green-600 dark:bg-green-400 rounded-full animate-pulse"></div>
                <span>Live</span>
              </div>
            )}

            {/* Prompt display/editor - always visible */}
            {!isEditingPrompt && radioState.room.radioConfig?.prompt && (
              <div className={`flex items-center gap-2 text-xs ${currentTrack && playbackState?.isPlaying ? 'border-l border-gray-300 dark:border-gray-600 pl-3' : ''}`}>
                <span className="truncate max-w-xs text-gray-600 dark:text-gray-400">
                  Prompt: {radioState.room.radioConfig.prompt}
                </span>
                <button
                  onClick={handleEditPrompt}
                  className="text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300 font-medium whitespace-nowrap"
                >
                  Edit
                </button>
              </div>
            )}
            {isEditingPrompt && (
              <div className={`flex items-center gap-2 text-xs ${currentTrack && playbackState?.isPlaying ? 'border-l border-gray-300 dark:border-gray-600 pl-3' : ''}`}>
                <input
                  type="text"
                  value={editedPrompt}
                  onChange={(e) => setEditedPrompt(e.target.value)}
                  onKeyDown={(e) => {
                    if (e.key === "Enter") handleSavePrompt();
                    if (e.key === "Escape") handleCancelEdit();
                  }}
                  className="px-2 py-1 border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 min-w-[300px]"
                  placeholder="Enter radio prompt..."
                  autoFocus
                />
                <button
                  onClick={handleSavePrompt}
                  disabled={!editedPrompt.trim()}
                  className="px-2 py-1 bg-blue-600 text-white rounded hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed font-medium whitespace-nowrap"
                >
                  Save
                </button>
                <button
                  onClick={handleCancelEdit}
                  className="px-2 py-1 bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 rounded hover:bg-gray-300 dark:hover:bg-gray-600 font-medium whitespace-nowrap"
                >
                  Cancel
                </button>
              </div>
            )}
          </div>
        </div>

        {/* Controls */}
        <div className="flex items-center gap-4">
          {/* Progress bar - only show if current track exists */}
          {currentTrack && (
            <RadioProgressBar
              startedAt={playbackState?.startedAt}
              duration={playbackState?.trackDuration}
            />
          )}

          {/* Skip button - always visible */}
          <button
            onClick={handleSkip}
            className="p-2 rounded-full hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors"
            title="Skip to next track"
          >
            <svg
              className="w-6 h-6 text-gray-700 dark:text-gray-300"
              fill="currentColor"
              viewBox="0 0 24 24"
            >
              <path d="M6 4v16l12-8z" />
              <path d="M18 4h2v16h-2z" />
            </svg>
          </button>

          {/* Like button - only show if current track exists */}
          {currentTrack && (
            <button
              onClick={handleLike}
              className={`p-2 rounded-full transition-colors ${
                currentUserId && currentTrack.likedBy?.includes(currentUserId)
                  ? "text-red-500 hover:text-red-600"
                  : "text-gray-400 hover:text-red-500 dark:text-gray-500 dark:hover:text-red-400"
              }`}
              aria-label="Like song"
              title={currentUserId && currentTrack.likedBy?.includes(currentUserId) ? "Unlike" : "Like"}
            >
              <Heart
                size={16}
                className={currentUserId && currentTrack.likedBy?.includes(currentUserId) ? "fill-current" : ""}
              />
            </button>
          )}

          {/* Reference button - only show if current track exists */}
          {currentTrack && onReferenceAtom && (
            <button
              onClick={() => onReferenceAtom(currentTrack._id as Id<"atoms">)}
              className="p-2 rounded-full transition-colors text-gray-400 hover:text-green-600 dark:text-gray-500 dark:hover:text-green-400"
              aria-label="Reference in chat"
              title="Reference this song in chat"
            >
              <MessageSquarePlus size={16} />
            </button>
          )}

          {/* Share button - only show if current track exists */}
          {currentTrack?.metadata?.sunoClipId && (
            <button
              onClick={() => handleShare(currentTrack.metadata.sunoClipId)}
              className="p-2 rounded-full transition-colors text-gray-400 hover:text-blue-600 dark:text-gray-500 dark:hover:text-blue-400"
              aria-label="Share song"
              title="Copy link to clipboard"
            >
              <Share2 size={16} />
            </button>
          )}

          {/* Volume control - only show if current track exists */}
          {currentTrack && (
            <div className="flex items-center gap-2">
              <svg
                className="w-5 h-5 text-gray-600 dark:text-gray-400"
                fill="currentColor"
                viewBox="0 0 24 24"
              >
                <path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z" />
              </svg>
              <input
                type="range"
                min="0"
                max="1"
                step="0.01"
                value={volume}
                onChange={(e) => setVolume(parseFloat(e.target.value))}
                className="w-20"
              />
            </div>
          )}
        </div>
      </div>

      {/* Queue preview - exclude current track */}
      <RadioQueuePreview
        queue={queueAtoms.filter((atom) => atom?._id !== currentTrack?._id)}
        generatingNewSongs={isGenerating ?? false}
      />
    </div>
  );
}
