"use client";

import Link from "next/link";
import { forwardRef, useEffect, useRef, useState } from "react";
import { useApiClient } from "../lib/apiClient";
import { useAudio } from "./components/AudioContext";

export interface Song {
  id: string;
  title: string;
  display_name: string;
  handle: string;
  audio_url: string;
  image_url?: string;
  video_cover_url?: string;
  avatar_image_url?: string;
  caption?: string;
  created_at: string;
  upvote_count: number;
  comment_count: number;
  play_count: number;
  display_tags?: string;
  source?: "trending" | "following" | "profile" | "For You" | "Best of 4.5";
  status?: string;
  is_liked?: boolean;
  metadata?: {
    duration?: number;
    prompt?: string;
  };
}

interface SongCardProps {
  song: Song;
  isCurrent: boolean;
  playSong: (song: Song, startTime?: number) => void;
  startTime?: number; // Default start time in seconds
}

function ShareButton({ songId }: { songId: string }) {
  const [copied, setCopied] = useState(false);
  const shareUrl = `https://suno.com/song/${songId}`;

  const handleShare = async (e: React.MouseEvent) => {
    e.stopPropagation();
    try {
      await navigator.clipboard.writeText(shareUrl);
      setCopied(true);
      setTimeout(() => setCopied(false), 1200);
    } catch (err) {
      // fallback or error handling
    }
  };

  return (
    <button
      onClick={handleShare}
      className="flex items-center gap-1 text-white/80 hover:text-green-400 transition-colors relative"
      title="Share song"
      aria-label="Share song"
      type="button"
      tabIndex={0}
      style={{ position: "relative" }}
    >
      <svg
        width="18"
        height="18"
        viewBox="0 0 24 24"
        fill="none"
        stroke="currentColor"
        strokeWidth="2"
        strokeLinecap="round"
        strokeLinejoin="round"
      >
        <circle cx="18" cy="5" r="3" />
        <circle cx="6" cy="12" r="3" />
        <circle cx="18" cy="19" r="3" />
        <line x1="8.59" y1="13.51" x2="15.42" y2="17.49" />
        <line x1="15.41" y1="6.51" x2="8.59" y2="10.49" />
      </svg>
      {copied && (
        <span className="absolute -top-7 left-1/2 -translate-x-1/2 bg-black/80 text-white text-xs px-2 py-1 rounded shadow z-20 whitespace-nowrap">
          Copied!
        </span>
      )}
    </button>
  );
}

