import React, { useState, useRef, useEffect } from 'react';
import { SearchIcon, SendIcon, PaperclipIcon, SmileIcon, ArrowLeftIcon, ChatIcon, MicrophoneIcon, Trash2Icon, FileIcon, PlayIcon, PauseIcon } from '../Icons';

interface Message {
  id: number;
  text?: string;
  audio?: { url: string; duration: number };
  file?: { url: string; name: string; type: string };
  timestamp: string;
  sender: 'me' | 'them';
}

interface Chat {
  id: number;
  user: {
    name: string;
    avatar: string;
    online: boolean;
  };
  lastMessage: string;
  timestamp: string;
  unreadCount: number;
  messages: Message[];
}

const initialChats: Chat[] = [
  {
    id: 1,
    user: { name: 'علی رضایی', avatar: 'https://picsum.photos/id/1005/100/100', online: true },
    lastMessage: 'باشه حتما، فردا هماهنگ می‌کنم.',
    timestamp: '۵ دقیقه پیش',
    unreadCount: 2,
    messages: [
      { id: 1, text: 'سلام، بسته من کی به دستم میرسه؟', timestamp: '۱۰:۳۰', sender: 'them' },
      { id: 2, text: 'سلام علی جان، لطفاً شماره سفارشت رو بفرست.', timestamp: '۱۰:۳۱', sender: 'me' },
      { id: 3, text: 'شماره سفارش ۱۲۳۴۵ هست.', timestamp: '۱۰:۳۲', sender: 'them' },
      { id: 4, text: 'ممنون. در حال بررسی هستم...', timestamp: '۱۰:۳۳', sender: 'me' },
      { id: 5, text: 'باشه حتما، فردا هماهنگ می‌کنم.', timestamp: '۱۰:۳۵', sender: 'them' }
    ]
  },
  {
    id: 2,
    user: { name: 'زهرا احمدی', avatar: 'https://picsum.photos/id/1011/100/100', online: false },
    lastMessage: 'ممنونم از راهنماییتون.',
    timestamp: '۲ ساعت پیش',
    unreadCount: 0,
    messages: [
      { id: 1, text: 'سلام، وقت بخیر', timestamp: '۰۸:۱۵', sender: 'them' },
      { id: 2, text: 'سلام خانم احمدی، در خدمتم.', timestamp: '۰۸:۱۶', sender: 'me' },
      { id: 3, text: 'میخواستم در مورد وضعیت سفرم بپرسم.', timestamp: '۰۸:۱۷', sender: 'them' },
      { id: 4, text: 'سفر شما طبق برنامه در حال انجام است.', timestamp: '۰۸:۲۰', sender: 'me' },
      { id: 5, text: 'ممنونم از راهنماییتون.', timestamp: '۰۸:۲۱', sender: 'them' },
    ]
  },
  {
    id: 3,
    user: { name: 'پشتیبانی', avatar: 'https://picsum.photos/id/1025/100/100', online: true },
    lastMessage: 'خواهش میکنم، روز خوبی داشته باشید.',
    timestamp: 'دیروز',
    unreadCount: 0,
    messages: [
       { id: 1, text: 'مشکل گزارش شده شما بررسی و حل شد.', timestamp: 'دیروز', sender: 'them' },
       { id: 2, text: 'خیلی ممنون از پیگیری شما.', timestamp: 'دیروز', sender: 'me' },
       { id: 3, text: 'خواهش میکنم، روز خوبی داشته باشید.', timestamp: 'دیروز', sender: 'them' },
    ]
  },
   {
    id: 4,
    user: { name: 'محمد قاسمی', avatar: 'https://picsum.photos/id/1027/100/100', online: false },
    lastMessage: 'آدرس رو لطف می‌کنید؟',
    timestamp: '۳ روز پیش',
    unreadCount: 1,
    messages: [
      { id: 1, text: 'آدرس رو لطف می‌کنید؟', timestamp: '۳ روز پیش', sender: 'them' },
    ]
  }
];

