import { useStore } from '../store';
import { Phone, PhoneOff, Mic, MicOff, Video, VideoOff } from 'lucide-react';
import { motion, AnimatePresence } from 'framer-motion';
import { useState, useEffect, useRef } from 'react';
import { socket } from '../socket';

export function CallOverlay() {
  const { activeCall, endCall, currentUser, incrementMissedCalls } = useStore();
  
  const [micMuted, setMicMuted] = useState(false);
  const [videoMuted, setVideoMuted] = useState(false);
  
  const [stream, setStream] = useState(null);
  const [callAccepted, setCallAccepted] = useState(false);
  const [videoActive, setVideoActive] = useState(false);
  const [incomingVideoRequest, setIncomingVideoRequest] = useState(false);
  const [isRequestingVideo, setIsRequestingVideo] = useState(false);

  
  const localVideoRef = useRef(null);
  const remoteVideoRef = useRef(null);
  const connectionRef = useRef(null);
  
  const leaveCall = () => {
    if (connectionRef.current) connectionRef.current.close();
    
    // Stop local media defensively via both state and active ref source
    if (stream) {
      stream.getTracks().forEach(track => track.stop());
    }
    if (localVideoRef.current && localVideoRef.current.srcObject) {
      localVideoRef.current.srcObject.getTracks().forEach(track => track.stop());
      localVideoRef.current.srcObject = null;
    }
    
    // Notify peer
    if (activeCall) {
      const peerId = activeCall.callerId === currentUser?.id ? activeCall.receiverId : activeCall.callerId;
      socket.emit('end-call', { to: peerId });
    }

    setStream(null);
    setCallAccepted(false);
    endCall();
  };

  // We need to listen to incoming calls globally even if not in an active call state
  useEffect(() => {
    socket.on('incoming-call', (data) => {
      // Setup incoming state in store manually by injecting it
      useStore.setState({
        activeCall: {
          callerId: data.from,
          callerName: data.callerName,
          callerSelfie: data.callerSelfie,
          receiverId: currentUser?.id,
          receiverName: currentUser?.name,
          receiverSelfie: currentUser?.selfiePath,
          status: 'ringing',
          signalData: data.signal // Stashed for answering
        }
      });

      if ("Notification" in window && Notification.permission === "granted") {
        new Notification("Incoming Call \u260E\uFE0F", { 
          body: `${data.callerName} is calling you on Meri Mandi!`,
          icon: data.callerSelfie || '/upiqr.jpeg'
        });
      }
    });

    socket.on('call-ended', () => {
      leaveCall();
    });

    socket.on('missed-call', () => {
      incrementMissedCalls();
      leaveCall();
    });

    socket.on('video-requested', () => {
      setIncomingVideoRequest(true);
    });

    socket.on('video-accepted', () => {
      setIsRequestingVideo(false);
      enableVideoTrack();
    });

    socket.on('video-rejected', () => {
      setIsRequestingVideo(false);
      alert("Video call request was declined.");
    });

    return () => {
      socket.off('incoming-call');
      socket.off('call-ended');
      socket.off('missed-call');
      socket.off('video-requested');
      socket.off('video-accepted');
      socket.off('video-rejected');
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [currentUser]);

  // Timeout logic (60 seconds)
  useEffect(() => {
    let timeoutId;
    if (activeCall && activeCall.status === 'ringing') {
      timeoutId = setTimeout(() => {
        const peerId = activeCall.callerId === currentUser?.id ? activeCall.receiverId : activeCall.callerId;
        if (activeCall.receiverId === currentUser?.id) {
          // I didn't answer - increment my missed calls
          incrementMissedCalls();
        }
        // Notify other party
        socket.emit('missed-call', { to: peerId });
        leaveCall();
      }, 60000); 
    }
    return () => clearTimeout(timeoutId);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [activeCall]);

  // When activeCall becomes truthy and we are the CALLER (initiating), setup streams.
  useEffect(() => {
    if (activeCall && !stream && !callAccepted && activeCall.callerId === currentUser?.id) {
      navigator.mediaDevices.getUserMedia({ video: false, audio: true }).then((currentStream) => {
        setStream(currentStream);
        if (localVideoRef.current) localVideoRef.current.srcObject = currentStream;
        
        // Setup Peer Connection
        const peer = new RTCPeerConnection({ iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] });
        
        currentStream.getTracks().forEach(track => peer.addTrack(track, currentStream));
        
        peer.ontrack = (event) => {
          if (remoteVideoRef.current) {
            remoteVideoRef.current.srcObject = event.streams[0];
          }
        };

        peer.onicecandidate = (event) => {
          if (event.candidate) {
            // ICE handling omitted for simplicity in this exact demo, or bundled in offer
          }
        };

        peer.createOffer().then(offer => {
          peer.setLocalDescription(offer);
          socket.emit('call-user', {
            userToCall: activeCall.receiverId,
            signalData: offer,
            from: currentUser.id,
            callerName: currentUser.name,
            callerSelfie: currentUser.selfiePath
          });
        });

        socket.on('call-accepted', (signal) => {
          setCallAccepted(true);
          peer.setRemoteDescription(new RTCSessionDescription(signal));
        });

        connectionRef.current = peer;
      }).catch(err => {
        console.error("Failed to get media", err);
        alert("Camera and Mic permissions are required for calling");
        endCall();
      });
    }

    // Cleanup when overlay completely unmounts
    return () => {
      if (!activeCall) {
        socket.off('call-accepted');
      }
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [activeCall, stream, currentUser]);


  const answerCall = () => {
    if (!activeCall || !activeCall.signalData) return;

    setCallAccepted(true);
    useStore.setState({ activeCall: { ...activeCall, status: 'connected' } });

    navigator.mediaDevices.getUserMedia({ video: false, audio: true }).then((currentStream) => {
      setStream(currentStream);
      if (localVideoRef.current) localVideoRef.current.srcObject = currentStream;

      const peer = new RTCPeerConnection({ iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] });
      
      currentStream.getTracks().forEach(track => peer.addTrack(track, currentStream));
      
      peer.ontrack = (event) => {
        if (remoteVideoRef.current) {
          remoteVideoRef.current.srcObject = event.streams[0];
        }
      };

      peer.setRemoteDescription(new RTCSessionDescription(activeCall.signalData)).then(() => {
        peer.createAnswer().then(answer => {
          peer.setLocalDescription(answer);
          socket.emit('answer-call', { signal: answer, to: activeCall.callerId });
        });
      });

      connectionRef.current = peer;
    });
  };

  const toggleMic = () => {
    if (stream) {
      stream.getAudioTracks()[0].enabled = micMuted;
      setMicMuted(!micMuted);
    }
  };

  const requestVideo = () => {
    const peerId = activeCall.callerId === currentUser?.id ? activeCall.receiverId : activeCall.callerId;
    setIsRequestingVideo(true);
    socket.emit('request-video', { to: peerId, from: currentUser.id });
  };

  const acceptVideo = () => {
    const peerId = activeCall.callerId === currentUser?.id ? activeCall.receiverId : activeCall.callerId;
    setIncomingVideoRequest(false);
    socket.emit('accept-video', { to: peerId });
    enableVideoTrack();
  };

  const rejectVideo = () => {
    const peerId = activeCall.callerId === currentUser?.id ? activeCall.receiverId : activeCall.callerId;
    setIncomingVideoRequest(false);
    socket.emit('reject-video', { to: peerId });
  };

  const enableVideoTrack = async () => {
    try {
      const videoStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: false });
      const videoTrack = videoStream.getVideoTracks()[0];
      
      if (stream) {
        stream.addTrack(videoTrack);
        if (localVideoRef.current) localVideoRef.current.srcObject = stream;
      }

      if (connectionRef.current) {
        const senders = connectionRef.current.getSenders();
        const videoSender = senders.find(s => s.track && s.track.kind === 'video');
        if (videoSender) {
          videoSender.replaceTrack(videoTrack);
        } else {
          connectionRef.current.addTrack(videoTrack, stream);
        }
      }
      setVideoActive(true);
      setVideoMuted(false);
    } catch (err) {
      console.error("Failed to start video", err);
    }
  };

  const toggleVideo = () => {
    if (!videoActive) {
      requestVideo();
      return;
    }
    if (stream && stream.getVideoTracks().length > 0) {
      const track = stream.getVideoTracks()[0];
      track.enabled = videoMuted;
      setVideoMuted(!videoMuted);
    }
  };

  if (!activeCall) return null;

  const isRinging = activeCall.status === 'ringing';
  const isIncoming = activeCall.receiverId === currentUser?.id && isRinging;
  const isOutgoing = activeCall.callerId === currentUser?.id;
  const peerSelfie = isOutgoing ? activeCall.receiverSelfie : activeCall.callerSelfie;

  return (
    <AnimatePresence>
      <motion.div 
        initial={{ opacity: 0, scale: 0.9 }} 
        animate={{ opacity: 1, scale: 1 }} 
        exit={{ opacity: 0, scale: 0.9 }}
        style={{
          position: 'fixed',
          top: 0, left: 0, right: 0, bottom: 0,
          background: 'rgba(6, 9, 7, 0.95)',
          backdropFilter: 'blur(20px)',
          zIndex: 9999,
          display: 'flex',
          flexDirection: 'column',
          alignItems: 'center',
          justifyContent: 'center',
          padding: '24px'
        }}
      >
        {/* Remote Video / Avatar Container */}
        <div style={{ textAlign: 'center', width: '100%', maxWidth: '400px', flex: 1, display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center' }}>
          
          <div style={{
            position: 'relative',
            width: callAccepted ? '100%' : '140px', 
            height: callAccepted ? '60vh' : '140px',
            borderRadius: callAccepted ? '24px' : '50%',
            overflow: 'hidden',
            background: 'linear-gradient(135deg, #10b981, #059669)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            fontSize: '48px', fontWeight: 700,
            transition: 'all 0.5s cubic-bezier(0.4, 0, 0.2, 1)',
            boxShadow: callAccepted ? '0 20px 50px rgba(0,0,0,0.5)' : '0 0 50px var(--primary-glow)',
            animation: isRinging ? 'pulse-ring 2s infinite' : 'none'
          }}>
            {/* Live Native Video */}
            <video 
              playsInline 
              ref={remoteVideoRef} 
              autoPlay 
              style={{ width: '100%', height: '100%', objectFit: 'cover', display: videoActive ? 'block' : 'none' }} 
            />
            
            {/* Fallback Static Avatar */}
            {!videoActive && (peerSelfie ? (
              <img src={peerSelfie} alt="Peer Selfie" style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
            ) : (
              isOutgoing ? activeCall.receiverName.charAt(0) : activeCall.callerName.charAt(0)
            ))}

            {/* Picture-in-Picture Local Viewer */}
            {videoActive && (
              <div style={{
                position: 'absolute', bottom: 16, right: 16,
                width: '100px', height: '150px', borderRadius: '12px',
                overflow: 'hidden', border: '2px solid white',
                background: '#000'
              }}>
                <video playsInline ref={localVideoRef} autoPlay muted style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
              </div>
            )}
          </div>
          
          <AnimatePresence>
            {incomingVideoRequest && (
              <motion.div 
                initial={{ opacity: 0, y: 10 }}
                animate={{ opacity: 1, y: 0 }}
                style={{
                  background: 'var(--primary-glow)', padding: '16px 24px', borderRadius: '16px', 
                  marginTop: '20px', border: '1px solid var(--primary-color)', textAlign: 'center'
                }}
              >
                <p style={{ fontWeight: 600, marginBottom: '12px' }}>Requesting Video Call...</p>
                <div style={{ display: 'flex', gap: '12px' }}>
                  <button onClick={rejectVideo} className="btn-secondary" style={{ padding: '8px 16px', fontSize: '14px' }}>Decline</button>
                  <button onClick={acceptVideo} className="btn-primary" style={{ padding: '8px 16px', fontSize: '14px' }}>Accept Video</button>
                </div>
              </motion.div>
            )}
            
            {isRequestingVideo && (
              <motion.div 
                initial={{ opacity: 0, y: 10 }}
                animate={{ opacity: 1, y: 0 }}
                style={{
                  background: 'var(--surface-color)', padding: '12px 20px', borderRadius: '12px', 
                  marginTop: '20px', border: '1px solid var(--border-color)', fontSize: '14px'
                }}
              >
                Waiting for video call acceptance...
              </motion.div>
            )}
          </AnimatePresence>
          
          <h2 style={{ fontSize: '32px', marginBottom: '8px', marginTop: '24px' }}>
            {isOutgoing ? activeCall.receiverName : activeCall.callerName}
          </h2>
          <p style={{ color: 'var(--text-muted)', fontSize: '18px' }}>
            {isRinging ? (isIncoming ? 'Incoming Call...' : 'Ringing...') : 'Connected Securely'}
          </p>
        </div>

        {/* Action Controls */}
        <div style={{ display: 'flex', gap: '24px', alignItems: 'center', marginTop: 'auto', marginBottom: '40px' }}>
          {(!isRinging || callAccepted) && (
            <>
              <button 
                className="btn-icon-circular" 
                onClick={toggleMic}
                style={{ width: '56px', height: '56px', background: micMuted ? 'var(--danger-color)' : 'var(--surface-color)', color: 'white' }}
              >
                {micMuted ? <MicOff size={24} /> : <Mic size={24} />}
              </button>
              <button 
                className="btn-icon-circular btn-call-reject" 
                onClick={leaveCall}
                style={{ width: '72px', height: '72px' }}
              >
                <PhoneOff size={32} />
              </button>
              <button 
                className="btn-icon-circular" 
                onClick={toggleVideo}
                disabled={isRequestingVideo || incomingVideoRequest}
                style={{ 
                  width: '56px', height: '56px', 
                  background: !videoActive ? 'var(--surface-color)' : (videoMuted ? 'var(--danger-color)' : 'var(--primary-color)'), 
                  color: 'white',
                  animation: !videoActive ? 'pulse-ring 2s infinite' : 'none'
                }}
              >
                {videoMuted ? <VideoOff size={24} /> : <Video size={24} />}
              </button>
            </>
          )}

          {isIncoming && isRinging && (
            <div style={{ display: 'flex', gap: '40px' }}>
              <button 
                className="btn-icon-circular btn-call-reject" 
                onClick={leaveCall}
                style={{ width: '72px', height: '72px' }}
              >
                <PhoneOff size={32} />
              </button>
              <button 
                className="btn-icon-circular btn-call-accept" 
                onClick={answerCall}
                style={{ width: '72px', height: '72px' }}
              >
                <Phone size={32} />
              </button>
            </div>
          )}

          {isOutgoing && isRinging && !callAccepted && (
            <button 
              className="btn-icon-circular btn-call-reject" 
              onClick={leaveCall}
              style={{ width: '72px', height: '72px' }}
            >
              <PhoneOff size={32} />
            </button>
          )}
        </div>
      </motion.div>
    </AnimatePresence>
  );
}
