"use client";

import React, { useState, useEffect, useRef } from 'react';
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Button } from "@/components/ui/button";
import { Phone, PhoneOff, Mic, MicOff, Volume2, VolumeX, User } from "lucide-react";
import { cn } from "@/lib/utils";
import { useCallInitiate } from '@/hooks/useWhatsApp';
import api from '@/lib/axios';
import { ApiResponseDetail } from '@/types/response';
import { CallIntiate } from '@/types/contacts';
import { v4 as uuidv4 } from "uuid";
import { useAuth } from '@/contexts/auth-context';
import useEcho from '@/lib/echo';
import { useQuery } from '@tanstack/react-query';
import { fa } from 'zod/v4/locales';

interface VoiceCallProps {
    contactName?: string;
    contactPhone?: string;
    contactAvatar?: string;
    isIncoming?: boolean;
    onEndCall?: () => void;
    onAnswer?: () => void;
    onDecline?: () => void;
}

interface CallData {
    message_id:string;
    contact_name:string;
    phone_number:string;
}

const VoiceCall: React.FC<VoiceCallProps> = ({
    contactName = "Unknown",
    contactPhone = "",
    contactAvatar,
    isIncoming = false,
    onEndCall,
    onAnswer,
    onDecline,
}) => {
    const [isMuted, setIsMuted] = useState<boolean>(false);
    const [isSpeakerOn, setIsSpeakerOn] = useState<boolean>(true);
    const [callDuration, setCallDuration] = useState(0);
    const [isCallActive, setIsCallActive] = useState(false);
    const [answer, setAnswer] = useState<boolean>(false);
    const [ringing, setRinging] = useState<boolean>(false);
    const [acceptedCall, setAcceptedCall] = useState<boolean>(false);
    const [callData, setCallData] = useState<CallData | null>(null);
    const localStreamRef = useRef<MediaStream>(null);
    const peerConnectionRef = useRef<RTCPeerConnection>(null);
    const [tabId, setTabId] = useState("");
    const TAB_ID = typeof window !== "undefined" ? Date.now().toString() : "";
    const { user } = useAuth();
    const echo = useEcho();
    const [intervalAudioCall, setIntervalAudioCall] = useState<NodeJS.Timeout | undefined>(undefined);

    const [audio, setAudio] = useState<any>(null);
    const [audioInitiate, setAudioInitiate] = useState<any>(null);

    const { isFetching, refetch: refecthTerminate } = useQuery({
        queryKey:["call-terminate"],
        queryFn:async () => api.post('/api/whatsapp/calls/terminate',{
            account_id:process.env.NEXT_PUBLIC_APP_ACCOUNT_ID_WHATSAPP_SERVICE,
            message_id: callData?.message_id,
            tabId:tabId,
            user:JSON.stringify(user)
        }).then((response) => {
            setCallData(null);
            setIsCallActive(false);
            setAnswer(false);
            setIsMuted(false);
            setRinging(false);
            setAcceptedCall(false);``
            sessionStorage.removeItem('callId');

            return response.data;
        }),
        enabled:false
    });

    const { isFetching: isFetchingInitiate, refetch: refetchInitiate } = useQuery({
        queryKey:["call-initiate"],
        queryFn:async () => {
            try {
                const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
                localStreamRef.current = stream;

                const ICE_SERVERS = [
                    { urls: "stun:stun.l.google.com:19302" }
                ];
                const pc = new RTCPeerConnection({ iceServers: ICE_SERVERS });
                stream.getTracks().forEach(t => pc.addTrack(t, stream));
                peerConnectionRef.current = pc;

                // Setup remote audio playback
                const audioElem = document.createElement('audio');
                audioElem.autoplay = true;
                pc.ontrack = e => (audioElem.srcObject = e.streams[0]);

                const offer = await pc.createOffer();
                await pc.setLocalDescription(offer);

                const response = await api.post<ApiResponseDetail<CallIntiate>>('/api/whatsapp/calls/initiate', {
                    account_id: process.env.NEXT_PUBLIC_APP_ACCOUNT_ID_WHATSAPP_SERVICE,
                    to: contactPhone,
                    sdp: offer.sdp,
                    tabId: tabId,
                    user: JSON.stringify(user)
                });

                
                setCallData({
                    message_id: response.data.data.message_id,
                    contact_name: response.data.data.contacts.name,
                    phone_number: response.data.data.contacts.phone_number,
                });

                if (!sessionStorage.getItem("callId")) {
                    sessionStorage.setItem("callId", response.data.data.message_id);
                }
                return true;
            } catch (err) {
                console.error('Error initiating call:', err);
                return false;
            }

        },
        enabled:false,
        refetchOnWindowFocus:false,
    });

    useEffect(() => {
        if (Notification.permission === "granted") {
             setAudio(new Audio("/audio/notification.wav"));
            sessionStorage.setItem('notification', !sessionStorage.getItem('notification') ? "true" : sessionStorage.getItem('notification') as string);
        } else {
            Notification.requestPermission();
        }

        setAudioInitiate(new Audio("/audio/phone-call.mp3"));


        let id = sessionStorage.getItem("tabId");
        if (!id) {
          id = uuidv4();
          sessionStorage.setItem("tabId", id);
        }
    
    
        // Coba jadi leader
        if (!localStorage.getItem("tab_leader")) {
          localStorage.setItem("tab_leader", TAB_ID);
        }
    
        // Jika tab ditutup, lepaskan posisi leader
        window.addEventListener("beforeunload", () => {
          if (localStorage.getItem("tab_leader") === TAB_ID) {
            localStorage.removeItem("tab_leader");
          }
        });
    
        // Jika leader tab ditutup, tab lain rebut posisi
        window.addEventListener("storage", (e) => {
          if (e.key === "tab_leader" && !e.newValue) {
            localStorage.setItem("tab_leader", TAB_ID);
          }
        });
    
        setTabId(id);
      }, []);

    useEffect(() => {
        if (contactPhone) {
            refetchInitiate();
        }
    }, []);

      useEffect(() => {
        if (typeof window == "undefined") return;
        if(!echo) return;
        const channel = echo?.channel(`calls.${process.env.NEXT_PUBLIC_APP_ACCOUNT_ID_WHATSAPP_SERVICE}`);

        channel.listen('.call.incoming', async (e:any) => {
            if(!sessionStorage.getItem("callId")) {
                setCallData(e);
                audio.play().catch((err:any) => {
                    console.warn("Autoplay blocked:", err);
                });
            }
           
        });

        channel.listen('.call.response', async (e:any) => {
            if(e.tabId != sessionStorage.getItem("tabId")) {
              if(!sessionStorage.getItem("callId")) {
                  setCallData(null);
                  sessionStorage.removeItem("callId");
              }
            }
        });

         channel.listen('.call.ringing', async (e:any) => {
            if(sessionStorage.getItem("callId") == e.message_id) {
              setRinging(true);
            }
        });


        channel.listen('.call.accepted', async (e:any) => {
            if(sessionStorage.getItem("callId") == e.message_id) {
              clearInterval(intervalAudioCall);
              setIsCallActive(true);
              setAcceptedCall(true);
            }
        });

        channel.listen('.call.preaccepted', async (e:any) => {
            if(sessionStorage.getItem("callId") == e.message_id) {
              const fixedSdp = fixSdp(e.sdp);
              if(fixedSdp) {
                 await peerConnectionRef.current?.setRemoteDescription({ type: 'answer', sdp: fixedSdp });
              }
            }
        });
        

        channel.listen('.call.end', async (e:any) => {
          if(sessionStorage.getItem("callId") == e.message_id) {
            localStreamRef.current?.getTracks().forEach(track => {
              track.stop(); // ini mematikan microphone & kamera
            });
            peerConnectionRef.current?.close();
            setIsCallActive(false);
            setIsMuted(false);
            setRinging(false);
            setAnswer(false);
            setAcceptedCall(false);
            setCallData(null);
            onEndCall?.();
            sessionStorage.removeItem('callId');
          }
        });
  
        return () => {
            echo?.leave(`calls.${process.env.NEXT_PUBLIC_APP_ACCOUNT_ID_WHATSAPP_SERVICE}`);
        }
    },[echo]);

    useEffect(() => {
        let interval: NodeJS.Timeout;
        if (isCallActive) {
            interval = setInterval(() => {
                setCallDuration((prev) => prev + 1);
            }, 1000);
        }
        return () => {
            if (interval) clearInterval(interval);
        };
    }, [isCallActive]);


    useEffect(() => {
        const interval = setInterval(() => {
            if (audioInitiate) {
                audioInitiate.play().catch((err:any) => {
                    console.warn("Autoplay blocked:", err);
                });
            }
        }, 1000);
        setIntervalAudioCall(interval);
    }, []);

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

    const fixSdp = (offerSdp:string) => {
        let sdp = offerSdp
        // hapus baris SSRC yang invalid
        .split('\r\n')
        .filter(line => !line.startsWith('a=ssrc:'))
        .join('\r\n');
  
        // pastikan line terminator benar
        if (!sdp.endsWith('\r\n')) sdp += '\r\n';
  
        return sdp;
      }
  

    const handleAnswer = () => {
        setIsCallActive(true);
        onAnswer?.();
    };

   
    
    const handleEndCall = async () => {
        setIsCallActive(false);
        localStreamRef.current?.getTracks().forEach(track => {
            track.stop(); // ini mematikan microphone & kamera
        });

        peerConnectionRef.current?.close();

        refecthTerminate();

        onEndCall?.();
    };

    const handleDecline = () => {
        onDecline?.();
    };

    const handleMute = (value:boolean) => {
        setIsMuted(value);
        localStreamRef.current?.getTracks().forEach(track => track.enabled = value);
    }

    const handleSpeaker = async (value: boolean) => {
        setIsSpeakerOn(value);
    }

    return (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-gradient-to-br from-[#075e54] via-[#128c7e] to-[#25d366] dark:from-[#0b141a] dark:via-[#1e2a35] dark:to-[#2a3942]">
            {/* Background Pattern */}
            <div className="absolute inset-0 opacity-10">
                <div className="absolute inset-0 bg-[url('/whatsapp-bg-light.png')] bg-repeat dark:opacity-0"></div>
                <div className="absolute inset-0 bg-[url('/wa-bg-dark.png')] bg-repeat opacity-0 dark:opacity-100"></div>
            </div>

            <div className="relative z-10 flex flex-col items-center justify-center w-full h-full px-6 py-12">
                {/* Contact Info */}
                <div className="flex flex-col items-center mb-12 space-y-4">
                    <div className="relative">
                        <Avatar className="w-32 h-32 border-4 border-white/20 dark:border-gray-700/20">
                            <AvatarImage src={contactAvatar} alt={contactName} />
                            <AvatarFallback className="text-4xl bg-white/10 dark:bg-gray-800/50 text-white">
                                {contactName[0]?.toUpperCase() || <User className="w-16 h-16" />}
                            </AvatarFallback>
                        </Avatar>
                        {isCallActive && (
                            <div className="absolute inset-0 flex items-center justify-center">
                                <div className="absolute w-32 h-32 rounded-full bg-white/20 animate-ping"></div>
                                <div className="absolute w-32 h-32 rounded-full bg-white/10 animate-pulse"></div>
                            </div>
                        )}
                    </div>

                    <div className="text-center">
                        <h2 className="text-3xl font-semibold text-white mb-2">{contactName}</h2>
                        {contactPhone && (
                            <p className="text-lg text-white/80 mb-2">{contactPhone}</p>
                        )}
                        {isCallActive ? (
                            <p className="text-base text-white/70">{formatDuration(callDuration)}</p>
                        ) : isIncoming ? (
                            <p className="text-base text-white/70">Panggilan Masuk...</p>
                        ) : (
                            ringing ? 
                            <p className="text-base text-white/70">Berdering...</p>
                            :
                            <p className="text-base text-white/70">Memanggil...</p>
                        )}
                    </div>
                </div>

                {/* Call Controls */}
                <div className="flex flex-col items-center gap-6 w-full max-w-md">
                    {/* Control Buttons Row */}
                    {isCallActive ? (
                        <div className="flex items-center justify-center gap-4">
                            {/* Mute Button */}
                            <Button
                                onClick={() => handleMute(!isMuted)}
                                className={cn(
                                    "rounded-full w-14 h-14 p-0",
                                    isMuted
                                        ? "bg-white/20 hover:bg-white/30 text-white backdrop-blur-sm"
                                        : "bg-red-500 hover:bg-red-600 text-white"
                                )}
                                variant="ghost"
                            >
                                {isMuted ? (
                                    <Mic className="w-6 h-6" />
                                ) : (
                                    <MicOff className="w-6 h-6" />
                                )}
                            </Button>

                            {/* Speaker Button */}
                            <Button
                                onClick={() => handleSpeaker(!isSpeakerOn)}
                                className={cn(
                                    "rounded-full w-14 h-14 p-0",
                                    isSpeakerOn
                                        ? "bg-white/20 hover:bg-white/30 text-white backdrop-blur-sm"
                                        : "bg-green-500 hover:bg-green-600 text-white" 
                                )}
                                variant="ghost"
                            >
                                {isSpeakerOn ? (
                                    <Volume2 className="w-6 h-6" />
                                ) : (
                                    <VolumeX className="w-6 h-6" />
                                )}
                            </Button>
                        </div>
                    ) : null}

                    {/* Action Buttons Row */}
                    <div className="flex items-center justify-center gap-6">
                        {isIncoming && !isCallActive ? (
                            <>
                                {/* Decline Button */}
                                <Button
                                    onClick={handleDecline}
                                    className="rounded-full w-16 h-16 p-0 bg-red-500 hover:bg-red-600 text-white shadow-lg"
                                    variant="ghost"
                                >
                                    <PhoneOff className="w-8 h-8" />
                                </Button>

                                {/* Answer Button */}
                                <Button
                                    onClick={handleAnswer}
                                    className="rounded-full w-16 h-16 p-0 bg-green-500 hover:bg-green-600 text-white shadow-lg"
                                    variant="ghost"
                                >
                                    <Phone className="w-8 h-8" />
                                </Button>
                            </>
                        ) : (
                            /* End Call Button */
                            <Button
                                onClick={handleEndCall}
                                className="rounded-full w-16 h-16 p-0 bg-red-500 hover:bg-red-600 text-white shadow-lg"
                                variant="ghost"
                            >
                                <PhoneOff className="w-8 h-8" />
                            </Button>
                        )}
                    </div>
                </div>
            </div>
        </div>
    );
};

export default VoiceCall;
