'use client';

import { Headphones, MessageCircle, Send, Users, X } from 'lucide-react';
import { useCallback, useEffect, useRef, useState } from 'react';
import { io, Socket } from 'socket.io-client';
import { api } from '@/lib/api';
import { useAuthStore } from '@/store/authStore';

type Channel = 'SUPPORT' | 'GENERAL';

export default function ChatPopup() {
  const token = useAuthStore((state) => state.token);
  const user = useAuthStore((state) => state.user);
  const [open, setOpen] = useState(false);
  const [channel, setChannel] = useState<Channel>('SUPPORT');
  const [room, setRoom] = useState<any>(null);
  const [messages, setMessages] = useState<any[]>([]);
  const [text, setText] = useState('');
  const [loading, setLoading] = useState(false);
  const [moderationNotice, setModerationNotice] = useState('');
  const [unreadByRoom, setUnreadByRoom] = useState<Record<string, number>>({});
  const socketRef = useRef<Socket | null>(null);
  const activeRoomIdRef = useRef<string | null>(null);
  const generalRoomIdRef = useRef<string | null>(null);
  const openRef = useRef(false);
  const messagesContainerRef = useRef<HTMLDivElement | null>(null);

  const loadChannel = useCallback(async (nextChannel: Channel) => {
    setChannel(nextChannel);
    setLoading(true);
    setMessages([]);
    try {
      const endpoint = nextChannel === 'GENERAL' ? '/chat/general' : '/chat/support';
      const roomResponse = await api.post(endpoint);
      const nextRoom = roomResponse.data;
      setRoom(nextRoom);
      activeRoomIdRef.current = nextRoom.id;
      if (nextChannel === 'GENERAL') generalRoomIdRef.current = nextRoom.id;
      setUnreadByRoom((current) => ({ ...current, [nextRoom.id]: 0 }));
      socketRef.current?.emit('join', { conversationId: nextRoom.id });
      const messagesResponse = await api.get(`/chat/conversations/${nextRoom.id}/messages`);
      setMessages(messagesResponse.data || []);
    } finally { setLoading(false); }
  }, []);

  useEffect(() => {
    if (!token) return;
    const timer = window.setTimeout(() => { void loadChannel('SUPPORT'); }, 0);
    return () => window.clearTimeout(timer);
  }, [token, loadChannel]);
  useEffect(() => {
    const openSupport = () => { setOpen(true); void loadChannel('SUPPORT'); };
    window.addEventListener('open-support-chat', openSupport);
    return () => window.removeEventListener('open-support-chat', openSupport);
  }, [loadChannel]);
  useEffect(() => {
    openRef.current = open;
    if (open && activeRoomIdRef.current) setUnreadByRoom((current) => ({ ...current, [activeRoomIdRef.current!]: 0 }));
  }, [open]);

  useEffect(() => {
    if (!token) return;
    const socketBase = process.env.NEXT_PUBLIC_SOCKET_URL || '/';
    const socket = io(`${socketBase}/chat`, { auth: { token } });
    socketRef.current = socket;
    socket.on('connect', () => {
      if (activeRoomIdRef.current) socket.emit('join', { conversationId: activeRoomIdRef.current });
      if (generalRoomIdRef.current) socket.emit('join', { conversationId: generalRoomIdRef.current });
    });
    socket.on('message', (message) => {
      if (message.conversationId === activeRoomIdRef.current) {
        setMessages((current) => current.some((item) => item.id === message.id) ? current : [...current, message]);
      }
      if (message.senderId !== user?.id && (!openRef.current || message.conversationId !== activeRoomIdRef.current)) {
        setUnreadByRoom((current) => ({ ...current, [message.conversationId]: (current[message.conversationId] || 0) + 1 }));
      }
    });
    socket.on('chat_error', (error) => setModerationNotice(error?.message || 'Không thể gửi tin nhắn.'));
    void api.post('/chat/general').then((response) => {
      generalRoomIdRef.current = response.data.id;
      if (socket.connected) socket.emit('join', { conversationId: response.data.id });
    }).catch(() => undefined);
    return () => { socket.disconnect(); socketRef.current = null; };
  }, [token, user?.id]);

  useEffect(() => {
    if (!open || !room?.id) return;
    const refresh = () => api.get(`/chat/conversations/${room.id}/messages`).then((response) => setMessages(response.data || [])).catch(() => undefined);
    void refresh();
    const interval = window.setInterval(refresh, 2500);
    return () => window.clearInterval(interval);
  }, [open, room?.id]);

  useEffect(() => { messagesContainerRef.current?.scrollTo({ top: messagesContainerRef.current.scrollHeight, behavior: 'smooth' }); }, [messages, open, room?.id]);

  if (!token) return null;

  const send = async () => {
    const content = text.trim();
    if (!room || !content) return;
    try {
      if (socketRef.current?.connected) socketRef.current.emit('message', { conversationId: room.id, content });
      else { const response = await api.post(`/chat/conversations/${room.id}/messages`, { content }); setMessages((current) => [...current, response.data]); }
      setText('');
    } catch (error: any) { setModerationNotice(error?.response?.data?.message || 'Không thể gửi tin nhắn.'); }
  };

  const banFromGeneral = async (message: any) => {
    if (!window.confirm(`Cấm chat tổng ${message.sender?.name || 'thành viên'}? Họ vẫn có thể liên hệ Support.`)) return;
    await api.post(`/chat/admin/users/${message.sender.id}/chat-ban`, { banned: true });
    setModerationNotice(`Đã cấm chat tổng ${message.sender.name}.`);
  };

  const roleLabel = (message: any) => {
    const role = message.sender?.role?.name;
    if (role === 'ADMIN' || role === 'SUPER_ADMIN') return channel === 'SUPPORT' ? 'Support' : 'Admin';
    if (role === 'SELLER') return 'Seller';
    return 'Khách hàng';
  };
  const roleStyle = (message: any) => {
    const role = message.sender?.role?.name;
    if (role === 'ADMIN' || role === 'SUPER_ADMIN') return channel === 'SUPPORT'
      ? 'border border-amber-300/40 bg-amber-400/15 text-amber-200 shadow-[0_0_12px_rgba(251,191,36,.28)]'
      : 'border border-red-400/40 bg-red-500/15 text-red-200 shadow-[0_0_12px_rgba(248,113,113,.28)]';
    if (role === 'SELLER') return 'border border-violet-400/40 bg-violet-500/15 text-violet-200 shadow-[0_0_12px_rgba(167,139,250,.28)]';
    return 'border border-white/25 bg-white/10 text-white shadow-[0_0_10px_rgba(255,255,255,.12)]';
  };
  const unreadCount = Object.values(unreadByRoom).reduce((total, count) => total + count, 0);
  const roomName = channel === 'GENERAL' ? '# General' : '# Support';
  const currentRole = typeof user?.role === 'string' ? user.role : user?.role?.name;
  const isAdmin = ['ADMIN', 'SUPER_ADMIN'].includes(currentRole);

  return <div className="fixed bottom-5 right-5 z-[80]">
    {open && <div className="mb-3 flex h-[620px] w-[430px] flex-col overflow-hidden rounded-[22px] border border-white/15 bg-[#0d0d0e] text-white shadow-2xl">
      <header className="flex items-center gap-3 border-b border-white/10 p-4"><div className="rounded-xl bg-white/10 p-2">{channel === 'GENERAL' ? <Users className="h-5 w-5" /> : <Headphones className="h-5 w-5" />}</div><div className="flex-1"><b>{channel === 'GENERAL' ? 'Chat cộng đồng' : 'Support'}</b><p className="text-xs text-gray-400">{channel === 'GENERAL' ? 'Mọi thành viên cùng trò chuyện' : 'Trao đổi trực tiếp với quản trị viên'}</p></div><span className="text-xs text-emerald-400">● Trực tiếp</span><button aria-label="Đóng chat" onClick={() => setOpen(false)}><X /></button></header>
      <nav className="flex gap-2 border-b border-white/10 p-2"><button onClick={() => void loadChannel('GENERAL')} className={`rounded-lg px-3 py-2 text-sm font-semibold ${channel === 'GENERAL' ? 'bg-violet-600' : 'bg-white/5 text-gray-300'}`}># General</button><button onClick={() => void loadChannel('SUPPORT')} className={`rounded-lg px-3 py-2 text-sm font-semibold ${channel === 'SUPPORT' ? 'bg-violet-600' : 'bg-white/5 text-gray-300'}`}># Support</button></nav>
      <main ref={messagesContainerRef} className="flex-1 space-y-3 overflow-auto p-4">{moderationNotice && <p className="rounded-lg bg-emerald-500/10 p-2 text-xs text-emerald-300">{moderationNotice}</p>}{loading ? <p className="text-sm text-gray-500">Đang tải hội thoại…</p> : messages.length ? messages.map((message) => { const mine = message.sender?.id === user?.id; return <div key={message.id} className={`flex ${mine ? 'justify-end' : 'justify-start'}`}><div className={`max-w-[82%] rounded-2xl p-3 text-sm ${mine ? 'bg-violet-600 text-white' : 'bg-white/10 text-white'}`}><div className={`mb-1 flex items-center gap-2 ${mine ? 'justify-end' : ''}`}><b className={`text-xs ${mine ? 'text-violet-100' : 'text-violet-300'}`}>{mine ? 'Bạn' : message.sender?.name || 'Thành viên'}</b><span className={`rounded-full px-2 py-0.5 text-[10px] font-bold tracking-wide ${mine ? 'border border-white/20 bg-white/15 text-white' : roleStyle(message)}`}>{roleLabel(message)}</span>{channel === 'GENERAL' && isAdmin && !mine && !['ADMIN', 'SUPER_ADMIN'].includes(message.sender?.role?.name) && <button onClick={() => void banFromGeneral(message)} className="rounded border border-red-400/40 px-2 py-0.5 text-[10px] font-bold text-red-300 hover:bg-red-500/10">Cấm chat tổng</button>}</div><p>{message.content}</p><span className={`mt-1 block text-[10px] ${mine ? 'text-violet-100/70 text-right' : 'text-gray-500'}`}>{message.createdAt ? new Date(message.createdAt).toLocaleTimeString('vi-VN', { hour: '2-digit', minute: '2-digit' }) : ''}</span></div></div>; }) : <p className="text-sm text-gray-500">{channel === 'GENERAL' ? 'Hãy bắt đầu cuộc trò chuyện với cộng đồng.' : 'Hãy gửi tin nhắn cho quản trị viên.'}</p>}</main>
      <footer className="flex gap-2 border-t border-white/10 p-3"><input value={text} maxLength={2000} onChange={(event) => setText(event.target.value)} onKeyDown={(event) => { if (event.key === 'Enter') void send(); }} className="flex-1 rounded-xl bg-white/10 px-3 py-2 text-sm outline-none ring-violet-500 focus:ring-1" placeholder={`Tin nhắn ${roomName}`} /><button aria-label="Gửi tin nhắn" onClick={() => void send()} className="rounded-xl bg-violet-600 p-2"><Send className="h-4 w-4" /></button></footer>
      <p className="border-t border-white/5 px-4 py-2 text-center text-[11px] text-gray-500">Chỉ hỗ trợ tin nhắn văn bản — không gửi ảnh, file, emoji hoặc âm thanh.</p>
    </div>}
    <button aria-label="Mở chat" onClick={() => setOpen((value) => !value)} className="relative ml-auto flex h-14 w-14 items-center justify-center rounded-full bg-violet-600 text-white shadow-lg"><MessageCircle />{unreadCount > 0 && <span className="absolute -right-1 -top-1 flex min-h-6 min-w-6 animate-pulse items-center justify-center rounded-full border-2 border-[#101010] bg-red-500 px-1 text-[11px] font-extrabold text-white shadow-[0_0_12px_rgba(239,68,68,.8)]">{unreadCount > 99 ? '99+' : unreadCount}</span>}</button>
  </div>;
}
