"use client";
import { useState, useEffect, useCallback, useRef } from "react";
import { SkipForward, SkipBack, Volume2, VolumeX, Pause, Play } from "lucide-react";
import { useSession } from "next-auth/react";
import type { DiscordServer, Track } from "@/types/music";

interface PlayerBarProps {
  selectedServer: DiscordServer | null;
}

export default function PlayerBar({ selectedServer }: PlayerBarProps) {
  const { data: session } = useSession();

  // 재생 상태 관리
  const [track, setTrack] = useState<Track | null>(null);
  const [botPlayer, setBotPlayer] = useState<boolean>(false);
  const [isPlaying, setIsPlaying] = useState<boolean>(false);
  const [isPaused, setIsPaused] = useState<boolean>(false);
  const [volume, setVolume] = useState<number>(50);

  // 시간 및 진행도 관리
  const [position, setPosition] = useState<number>(0);
  const [duration, setDuration] = useState<number>(0);
  const isDragging = useRef<boolean>(false); // 재생바를 드래그 중인지 여부
  // 👇 [추가할 부분] 볼륨 바를 잡고 있는지 여부 추적
  const [isVolumeDragging, setIsVolumeDragging] = useState<boolean>(false);

  // 1. 현재 재생 상태 불러오기 (player_now)
  const fetchNowPlaying = useCallback(async () => {
    if (!selectedServer) return;

    const userId = session?.user?.id;
    if (!userId) return;

    try {
      const res = await fetch('/api/player/now', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          serverId: selectedServer.id,
          userId: userId,
        })
      });
      const data = await res.json();

      if (res.ok && data.success && data.track) {
        setBotPlayer(Boolean(data.botPlayer));
        setIsPlaying(Boolean(data.isPlaying));
        setIsPaused(Boolean(data.isPaused));
        setTrack(data.track as Track);
        setDuration(Number(data.track?.info?.length ?? 0) || 0);
        setVolume(typeof data.volume === "number" ? data.volume : 50);
        // 드래그 중이 아닐 때만 서버 시간으로 동기화 (안 그러면 드래그할 때 튐)
        if (!isDragging.current) {
          setPosition(data.position || 0);
        }
      } else {
        setTrack(null);
        setIsPlaying(false);
        setPosition(0);
        setDuration(0);
      }
    } catch (error) {
      console.error("재생 정보 불러오기 실패:", error);
    }
  }, [selectedServer, session]);

  // 2. 초기 로드 및 SSE 실시간 업데이트 수신
  useEffect(() => {
    if (!selectedServer) return;
    // 서버 선택 시 1회 즉시 동기화 — 의도적 패턴.
    // eslint-disable-next-line react-hooks/set-state-in-effect
    fetchNowPlaying();

    // 봇에서 "곡 변경", "일시정지" 등의 이벤트가 발생하면 새로고침하라는 신호
    const eventSource = new EventSource(`/api/player/events?serverId=${selectedServer.id}`);
    eventSource.onmessage = (event) => {
      try {
        const data = JSON.parse(event.data);
        if (data?.type === "player_update") {
          fetchNowPlaying();
        }
      } catch (err) {
        console.warn("SSE JSON 파싱 실패:", err);
      }
    };
    eventSource.onerror = (error) => {
      console.error("Player SSE 연결 오류:", error);
      eventSource.close();
    };
    return () => eventSource.close();
  }, [selectedServer, fetchNowPlaying]);

  // 3. 🌟 로컬 1초 타이머 & 10초 서버 동기화 통합 (재생 중일 때만 작동!)
  // isPaused 상태를 ref 로 들고 있어서, interval 콜백이 항상 최신 값을 읽도록 처리.
  const isPausedRef = useRef(isPaused);
  useEffect(() => {
    isPausedRef.current = isPaused;
  }, [isPaused]);

  useEffect(() => {
    if (!isPlaying) return;

    // ① 1초마다 프론트엔드 단독으로 시계 굴리기 (부드러운 애니메이션용)
    const localInterval = setInterval(() => {
      if (isPausedRef.current || isDragging.current) return;
      setPosition((prev) => {
        if (prev >= duration) return duration;
        return prev + 1000;
      });
    }, 1000);

    // ② 10초마다 진짜 시간 서버에 물어보기 (오차 교정용)
    const syncInterval = setInterval(() => {
      if (isPausedRef.current || isDragging.current) return;
      fetchNowPlaying();
    }, 10000);

    // 일시정지되거나 컴포넌트가 꺼지면 두 타이머 모두 깔끔하게 청소합니다.
    return () => {
      clearInterval(localInterval);
      clearInterval(syncInterval);
    };
  }, [isPlaying, duration, fetchNowPlaying]);


  // ================= [ 컨트롤러 액션 ] =================

  // 재생/일시정지 토글 (player_pause)
  const handleTogglePause = async () => {
    if (!selectedServer || !track) return;
    if (!isPlaying) return;
    const userId = session?.user?.id;
    if (!userId) return;
    const nextPaused = !isPaused;
    // UI 즉각 반영 (Optimistic UI)
    setIsPaused(nextPaused);
    try {
      const res = await fetch('/api/player/pause', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          serverId: selectedServer.id,
          userId: userId,
          isPaused: nextPaused, // boolean 그대로 전송
        })
      });
      const data = await res.json();
      if (res.ok && data.success) {
        // 봇이 실제로 적용된 paused 상태를 돌려줌. 없으면 낙관적 값 유지.
        if (typeof data.paused === "boolean") setIsPaused(data.paused);
      } else {
        // 실패 시 롤백
        setIsPaused(!nextPaused);
      }
    } catch (error) {
      console.error("일시정지 에러:", error);
      setIsPaused(!nextPaused); // 실패 시 롤백
    }
  };

  // 다음 곡 스킵 (player_skip)
  const handleSkip = async () => {
    if (!selectedServer || !track) return;
    const userId = session?.user?.id;
    if (!userId) return;
    try {
      await fetch('/api/player/skip', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          serverId: selectedServer.id,
          userId: userId,
        })
      });
      // 성공하면 곧 SSE 이벤트가 와서 fetchNowPlaying을 트리거하겠지만, 즉각 반응을 위해 찔러줌
      setTimeout(fetchNowPlaying, 500);
    } catch (error) {
      console.error("스킵 에러:", error);
    }
  };

  // 🌟 [수정됨] 마우스 이벤트와 터치 이벤트를 모두 허용하도록 타입 변경
  const handleSeekEnd = async (e: React.MouseEvent<HTMLInputElement> | React.TouchEvent<HTMLInputElement>) => {
    if (!selectedServer || !track) return;
    const userId = session?.user?.id;
    if (!userId) return;
    isDragging.current = false;

    // 🌟 [수정됨] e.target 대신 e.currentTarget을 사용해야 타입 에러가 나지 않습니다.
    const newPosition = Number(e.currentTarget.value);

    try {
      await fetch('/api/player/seek', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          serverId: selectedServer.id,
          seek: newPosition,
          userId: userId,
        })
      });
    } catch (error) {
      console.error("시간 이동 에러:", error);
    }
  };

  // 볼륨 조절 (player_volume)
  const handleVolumeChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
    if (!selectedServer) return;
    setVolume(Number(e.target.value)); // UI 즉시 반영
  };

  // 🌟 [신규 추가] 드래그가 끝났을 때 (마우스를 뗐을 때) 딱 한 번 API 전송
  const handleVolumeEnd = async (e: React.MouseEvent<HTMLInputElement> | React.TouchEvent<HTMLInputElement>) => {
    setIsVolumeDragging(false);
    if (!selectedServer) return;
    const userId = session?.user?.id;
    if (!userId) return;
    const finalVolume = Number(e.currentTarget.value);
    setVolume(finalVolume); // UI 즉시 반영

    try {
      await fetch('/api/player/volume', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          serverId: selectedServer.id,
          userId: userId,
          volume: finalVolume,
        })
      });
    } catch (error) {
      console.error("볼륨 조절 에러:", error);
    }
  };

  // 시간 포맷 변환 함수 (ms -> mm:ss)
  const formatTime = (ms: number) => {
    if (!ms || isNaN(ms)) return "00:00";
    const totalSeconds = Math.floor(ms / 1000);
    const minutes = Math.floor(totalSeconds / 60);
    const seconds = totalSeconds % 60;
    return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
  };

  // 진행도 퍼센트 계산 (0 ~ 100)
  const progressPercent = duration > 0 ? (position / duration) * 100 : 0;

  return (
    <footer className="h-24 flex-shrink-0 bg-black border-t border-neutral-800 px-6 flex items-center justify-between z-50">

      {/* 1. 노래 정보 영역 */}
      <div className="flex items-center gap-4 w-1/4">
        {track ? (
          <>
            <div className="w-14 h-14 bg-neutral-800 rounded-md shadow-md overflow-hidden">
              {track.info?.artworkUrl && <img src={track.info.artworkUrl} alt="cover" className="w-full h-full object-cover" />}
            </div>
            <div className="flex flex-col overflow-hidden">
              <span className="text-sm font-bold text-white truncate cursor-pointer hover:underline">{track.info?.title}</span>
              <span className="text-xs text-neutral-400 truncate cursor-pointer hover:underline">{track.info?.author?.replace(" - Topic", "")}</span>
            </div>
          </>
        ) : (
          // 재생 중인 곡이 없을 때 빈 공간
          <div className="flex items-center gap-4 text-neutral-600">
            <div className="w-14 h-14 bg-neutral-900 rounded-md"></div>
            <span className="text-sm">재생 중인 곡 없음</span>
          </div>
        )}
      </div>

      {/* 2. 중앙 컨트롤러 영역 */}
      <div className="flex flex-col items-center gap-2 w-2/4 max-w-2xl">
        <div className="flex items-center gap-6">
          {/* 이전 곡 (비활성화 상태) */}
          <button className="text-neutral-600 cursor-not-allowed">
            <SkipBack size={20} />
          </button>

          {/* 재생/일시정지 버튼 */}
          <button
            onClick={handleTogglePause}
            disabled={!botPlayer || !isPlaying || !track}
            className={`w-8 h-8 rounded-full flex items-center justify-center transition-transform text-black 
              ${track ? 'bg-white hover:scale-105' : 'bg-neutral-700 cursor-not-allowed'}`}
          >
            {!isPaused ? <Pause size={18} fill="black" /> : <Play size={18} fill="black" className="ml-0.5" />}
          </button>

          {/* 다음 곡 스킵 버튼 */}
          <button
            onClick={handleSkip}
            disabled={!botPlayer || !isPlaying || !track}
            className={`transition-colors ${isPlaying && track ? 'text-neutral-400 hover:text-white' : 'text-neutral-600 cursor-not-allowed'}`}
          >
            <SkipForward size={20} />
          </button>
        </div>

        {/* 재생 바 (Range Input으로 구현하여 드래그/클릭 완벽 지원) */}
        <div className="flex items-center gap-2 w-full text-xs text-neutral-400">
          <span className="w-10 text-right">{formatTime(position)}</span>

          <div className="flex-1 flex items-center group relative h-4">
            <input
              type="range"
              min={0}
              max={duration || 100}
              value={position}
              disabled={!botPlayer || !isPlaying || !track}
              onChange={(e) => {
                isDragging.current = true;
                setPosition(Number(e.target.value)); // 드래그 중 화면 즉시 업데이트
              }}
              onMouseUp={handleSeekEnd}
              onTouchEnd={handleSeekEnd}
              className="absolute w-full h-1 opacity-0 cursor-pointer z-20"
            // ↑ 투명한 진짜 input을 덮어씌워서 클릭 이벤트를 완벽하게 받습니다.
            />
            {/* 시각적으로 보여주는 커스텀 바 */}
            <div className="w-full h-1 bg-neutral-600 rounded-full overflow-hidden absolute z-10 pointer-events-none">
              <div
                className="h-full bg-white group-hover:bg-green-500 transition-colors pointer-events-none"
                style={{ width: `${progressPercent}%` }}
              ></div>
            </div>
            {/* 동그란 핸들바 */}
            <div
              className="absolute w-3 h-3 bg-white rounded-full opacity-0 group-hover:opacity-100 shadow-md pointer-events-none z-10 -ml-1.5"
              style={{ left: `${progressPercent}%` }}
            ></div>
          </div>

          <span className="w-10">{formatTime(duration)}</span>
        </div>
      </div>

      {/* 3. 우측 볼륨 영역 */}
      <div className="flex items-center justify-end gap-3 w-1/4 text-neutral-400">
        {volume === 0 ? <VolumeX size={20} /> : <Volume2 size={20} />}

        <div className="w-24 h-4 flex items-center group relative">
          <input
            type="range"
            min={0}
            max={100}
            value={volume}
            disabled={!botPlayer || !isPlaying || !track}
            onChange={handleVolumeChange} // 눈에 보이는 볼륨만 즉시 변경
            onMouseDown={() => setIsVolumeDragging(true)}
            onTouchStart={() => setIsVolumeDragging(true)}
            onMouseUp={handleVolumeEnd}   // 🌟 마우스를 뗐을 때 봇으로 전송
            onTouchEnd={handleVolumeEnd}  // 🌟 스마트폰 터치를 뗐을 때 봇으로 전송
            className="absolute w-full h-1 opacity-0 cursor-pointer z-20"
          />
          {/* 커스텀 볼륨 바 디자인 */}
          <div className="w-full h-1 bg-neutral-600 rounded-full overflow-hidden absolute z-10 pointer-events-none">
            <div
              className="h-full bg-white group-hover:bg-green-500 transition-colors pointer-events-none"
              style={{ width: `${volume}%` }}
            ></div>
          </div>
          {/* 👇 [수정할 부분] 핸들바 안에 말풍선 툴팁 코드 추가 */}
          <div
            className="absolute w-3 h-3 bg-white rounded-full opacity-0 group-hover:opacity-100 shadow-md pointer-events-none z-10 -ml-1.5 flex justify-center"
            style={{ left: `${volume}%` }}
          >
            {/* 드래그 중(isVolumeDragging === true)일 때만 나타나는 숫자 말풍선 */}
            {isVolumeDragging && (
              <div className="absolute bottom-4 bg-neutral-800 text-white text-[10px] font-bold py-1 px-2 rounded shadow-lg border border-neutral-700 whitespace-nowrap animate-in fade-in zoom-in duration-150">
                {volume}
              </div>
            )}
          </div>
        </div>
      </div>

    </footer>
  );
}