const MessagesPage: React.FC = () => {
    const [chats, setChats] = useState<Chat[]>(initialChats);
    const [selectedChatId, setSelectedChatId] = useState<number | null>(initialChats[0]?.id || null);
    const [newMessage, setNewMessage] = useState('');
    const [isRecording, setIsRecording] = useState(false);
    const [recordingDuration, setRecordingDuration] = useState(0);

    const messagesEndRef = useRef<HTMLDivElement>(null);
    const fileInputRef = useRef<HTMLInputElement>(null);
    const mediaRecorderRef = useRef<MediaRecorder | null>(null);
    const recordingTimerRef = useRef<ReturnType<typeof setInterval> | null>(null);
    const audioChunksRef = useRef<Blob[]>([]);
    const shouldSendAudioRef = useRef(false);
    const mimeTypeRef = useRef<string | null>(null);
    const chatsRef = useRef(chats);
    chatsRef.current = chats;

    const selectedChat = chats.find(c => c.id === selectedChatId);

    const scrollToBottom = () => {
        messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
    }

    useEffect(() => {
        if (selectedChatId) {
            scrollToBottom()
        }
    }, [selectedChat?.messages, selectedChatId]);
    
    useEffect(() => {
      // This cleanup function runs only once when the component unmounts.
      return () => {
        // Stop any active recording to prevent state updates on an unmounted component.
        if (mediaRecorderRef.current && mediaRecorderRef.current.state === 'recording') {
          mediaRecorderRef.current.stop();
        }
        if (recordingTimerRef.current) {
          clearInterval(recordingTimerRef.current);
        }

        // Revoke all created object URLs to prevent memory leaks.
        // Use the ref to get the latest list of chats.
        chatsRef.current.forEach(chat => {
          chat.messages.forEach(msg => {
            if (msg.audio?.url) URL.revokeObjectURL(msg.audio.url);
            if (msg.file?.url) URL.revokeObjectURL(msg.file.url);
          });
        });
      };
    }, []); // Empty dependency array ensures this runs only on mount and unmount.

    const updateChatList = (chatId: number, lastMessage: string, newMessage: Message) => {
        const updatedChats = chats.map(chat => {
            if (chat.id === chatId) {
                return {
                    ...chat,
                    messages: [...chat.messages, newMessage],
                    lastMessage,
                    timestamp: 'همین الان'
                };
            }
            return chat;
        });

        const currentChatIndex = updatedChats.findIndex(c => c.id === chatId);
        if (currentChatIndex > -1) {
            const [currentChat] = updatedChats.splice(currentChatIndex, 1);
            updatedChats.unshift(currentChat);
        }
        setChats(updatedChats);
    };

    const handleSendMessage = (e: React.FormEvent) => {
        e.preventDefault();
        if (!newMessage.trim() || !selectedChatId) return;

        const now = new Date();
        const newMsg: Message = {
            id: Date.now(),
            text: newMessage,
            timestamp: `${now.getHours()}:${now.getMinutes().toString().padStart(2, '0')}`,
            sender: 'me'
        };
        updateChatList(selectedChatId, newMessage, newMsg);
        setNewMessage('');
    };
    
    const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        const file = e.target.files?.[0];
        if (file && selectedChatId) {
            const newFileMsg: Message = {
                id: Date.now(),
                file: {
                    url: URL.createObjectURL(file),
                    name: file.name,
                    type: file.type,
                },
                timestamp: new Date().toLocaleTimeString('fa-IR', { hour: '2-digit', minute: '2-digit' }),
                sender: 'me',
            };
            updateChatList(selectedChatId, file.name, newFileMsg);
        }
        // Reset file input
        if (e.target) e.target.value = '';
    };

    const handleStartRecording = async () => {
        if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia || !window.MediaRecorder) {
            alert('مرورگر شما از ضبط صدا پشتیبانی نمی‌کند.');
            return;
        }

        const MimeTypes = ['audio/webm;codecs=opus', 'audio/ogg;codecs=opus', 'audio/webm', 'audio/mp4', 'audio/aac'];
        const supportedMimeType = MimeTypes.find(type => MediaRecorder.isTypeSupported(type));

        if (!supportedMimeType) {
            alert('مرورگر شما از هیچ فرمت صوتی پشتیبانی نمی‌کند.');
            return;
        }
        mimeTypeRef.current = supportedMimeType;

        try {
            audioChunksRef.current = []; // Clear any previous chunks.
            shouldSendAudioRef.current = false; // Reset flag at the start of a new recording.

            const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
            mediaRecorderRef.current = new MediaRecorder(stream, { mimeType: mimeTypeRef.current });
            
            mediaRecorderRef.current.ondataavailable = event => {
                audioChunksRef.current.push(event.data);
            };

            mediaRecorderRef.current.onstop = () => {
                // Always clean up stream tracks
                mediaRecorderRef.current?.stream.getTracks().forEach(track => track.stop());

                if (shouldSendAudioRef.current) {
                    const audioBlob = new Blob(audioChunksRef.current, { type: mimeTypeRef.current! });
                    if (audioBlob.size > 0) {
                        const audioUrl = URL.createObjectURL(audioBlob);
                        const newAudioMsg: Message = {
                            id: Date.now(),
                            audio: { url: audioUrl, duration: recordingDuration },
                            timestamp: new Date().toLocaleTimeString('fa-IR', { hour: '2-digit', minute: '2-digit' }),
                            sender: 'me',
                        };
                        if (selectedChatId) {
                            updateChatList(selectedChatId, 'پیام صوتی', newAudioMsg);
                        }
                    }
                }
                // Reset for next recording
                audioChunksRef.current = [];
                shouldSendAudioRef.current = false; // Reset the flag after use.
            };

            mediaRecorderRef.current.start();
            setIsRecording(true);
            setRecordingDuration(0);
            recordingTimerRef.current = setInterval(() => {
                setRecordingDuration(prev => prev + 1);
            }, 1000);

        } catch (err) {
            console.error("Error starting recording:", err);
            let message = 'دسترسی به میکروفون امکان‌پذیر نیست. لطفا دسترسی لازم را بدهید.';
            if (err instanceof DOMException) {
                if (err.name === 'NotAllowedError') {
                    message = 'شما اجازه دسترسی به میکروفون را نداده‌اید. لطفاً دسترسی را از تنظیمات مرورگر خود فعال کنید.';
                } else if (err.name === 'NotFoundError') {
                    message = 'هیچ میکروفونی یافت نشد.';
                } else if (err.name === 'NotReadableError') {
                    message = 'مشکلی در سخت‌افزار میکروفون شما وجود دارد.';
                }
            }
            alert(message);
        }
    };
    
    const stopRecording = (send: boolean) => {
        if (!isRecording) return; // If not recording, do nothing.

        shouldSendAudioRef.current = send;
        if (mediaRecorderRef.current?.state === 'recording') {
            mediaRecorderRef.current.stop();
        }
        if (recordingTimerRef.current) {
            clearInterval(recordingTimerRef.current);
            recordingTimerRef.current = null;
        }
        setIsRecording(false);
    };

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

    return (
        <div className="flex h-[calc(100vh-130px)] bg-custom-light-card dark:bg-custom-dark-blue-light rounded-2xl shadow-lg overflow-hidden">
            {/* Chat List */}
            <div className={`w-full md:w-1/3 lg:w-1/4 flex flex-col border-l border-gray-200 dark:border-gray-700 transition-all duration-300 ${selectedChatId && 'hidden'} md:flex`}>
                <div className="p-4 border-b border-gray-200 dark:border-gray-700">
                    <h2 className="text-xl font-bold">پیام‌ها</h2>
                    <div className="relative mt-4">
                        <input type="text" placeholder="جستجو در پیام‌ها..." className="w-full pr-10 pl-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-custom-light-bg dark:bg-custom-dark-blue focus:ring-2 focus:ring-custom-purple focus:border-transparent outline-none transition"/>
                        <SearchIcon className="absolute right-3 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-400"/>
                    </div>
                </div>
                <div className="flex-1 overflow-y-auto">
                    {chats.map(chat => (
                        <button key={chat.id} onClick={() => setSelectedChatId(chat.id)} className={`w-full text-right flex items-center p-4 border-b border-gray-200 dark:border-gray-700 hover:bg-gray-100 dark:hover:bg-custom-dark-blue transition-colors ${selectedChatId === chat.id ? 'bg-custom-purple/10 dark:bg-custom-purple/20' : ''}`}>
                            <div className="relative">
                                <img src={chat.user.avatar} alt={chat.user.name} className="w-12 h-12 rounded-full" />
                                {chat.user.online && <span className="absolute bottom-0 right-0 block h-3 w-3 rounded-full bg-green-500 ring-2 ring-custom-light-card dark:ring-custom-dark-blue-light"></span>}
                            </div>
                            <div className="flex-1 mr-4 overflow-hidden">
                                <div className="flex justify-between items-center">
                                    <h3 className="font-semibold text-gray-800 dark:text-gray-200">{chat.user.name}</h3>
                                    <p className="text-xs text-gray-500 dark:text-gray-400 flex-shrink-0">{chat.timestamp}</p>
                                </div>
                                <div className="flex justify-between items-center mt-1">
                                    <p className="text-sm text-gray-500 dark:text-gray-400 truncate">{chat.lastMessage}</p>
                                    {chat.unreadCount > 0 && <span className="bg-custom-purple text-white text-xs font-bold rounded-full px-2 py-0.5">{chat.unreadCount}</span>}
                                </div>
                            </div>
                        </button>
                    ))}
                </div>
            </div>

            {/* Chat Window */}
            <div className={`flex-1 flex-col ${selectedChat ? 'flex' : 'hidden'} md:flex`}>
                {selectedChat ? (
                    <>
                        <div className="flex items-center p-4 border-b border-gray-200 dark:border-gray-700 bg-custom-light-card dark:bg-custom-dark-blue-light/50">
                            <button className="md:hidden ml-2 p-2" onClick={() => setSelectedChatId(null)}><ArrowLeftIcon className="w-6 h-6 transform rotate-180"/></button>
                            <img src={selectedChat.user.avatar} alt={selectedChat.user.name} className="w-12 h-12 rounded-full"/>
                            <div className="mr-4">
                                <h3 className="font-bold text-lg">{selectedChat.user.name}</h3>
                                {selectedChat.user.online && <p className="text-sm text-green-500 flex items-center"> <span className="h-2 w-2 bg-green-500 rounded-full inline-block ml-2"></span> آنلاین</p> }
                            </div>
                        </div>

                        <div className="flex-1 p-6 overflow-y-auto bg-custom-light-bg dark:bg-custom-dark-blue space-y-4">
                            {selectedChat.messages.map(msg => (
                                <div key={msg.id} className={`flex ${msg.sender === 'me' ? 'justify-end' : 'justify-start'}`}>
                                    <div className={`max-w-md flex items-end gap-2 ${msg.sender === 'me' ? 'flex-row-reverse' : 'flex-row'}`}>
                                       {msg.sender === 'them' && <img src={selectedChat.user.avatar} className="w-8 h-8 rounded-full self-end mb-3"/>}
                                        <div>
                                            <div className={`px-4 py-2 rounded-2xl ${msg.sender === 'me' ? 'bg-custom-purple text-white rounded-br-none' : 'bg-white dark:bg-custom-dark-blue-light text-gray-800 dark:text-gray-200 rounded-bl-none'}`}>
                                                {msg.text && <p>{msg.text}</p>}
                                                {msg.audio && <AudioPlayer src={msg.audio.url} />}
                                                {msg.file && <FileAttachment file={msg.file} />}
                                            </div>
                                            <p className={`text-xs text-gray-400 mt-1 px-1 ${msg.sender === 'me' ? 'text-left' : 'text-right'}`}>{msg.timestamp}</p>
                                        </div>
                                    </div>
                                </div>
                            ))}
                            <div ref={messagesEndRef} />
                        </div>
                        
                        <div className="p-4 bg-custom-light-card dark:bg-custom-dark-blue-light border-t border-gray-200 dark:border-gray-700">
                           {isRecording ? (
                                <div className="flex items-center justify-between">
                                    <button onClick={() => stopRecording(false)} className="p-3 text-red-500 hover:bg-red-100 dark:hover:bg-red-900/50 rounded-full transition-colors">
                                        <Trash2Icon className="w-6 h-6"/>
                                    </button>
                                    <div className="flex items-center gap-2 text-lg font-mono text-red-500">
                                        <div className="w-3 h-3 bg-red-500 rounded-full animate-pulse"></div>
                                        <span>{formatRecordingTime(recordingDuration)}</span>
                                    </div>
                                    <button onClick={() => stopRecording(true)} className="p-3 bg-custom-purple text-white rounded-full hover:bg-custom-light-purple transition-colors shadow-lg">
                                        <SendIcon className="w-6 h-6"/>
                                    </button>
                                </div>
                            ) : (
                                <form onSubmit={handleSendMessage} className="flex items-center space-x-2 space-x-reverse">
                                    <input ref={fileInputRef} type="file" onChange={handleFileChange} className="hidden" />
                                    <button type="button" onClick={() => fileInputRef.current?.click()} className="p-2 text-gray-500 dark:text-gray-400 hover:text-custom-purple dark:hover:text-custom-light-purple rounded-full"><PaperclipIcon className="w-6 h-6"/></button>
                                    
                                    <input 
                                        type="text" 
                                        value={newMessage}
                                        onChange={(e) => setNewMessage(e.target.value)}
                                        placeholder="پیام خود را بنویسید..." 
                                        className="flex-1 pr-4 pl-4 py-2.5 border border-gray-300 dark:border-gray-600 rounded-full bg-custom-light-bg dark:bg-custom-dark-blue focus:ring-2 focus:ring-custom-purple focus:border-transparent outline-none transition"
                                    />
                                    {newMessage.trim() ? (
                                        <button type="submit" className="p-3 bg-custom-purple text-white rounded-full hover:bg-custom-light-purple transition-colors shadow-lg disabled:bg-gray-400">
                                            <SendIcon className="w-6 h-6"/>
                                        </button>
                                    ) : (
                                        <button type="button" onClick={handleStartRecording} className="p-3 bg-custom-purple text-white rounded-full hover:bg-custom-light-purple transition-colors shadow-lg">
                                            <MicrophoneIcon className="w-6 h-6"/>
                                        </button>
                                    )}
                                </form>
                           )}
                        </div>
                    </>
                ) : (
                    <div className="flex-1 flex-col items-center justify-center text-center text-gray-500 dark:text-gray-400 bg-custom-light-bg dark:bg-custom-dark-blue hidden md:flex">
                        <ChatIcon className="w-24 h-24 mb-4 text-gray-300 dark:text-gray-600"/>
                        <h2 className="text-2xl font-semibold">گفتگویی را انتخاب کنید</h2>
                        <p>برای شروع مکالمه، یک نفر را از لیست انتخاب کنید.</p>
                    </div>
                )}
            </div>
        </div>
    );
};

