'use client';

import { useEffect, useRef, useState } from 'react';
import { useSearchParams, useRouter } from 'next/navigation';
import { useSocket } from '@/context/SocketContext';
import { useAuthStore } from '@/stores/authStore';
import { Button } from '@/components/ui/button';
import {
  Mic,
  MicOff,
  Video,
  VideoOff,
  RefreshCcw,
  PhoneOff
} from 'lucide-react';

export default function VideoCallPage() {
  const searchParams = useSearchParams();
  const router = useRouter();
  const roomId = searchParams.get('roomId');
  const participantName = 'Participant';
  const user = useAuthStore((state) => state.user);
  const { socket } = useSocket();

  const localVideoRef = useRef(null);
  const remoteVideoRef = useRef(null);
  const peerConnectionRef = useRef(null);
  const localStreamRef = useRef(null);

  const [localStream, setLocalStream] = useState(null);
  const [isMuted, setIsMuted] = useState(false);
  const [isVideoOn, setIsVideoOn] = useState(true);
  const [isCaller, setIsCaller] = useState(false);
  const [showConfirm, setShowConfirm] = useState(false);

  const remoteDescriptionSet = useRef(false);
  const pendingCandidates = useRef([]);
  const hasCreatedOffer = useRef(false);
  const hasInitialized = useRef(false);

  const forceReload = (reason) => {
    console.warn(`Force reload triggered: ${reason}`);
    setTimeout(() => window.location.reload(), 1000);
  };

  useEffect(() => {
    if (!socket || !roomId || !user?.id || hasInitialized.current) return;
    hasInitialized.current = true;

    const pc = new RTCPeerConnection();
    peerConnectionRef.current = pc;

    const initCall = async () => {
      try {
        const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
        setLocalStream(stream);
        localStreamRef.current = stream;

        if (localVideoRef.current) {
          localVideoRef.current.srcObject = stream;
        }


        if (pc.signalingState !== 'closed') {
          stream.getTracks().forEach((track) => {
            try {
              pc.addTrack(track, stream);
            } catch (err) {
              console.error('Track add failed:', err);
            }
          });
        } else {
          console.warn('RTCPeerConnection is closed before tracks could be added.');
        }

        pc.ontrack = (event) => {
          if (remoteVideoRef.current) {
            remoteVideoRef.current.srcObject = event.streams[0];
          }
        };

        pc.onicecandidate = (event) => {
          if (event.candidate) {
            socket.emit('ice-candidate', { roomId, candidate: event.candidate });
          }
        };

        // socket.emit('join-room', { roomId });
        const currentUserId = user?.id;
        const targetUserId = searchParams.get('targetUserId');

        socket.emit('join-room', { roomId, userId: currentUserId, targetUserId });


        socket.on('initiate-offer', async () => {
          if (hasCreatedOffer.current || pc.signalingState === 'closed') return;
          hasCreatedOffer.current = true;
          try {
            setIsCaller(true);
            const offer = await pc.createOffer();
            await pc.setLocalDescription(offer);
            socket.emit('offer', { roomId, offer });
          } catch (err) {
            console.error('Error creating offer:', err);
          }
        });

        socket.on('offer', async ({ offer }) => {
          try {
            if (remoteDescriptionSet.current || pc.signalingState === 'closed') return;
            await pc.setRemoteDescription(new RTCSessionDescription(offer));
            remoteDescriptionSet.current = true;

            const answer = await pc.createAnswer();
            await pc.setLocalDescription(answer);
            socket.emit('answer', { roomId, answer });

            pendingCandidates.current.forEach((candidate) => {
              pc.addIceCandidate(new RTCIceCandidate(candidate));
            });
            pendingCandidates.current = [];
          } catch (err) {
            console.error('Error handling offer:', err);
          }
        });

        socket.on('answer', async ({ answer }) => {
          try {
            if (remoteDescriptionSet.current || pc.signalingState === 'closed') return;
            await pc.setRemoteDescription(new RTCSessionDescription(answer));
            remoteDescriptionSet.current = true;

            pendingCandidates.current.forEach((candidate) => {
              pc.addIceCandidate(new RTCIceCandidate(candidate));
            });
            pendingCandidates.current = [];
          } catch (err) {
            console.error('Error handling answer:', err);
          }
        });

        socket.on('ice-candidate', ({ candidate }) => {
          if (!candidate || pc.signalingState === 'closed') return;
          const iceCandidate = new RTCIceCandidate(candidate);
          if (remoteDescriptionSet.current) {
            pc.addIceCandidate(iceCandidate);
          } else {
            pendingCandidates.current.push(candidate);
          }
        });
      } catch (err) {
        console.error('Error initializing call:', err);
      }
    };

    initCall();

    return () => {
      hasInitialized.current = false;

      if (peerConnectionRef.current) {
        try {
          peerConnectionRef.current.close();
        } catch (e) {
          console.warn('Error closing peer connection:', e);
        }
        peerConnectionRef.current = null;
      }

      if (localStreamRef.current) {
        localStreamRef.current.getTracks().forEach((track) => track.stop());
        localStreamRef.current = null;
      }

      socket?.emit('leave-room', roomId);
      socket?.off('offer');
      socket?.off('answer');
      socket?.off('ice-candidate');
      socket?.off('initiate-offer');
    };
  }, [socket, roomId, user?.id]);

  const toggleMute = () => {
    if (!localStreamRef.current) return;
    const audioTrack = localStreamRef.current.getAudioTracks()[0];
    if (audioTrack) {
      audioTrack.enabled = !audioTrack.enabled;
      setIsMuted(!audioTrack.enabled);
    }
  };

  const toggleVideo = () => {
    if (!localStreamRef.current) return;
    const videoTrack = localStreamRef.current.getVideoTracks()[0];
    if (videoTrack) {
      videoTrack.enabled = !videoTrack.enabled;
      setIsVideoOn(videoTrack.enabled);
    }
  };

  const leaveRoom = () => {
    if (socket && roomId) {
      socket.emit('leave-room', roomId);
      socket.off('offer');
      socket.off('answer');
      socket.off('ice-candidate');
      socket.off('initiate-offer');
    }

    if (peerConnectionRef.current) {
      try {
        peerConnectionRef.current.close();
      } catch (e) {
        console.warn('Error closing peer connection:', e);
      }
      peerConnectionRef.current = null;
    }

    if (localStreamRef.current) {
      localStreamRef.current.getTracks().forEach((track) => track.stop());
      localStreamRef.current = null;
    }

    setLocalStream(null);
    router.push(user?.role ? `/dashboard/${user.role}` : '/');
  };

  return (
    <div className="flex flex-col items-center justify-center min-h-screen bg-gray-950 text-white px-4 py-8">
      <h2 className="text-2xl md:text-3xl font-semibold mb-6 text-center">Video Consultation Room</h2>

      <div className="flex flex-col md:flex-row items-center justify-center gap-6 mb-6 w-full max-w-5xl">
        <div className="relative w-full md:w-1/2 aspect-video bg-black rounded-xl shadow-lg overflow-hidden">
          <video ref={localVideoRef} autoPlay muted playsInline className="w-full h-full object-cover" />
          <p className="absolute bottom-2 left-2 text-sm bg-black/60 px-2 py-1 rounded text-white">You</p>
        </div>

        <div className="relative w-full md:w-1/2 aspect-video bg-black rounded-xl shadow-lg overflow-hidden">
          <video ref={remoteVideoRef} autoPlay playsInline className="w-full h-full object-cover" />
          <p className="absolute bottom-2 left-2 text-sm bg-black/60 px-2 py-1 rounded text-white">{participantName}</p>
        </div>
      </div>

      <div className="flex flex-wrap justify-center gap-4 mt-4">
        <Button onClick={toggleMute} className="flex items-center gap-2">
          {isMuted ? <MicOff size={20} /> : <Mic size={20} />}
          {isMuted ? 'Unmute' : 'Mute'}
        </Button>
        <Button onClick={toggleVideo} className="flex items-center gap-2">
          {isVideoOn ? <VideoOff size={20} /> : <Video size={20} />}
          {isVideoOn ? 'Turn Off Video' : 'Turn On Video'}
        </Button>
        <Button onClick={() => forceReload('manual')} className="flex items-center gap-2">
          <RefreshCcw size={20} />
          Reload
        </Button>
        <Button
          onClick={() => setShowConfirm(true)}
          className="bg-red-600 hover:bg-red-700 text-white flex items-center gap-2"
        >
          <PhoneOff size={20} />
          Leave Call
        </Button>
      </div>

      {showConfirm && (
        <div className="fixed inset-0 flex items-center justify-center bg-black bg-opacity-60 z-50">
          <div className="bg-white text-black p-6 rounded-xl w-full max-w-sm shadow-lg text-center space-y-4">
            <p className="text-lg font-medium">Are you sure you want to leave the call?</p>
            <div className="flex justify-center gap-4">
              <Button
                onClick={() => {
                  setShowConfirm(false);
                  leaveRoom();
                }}
                className="bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded-md"
              >
                Yes, Leave
              </Button>
              <Button
                onClick={() => setShowConfirm(false)}
                className="bg-gray-200 hover:bg-gray-300 text-black px-4 py-2 rounded-md"
              >
                Cancel
              </Button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
