"use client";
import { useParams } from "next/navigation";
import { useEffect, useRef, useState } from "react";
import supabase from "../../../utils/supabase/client";
import type { Song } from "../../SongCard";
import SongCard from "../../SongCard";
import { useAudio } from "../../components/AudioContext";
import LeftSidebar from "../../components/LeftSidebar";
import RadioPlaybar from "../../components/RadioPlaybar";

// Prompt queue row type (inline, since not found in gen.ts)
type PromptQueueRow = {
  id: string;
  text: string;
  prompt_json: any;
  submitted_by: string | null;
  created_at: string;
  user_profile?: string | null; // joined from profiles
  user_id?: string | null;
};

export default function RadioStationPage() {
  const params = useParams();
  const radioId = params?.radio_id as string;
  const { playSong, currentSong, isPlaying, audioRef } = useAudio();
  const [presenceUsers, setPresenceUsers] = useState<any[]>([]);
  const [userEmail, setUserEmail] = useState<string | null>(null);
  const [promptQueue, setPromptQueue] = useState<PromptQueueRow[]>([]);
  const [loadedSong, setLoadedSong] = useState<Song | null>(null);
  const [generateLoading, setGenerateLoading] = useState(false);
  const [generateError, setGenerateError] = useState<string | null>(null);
  const [generateSuccess, setGenerateSuccess] = useState(false);
  const [currentClipId, setCurrentClipId] = useState<string | null>(null);
  const clipChannelRef = useRef<any>(null);
  const [isLeader, setIsLeader] = useState(false);
  const [currentUserId, setCurrentUserId] = useState<string | null>(null);

  // Get user email and ID on mount
  useEffect(() => {
    supabase.auth.getSession().then(({ data }) => {
      const email = data.session?.user?.email || null;
      const userId = data.session?.user?.id || null;
      setUserEmail(email);
      setCurrentUserId(userId);
      console.log("Auth session loaded:", {
        email,
        userId,
      });
    });
  }, []);

  // Check if current user is the leader
  useEffect(() => {
    if (!radioId || !currentUserId) return;

    const checkLeaderStatus = async () => {
      const { data, error } = await supabase
        .from("room_status")
        .select("leader_user_id")
        .eq("radio_room_id", radioId)
        .single();

      if (!error && data) {
        setIsLeader(data.leader_user_id === currentUserId);
      }
    };

    checkLeaderStatus();
  }, [radioId, currentUserId]);

  useEffect(() => {
    if (!radioId || userEmail === undefined) return;
    // Create a channel for this radio room
    const channel = supabase.channel(`radio-presence-${radioId}`, {
      config: {
        presence: { key: undefined },
      },
    });

    channel
      .on("presence", { event: "sync" }, () => {
        const state = channel.presenceState();
        // Flatten state to array of users
        // values are objects with joined_at, name, presence_ref
        const users = Object.values(state).flatMap((arr: any) =>
          arr.map((meta: any) => ({
            joined_at: meta.joined_at,
            name: meta.name,
            presence_ref: meta.presence_ref,
          }))
        );
        setPresenceUsers(users);
      })
      .subscribe(async (status) => {
        if (status === "SUBSCRIBED") {
          await channel.track({
            name: userEmail || "Anonymous",
            joined_at: new Date().toISOString(),
          });
        }
      });

    return () => {
      channel.untrack();
      channel.unsubscribe();
    };
  }, [radioId, userEmail]);

  // Load prompt queue for this room
  useEffect(() => {
    if (!radioId) return;
    // Fetch last 10 prompt queue entries for this room, newest first
    (async () => {
      const { data, error } = await supabase
        .from("prompt_queue")
        .select(
          `id, text, prompt_json, submitted_by, created_at, profiles:submitted_by(id, handle)`
        ) // join profiles with handle
        .eq("radio_room_id", radioId)
        .order("created_at", { ascending: false })
        .limit(10);
      console.log("data", data, error);
      if (!error && data) {
        setPromptQueue(
          data.map((row: any) => ({
            ...row,
            user_profile: row.profiles?.id
              ? row.profiles.handle || "Unknown"
              : "Unknown",
            user_id: row.profiles?.id || row.submitted_by || null,
          }))
        );
      } else {
        setPromptQueue([]);
      }
    })();
  }, [radioId]);

  // --- Realtime broadcast subscription for all room events ---
  useEffect(() => {
    if (!radioId) return;
    let channel: any = null;
    let isMounted = true;

    (async () => {
      await supabase.realtime.setAuth();

      // Subscribe to a single broadcast channel for this room
      channel = supabase
        .channel(`room:${radioId}`, {
          config: { private: true, broadcast: { self: true } },
        })
        .on("broadcast", { event: "*" }, (payload) => {
          // payload.payload contains your event
          console.log("Broadcast event:", payload);
          // You can switch on payload.payload.table and payload.payload.event
          // and update state accordingly
          fetchRoomStatus(); // or more granular updates if desired
        })
        .subscribe((status) => {
          console.log("Broadcast channel status:", status);
          if (status === "CHANNEL_ERROR") {
            console.error("Failed to subscribe to broadcast channel");
          }
        });
    })();

    return () => {
      isMounted = false;
      if (channel) {
        supabase.removeChannel(channel);
      }
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [radioId]);

  // --- Helper to fetch room_status and set currentClipId/loadedSong ---
  const fetchRoomStatus = async () => {
    const { data, error } = await supabase
      .from("room_status")
      .select(
        `current_clip_id, current_clip_started_at, clips:current_clip_id(metadata)`
      )
      .eq("radio_room_id", radioId)
      .single();
    console.log("fetch room status", data, error);
    if (!error && data && data.clips) {
      const clip = Array.isArray(data.clips) ? data.clips[0] : data.clips;
      setCurrentClipId(data.current_clip_id || null);
      if (clip && clip.metadata) {
        const meta = clip.metadata;
        setLoadedSong({
          id: meta.id ?? data.current_clip_id ?? "",
          title: meta.title ?? "",
          display_name: meta.display_name ?? "",
          handle: meta.handle ?? "",
          audio_url: meta.audio_url ?? "",
          image_url: meta.image_url ?? "",
          video_cover_url: meta.video_cover_url ?? undefined,
          avatar_image_url: meta.avatar_image_url ?? undefined,
          caption: meta.caption ?? undefined,
          created_at: meta.created_at ?? "",
          upvote_count: meta.upvote_count ?? 0,
          comment_count: meta.comment_count ?? 0,
          play_count: meta.play_count ?? 0,
          display_tags: meta.display_tags ?? undefined,
          source: meta.source ?? undefined,
          status: meta.status ?? undefined,
          is_liked: meta.is_liked ?? undefined,
          metadata: meta.metadata ?? {},
        });
      } else {
        setLoadedSong(null);
      }
    } else {
      setLoadedSong(null);
      setCurrentClipId(null);
    }
  };

  // --- Initial load and on radioId change ---
  useEffect(() => {
    if (!radioId) return;
    fetchRoomStatus();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [radioId]);

  const handleGenerate = async () => {
    if (!radioId || !promptQueue[0]?.id) return;
    setGenerateLoading(true);
    setGenerateError(null);
    setGenerateSuccess(false);
    try {
      const { data, error } = await supabase.functions.invoke("generate_clip", {
        body: { room_id: radioId, prompt_id: promptQueue[0].id },
      });
      if (error) throw new Error(error.message || "Failed to generate");
      const newClipId = data?.ids?.[0];
      if (newClipId) {
        // Update room_status with the new clip id
        // await 50 ms
        await new Promise((resolve) => setTimeout(resolve, 50));

        const { error: updateError } = await supabase
          .from("room_status")
          .update({
            current_clip_id: newClipId,
            current_clip_started_at: new Date().toISOString(),
          })
          .eq("radio_room_id", radioId);
        if (updateError)
          throw new Error(
            updateError.message || "Failed to update room status"
          );
      }
      setGenerateSuccess(true);
    } catch (e: any) {
      setGenerateError(e.message || "Unknown error");
    } finally {
      setGenerateLoading(false);
    }
  };

  // Custom play handler for radio that syncs to room timestamp
  const handleRadioPlay = async (song: Song, startTime?: number) => {
    if (isLeader) {
      // Leaders can play normally
      playSong(song, startTime);
      return;
    }

    // Non-leaders need to sync to the room's current playback position
    try {
      const { data, error } = await supabase
        .from("room_status")
        .select("current_clip_started_at")
        .eq("radio_room_id", radioId)
        .single();

      if (error || !data?.current_clip_started_at) {
        // Fallback to normal play if we can't get the timestamp
        playSong(song, startTime);
        return;
      }

      // Calculate how much time has elapsed since the clip started
      const clipStartTime = new Date(data.current_clip_started_at);
      const now = new Date();
      const elapsedSeconds = Math.max(
        0,
        (now.getTime() - clipStartTime.getTime()) / 1000
      );

      // Play the song starting from the calculated position
      playSong(song, elapsedSeconds);
    } catch (error) {
      console.error("Failed to sync playback position:", error);
      // Fallback to normal play
      playSong(song, startTime);
    }
  };

  // Custom toggle handler for radio that syncs non-leaders when resuming
  const handleRadioTogglePlayPause = async () => {
    if (isPlaying) {
      // If currently playing, just pause normally
      audioRef.current?.pause();
      return;
    }

    // If currently paused and trying to resume
    if (isLeader) {
      // Leaders can resume normally
      audioRef.current?.play();
      return;
    }

    // Non-leaders need to sync to room timestamp when resuming
    if (currentSong && loadedSong) {
      await handleRadioPlay(loadedSong, 0);
    }
  };

  return (
    <div className="flex min-h-screen w-full bg-[#18181b]">
      <LeftSidebar />
      {/* Main content: two columns */}
      <div className="flex flex-1 flex-row">
        {/* Left column: Prompt Queue, Presence, Generate */}
        <div className="w-80 bg-[#23232a] border-r border-black/10 p-6 flex flex-col gap-4">
          <h2 className="text-lg font-bold text-white mb-2">Prompt Queue</h2>
          <ul className="flex flex-col gap-3">
            {promptQueue.map((prompt) => (
              <li
                key={prompt.id}
                className="bg-[#23232a] rounded-lg px-4 py-3 border border-white/5 text-white/90"
              >
                <div className="text-sm font-medium">{prompt.text}</div>
                <div className="text-xs text-white/50 mt-1">
                  by {prompt.user_profile}
                </div>
              </li>
            ))}
          </ul>
          <div className="mt-8 text-xs text-white/40 flex items-center gap-2">
            {presenceUsers.length} listener
            {presenceUsers.length !== 1 ? "s" : ""} online
            <div className="flex flex-row gap-1 ml-2">
              {presenceUsers.map((user, i) => (
                <span
                  key={user.presence_ref || i}
                  className="w-7 h-7 rounded-full bg-gradient-to-br from-[#F24018] to-[#FD429C] flex items-center justify-center text-white font-bold text-xs cursor-pointer"
                  title={user.name}
                >
                  {user.name?.[0]?.toUpperCase() || "?"}
                </span>
              ))}
            </div>
          </div>
          {/* Generate Button */}
          {radioId && promptQueue[0]?.id && (
            <button
              className="mt-6 w-full bg-blue-600 hover:bg-blue-700 text-white font-semibold py-2 px-4 rounded-lg transition-colors disabled:opacity-60"
              onClick={handleGenerate}
              disabled={generateLoading}
            >
              {generateLoading
                ? "Generating..."
                : generateSuccess
                ? "Generated!"
                : "Generate"}
            </button>
          )}
          {generateError && (
            <div className="text-red-500 text-xs mt-2">{generateError}</div>
          )}
        </div>
        {/* Right column: Song Card */}
        <main className="flex-1 flex flex-col items-center justify-center p-12">
          <div className="max-w-xl w-full">
            {loadedSong && (
              <SongCard
                song={loadedSong}
                isCurrent={true}
                playSong={handleRadioPlay}
                startTime={0}
              />
            )}
          </div>
        </main>
      </div>
      {/* Playbar at the bottom */}
      <RadioPlaybar
        radioId={radioId}
        customTogglePlayPause={handleRadioTogglePlayPause}
      />
    </div>
  );
}