const AudioPlayer: React.FC<{ src: string }> = ({ src }) => {
    const audioRef = useRef<HTMLAudioElement>(null);
    const [isPlaying, setIsPlaying] = useState(false);
    const [currentTime, setCurrentTime] = useState(0);
    const [duration, setDuration] = useState(0);

    useEffect(() => {
        const audio = audioRef.current;
        if (!audio) return;
        
        const setAudioData = () => {
            if(isFinite(audio.duration)) {
                setDuration(audio.duration)
            }
        };
        const timeUpdateHandler = () => setCurrentTime(audio.currentTime);
        const endedHandler = () => { setIsPlaying(false); setCurrentTime(0); };
        
        audio.addEventListener('loadedmetadata', setAudioData);
        audio.addEventListener('timeupdate', timeUpdateHandler);
        audio.addEventListener('ended', endedHandler);

        return () => {
            audio.removeEventListener('loadedmetadata', setAudioData);
            audio.removeEventListener('timeupdate', timeUpdateHandler);
            audio.removeEventListener('ended', endedHandler);
        };
    }, []);

    const togglePlay = () => {
        if (audioRef.current) {
            if (isPlaying) audioRef.current.pause();
            else audioRef.current.play();
            setIsPlaying(!isPlaying);
        }
    };
    
    const formatTime = (time: number) => {
        if (!isFinite(time) || time < 0) return '0:00';
        const minutes = Math.floor(time / 60);
        const seconds = Math.floor(time % 60).toString().padStart(2, '0');
        return `${minutes}:${seconds}`;
    };

    const progress = duration > 0 ? (currentTime / duration) * 100 : 0;

    return (
        <div className="flex items-center gap-2 w-48 text-current">
            <audio ref={audioRef} src={src} preload="metadata"></audio>
            <button onClick={togglePlay} className="p-2 flex-shrink-0">
                {isPlaying ? <PauseIcon className="w-5 h-5" /> : <PlayIcon className="w-5 h-5" />}
            </button>
            <div className="w-full h-1 bg-gray-400/50 dark:bg-gray-500/50 rounded-full relative">
                <div className="absolute top-0 right-0 h-1 bg-current rounded-full" style={{ width: `${progress}%` }}></div>
                <div className="absolute h-3 w-3 bg-current rounded-full top-1/2 -mt-1.5" style={{ right: `calc(${progress}% - 6px)` }}></div>
            </div>
            <span className="text-xs text-inherit opacity-70 w-10 text-center">{formatTime(duration)}</span>
        </div>
    );
};

const FileAttachment: React.FC<{ file: { url: string; name: string; type: string } }> = ({ file }) => {
    return (
        <a href={file.url} download={file.name} className="flex flex-col gap-2 max-w-xs cursor-pointer">
            {file.type.startsWith('image/') ? (
                <img src={file.url} alt={file.name} className="rounded-lg max-w-full h-auto" />
            ) : (
                <div className="flex items-center gap-3 p-3 rounded-lg bg-black/10 dark:bg-white/10">
                    <FileIcon className="w-8 h-8 flex-shrink-0" />
                    <span className="text-sm truncate font-medium">{file.name}</span>
                </div>
            )}
        </a>
    );
};

export default MessagesPage;