const SongCard = forwardRef<HTMLDivElement, SongCardProps>(
  ({ song, isCurrent, playSong, startTime = 30 }, ref) => {
    const cardRef = useRef<HTMLDivElement>(null);
    const { currentSong, isPlaying, audioRef } = useAudio();
    const apiClient = useApiClient();
    const hasFetchedLyrics = useRef(false);
    const [alignedLyrics, setAlignedLyrics] = useState<any[] | null>(null);
    const [currentLyric, setCurrentLyric] = useState<string>("");
    const [currentWordIdx, setCurrentWordIdx] = useState<number | null>(null);
    const [currentLyricObj, setCurrentLyricObj] = useState<any>(null);
    const [isLiked, setIsLiked] = useState(song.is_liked || false);
    const [likeCount, setLikeCount] = useState(song.upvote_count);

    // Attach the forwarded ref to the card
    useEffect(() => {
      if (!ref) return;
      if (typeof ref === "function") {
        ref(cardRef.current);
      } else {
        (ref as React.MutableRefObject<HTMLDivElement | null>).current =
          cardRef.current;
      }
    }, [ref]);

    const formatPlayCount = (count: number) => {
      if (count >= 1000000) return `${(count / 1000000).toFixed(1)}M`;
      if (count >= 1000) return `${(count / 1000).toFixed(1)}K`;
      return count.toString();
    };

    const formatTimeAgo = (dateString: string) => {
      const date = new Date(dateString);
      const now = new Date();
      const diffInHours = Math.floor(
        (now.getTime() - date.getTime()) / (1000 * 60 * 60)
      );

      if (diffInHours < 24) return `${diffInHours}h ago`;
      const diffInDays = Math.floor(diffInHours / 24);
      if (diffInDays < 7) return `${diffInDays}d ago`;
      const diffInWeeks = Math.floor(diffInDays / 7);
      return `${diffInWeeks}w ago`;
    };

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

    const handleCardClick = () => {
      // Only play if song is complete or streaming
      if (
        song.status === "complete" ||
        song.status === "streaming" ||
        !song.status
      ) {
        // Use the startTime prop, but override to 0 for streaming songs
        const actualStartTime = song.status === "streaming" ? 0 : startTime;
        playSong(song, actualStartTime);
      }
    };

    const handleLikeClick = async (e: React.MouseEvent) => {
      e.stopPropagation(); // Prevent card click
      try {
        await apiClient.POST("/api/gen/{gen_id}/update_reaction_type/", {
          params: { path: { gen_id: song.id } },
          body: { reaction: isLiked ? null : "LIKE" },
        });

        // Update local state
        setIsLiked(!isLiked);
        setLikeCount(isLiked ? likeCount - 1 : likeCount + 1);
      } catch (err) {
        console.error("Failed to update like status:", err);
      }
    };

    useEffect(() => {
      const observer = new IntersectionObserver(
        (entries) => {
          entries.forEach((entry) => {
            // Auto-play when card enters viewport (70% visible)
            if (entry.isIntersecting && entry.intersectionRatio >= 0.7) {
              // Only auto-play if song is complete/streaming and no song is currently playing or if it's a different song
              if (
                (song.status === "complete" ||
                  song.status === "streaming" ||
                  !song.status) &&
                (!currentSong || currentSong.id !== song.id)
              ) {
                // Use the startTime prop, but override to 0 for streaming songs
                const actualStartTime =
                  song.status === "streaming" ? 0 : startTime;
                playSong(song, actualStartTime);
              }
              // Fetch aligned lyrics from v2 endpoint (only once per card)
              if (!hasFetchedLyrics.current) {
                hasFetchedLyrics.current = true;
                apiClient
                  .GET("/api/gen/{clip_id}/aligned_lyrics/v2", {
                    params: { path: { clip_id: song.id } },
                  })
                  .then((res) => {
                    if (res.data && Array.isArray(res.data.aligned_lyrics)) {
                      setAlignedLyrics(res.data.aligned_lyrics);
                    } else {
                      setAlignedLyrics(null);
                    }
                  });
              }
            }
          });
        },
        {
          threshold: [0.7], // Trigger when 70% of the card is visible
          rootMargin: "-50px 0px", // Add some margin for better UX
        }
      );

      if (cardRef.current) {
        observer.observe(cardRef.current);
      }

      return () => {
        if (cardRef.current) {
          observer.unobserve(cardRef.current);
        }
      };
    }, [song, currentSong, playSong, apiClient]);

    // Lyric sync effect
    useEffect(() => {
      if (!alignedLyrics || currentSong?.id !== song.id) {
        setCurrentLyric("");
        setCurrentWordIdx(null);
        setCurrentLyricObj(null);
        return;
      }
      let rafId: number | null = null;
      let stopped = false;

      const updateLyric = () => {
        if (stopped) return;
        const audio = audioRef?.current;
        if (!audio) return;
        const currentTime = audio.currentTime;
        // Find the lyric whose start_s <= currentTime < end_s
        let lyric = "";
        let lyricObj = null;
        for (let i = 0; i < alignedLyrics.length; i++) {
          if (
            alignedLyrics[i].start_s <= currentTime &&
            alignedLyrics[i].end_s > currentTime
          ) {
            lyric = alignedLyrics[i].text;
            lyricObj = alignedLyrics[i];
            break;
          }
        }
        let wordIdx: number | null = null;
        if (lyricObj && Array.isArray(lyricObj.words)) {
          for (let j = 0; j < lyricObj.words.length; j++) {
            const w = lyricObj.words[j];
            if (w.start_s <= currentTime && w.end_s > currentTime) {
              wordIdx = j;
              break;
            }
          }
        }
        setCurrentLyric((prev) => {
          return lyric;
        });
        setCurrentWordIdx(wordIdx);
        setCurrentLyricObj(lyricObj);

        rafId = requestAnimationFrame(updateLyric);
      };

      const startRaf = () => {
        stopped = false;
        if (rafId === null) {
          rafId = requestAnimationFrame(updateLyric);
        }
      };
      const stopRaf = () => {
        stopped = true;
        if (rafId !== null) {
          cancelAnimationFrame(rafId);
          rafId = null;
        }
      };

      // Visibility handler
      const handleVisibility = () => {
        if (document.visibilityState === "visible") {
          startRaf();
        } else {
          stopRaf();
        }
      };

      document.addEventListener("visibilitychange", handleVisibility);
      // Start initially if visible
      if (document.visibilityState === "visible") {
        startRaf();
      }

      return () => {
        document.removeEventListener("visibilitychange", handleVisibility);
        stopRaf();
      };
    }, [alignedLyrics, isPlaying, currentSong, song.id, audioRef]);

    return (
      <div
        ref={cardRef}
        className={`relative bg-white/60 dark:bg-black/60 backdrop-blur-sm border border-black/[.08] dark:border-white/[.145] rounded-2xl overflow-hidden hover:bg-white/70 dark:hover:bg-black/70 transition-all duration-200 cursor-pointer group p-0 mb-3${
          isCurrent ? " pulse-glow" : ""
        }`}
        onClick={handleCardClick}
        style={{}}
      >
        {/* Album Art (now fills the card) */}
        <div className="relative w-full aspect-[4/5] max-h-[70vh] flex items-center justify-center">
          {/* Video or Image */}
          {song.video_cover_url ? (
            <video
              src={song.video_cover_url}
              autoPlay
              loop
              muted
              playsInline
              className="w-full h-full object-cover"
            />
          ) : song.image_url ? (
            <img
              src={song.image_url}
              alt={song.title}
              className={`w-full h-full object-cover ${
                isCurrent && isPlaying ? "pan-image" : ""
              }`}
            />
          ) : (
            <div className="w-full h-full flex items-center justify-center text-foreground/30">
              <svg
                width="64"
                height="64"
                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>
          )}
          {/* Top Gradient Overlay for Info */}
          <div className="absolute top-0 left-0 w-full pt-4 px-4 pb-10 bg-gradient-to-b from-black/70 via-black/30 to-transparent z-10">
            {/* User Header */}
            <div className="flex items-center gap-3 mb-2">
              <div className="w-8 h-8 rounded-full overflow-hidden bg-gradient-to-br from-blue-400 to-purple-500 flex items-center justify-center text-white font-semibold text-xs">
                {song.avatar_image_url ? (
                  <img
                    src={song.avatar_image_url}
                    alt={song.display_name}
                    className="w-full h-full object-cover"
                  />
                ) : (
                  song.display_name.charAt(0).toUpperCase()
                )}
              </div>
              <div className="flex-1 min-w-0">
                <div className="flex items-center gap-2">
                  <Link
                    href={`/@${song.handle}`}
                    onClick={(e) => e.stopPropagation()}
                  >
                    <h3 className="font-semibold text-xs text-white truncate hover:text-green-300 transition-colors cursor-pointer">
                      {song.display_name}
                    </h3>
                  </Link>
                  <span className="text-xs text-white/60">•</span>
                  <span className="text-xs text-white/60 truncate">
                    @{song.handle}
                  </span>
                </div>
              </div>
              {/* Source Badge */}
              {song.source && (
                <div
                  className={`inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium ${
                    song.source === "trending"
                      ? "bg-orange-500/20 text-orange-200"
                      : song.source === "profile"
                      ? "bg-green-500/20 text-green-200"
                      : song.source === "Best of 4.5"
                      ? "bg-purple-500/20 text-purple-200"
                      : song.source === "For You"
                      ? "bg-pink-500/20 text-pink-200"
                      : "bg-blue-500/20 text-blue-200"
                  }`}
                >
                  {song.source.charAt(0).toUpperCase() + song.source.slice(1)}
                </div>
              )}
            </div>
            {/* Title & Caption */}
            <h2 className="text-xl font-bold text-white mb-1 leading-tight truncate">
              {song.title}
            </h2>
            {song.caption && (
              <p className="text-xs text-white/80 mb-1 line-clamp-2">
                {song.caption}
              </p>
            )}
          </div>
          {/* Bottom Gradient Overlay for Stats & Lyrics */}
          <div className="absolute bottom-0 left-0 w-full px-4 pb-4 pt-10 bg-gradient-to-t from-black/70 via-black/30 to-transparent z-10 flex flex-col">
            {/* Lyric Overlay */}
            {alignedLyrics && currentLyric && currentSong?.id === song.id && (
              <div className="w-full text-center text-white text-3xl font-semibold mb-2 pointer-events-none">
                {currentLyricObj &&
                Array.isArray(currentLyricObj.words) &&
                currentLyricObj.words.length > 0
                  ? currentLyricObj.words.map((w: any, idx: number) => (
                      <span
                        key={idx}
                        className={
                          idx === currentWordIdx ? "text-green-400" : undefined
                        }
                      >
                        {w.text}
                      </span>
                    ))
                  : currentLyric}
              </div>
            )}
            {/* Engagement Bar */}
            <div className="flex items-center justify-between w-full">
              <div className="flex items-center gap-6">
                <button
                  onClick={handleLikeClick}
                  className={`flex items-center gap-2 transition-colors ${
                    isLiked
                      ? "text-pink-500"
                      : "text-white/80 hover:text-pink-400"
                  }`}
                  aria-label={isLiked ? "Unlike song" : "Like song"}
                >
                  <svg
                    width="20"
                    height="20"
                    viewBox="0 0 24 24"
                    fill="currentColor"
                  >
                    <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" />
                  </svg>
                  <span className="text-sm font-medium">{likeCount}</span>
                </button>
                <div className="flex items-center gap-2 text-white/80">
                  <svg
                    width="20"
                    height="20"
                    viewBox="0 0 24 24"
                    fill="currentColor"
                  >
                    <path d="M21 6h-2v9H6v2c0 .55.45 1 1 1h11l4 4V7c0-.55-.45-1-1-1zm-4 6V3c0-.55-.45-1-1-1H3c-.55 0-1 .45-1 1v14l4-4h11c.55 0 1-.45 1-1z" />
                  </svg>
                  <span className="text-sm font-medium">
                    {song.comment_count}
                  </span>
                </div>
                <div className="flex items-center gap-2 text-white/80">
                  <svg
                    width="20"
                    height="20"
                    viewBox="0 0 24 24"
                    fill="currentColor"
                  >
                    <path d="M8 5v14l11-7z" />
                  </svg>
                  <span className="text-sm font-medium">
                    {formatPlayCount(song.play_count)}
                  </span>
                </div>
                {/* Share Button */}
                <ShareButton songId={song.id} />
              </div>
              {/* Duration Badge */}
              {song.metadata?.duration && (
                <div className="bg-black/70 text-white text-xs px-2 py-1 rounded-full">
                  {formatDuration(song.metadata.duration)}
                </div>
              )}
            </div>
          </div>
        </div>

        {/* Loading Overlay */}
        {song.status &&
          song.status !== "complete" &&
          song.status !== "streaming" && (
            <div className="absolute inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-20">
              <div className="text-center">
                <div className="inline-block animate-spin rounded-full h-12 w-12 border-4 border-solid border-white border-r-transparent mb-3"></div>
                <p className="text-white text-sm font-medium">Generating...</p>
              </div>
            </div>
          )}
      </div>
    );
  }
);

export default SongCard;
