import { useState, useRef, useEffect } from 'react';
import { useParams, useNavigate, Link } from 'react-router-dom';
import Layout from '../components/layout/Layout';
import { useAuth } from '../contexts/AuthContext';
import { Send, UserPlus, Loader2, LogOut, AlertTriangle, QrCode, Edit2, Filter, X } from 'lucide-react';
import { connectSocket, disconnectSocket, getSocket } from '../services/socket';
import { eventsAPI, heatsAPI } from '../services/api';
import HeatsBanner from '../components/heats/HeatsBanner';

const EventChatPage = () => {
  const { slug } = useParams();
  const { user } = useAuth();
  const navigate = useNavigate();
  const [event, setEvent] = useState(null);
  const [isParticipant, setIsParticipant] = useState(false);
  const [loading, setLoading] = useState(true);
  const [messages, setMessages] = useState([]);
  const [newMessage, setNewMessage] = useState('');
  const [activeUsers, setActiveUsers] = useState([]);
  const [checkedInUsers, setCheckedInUsers] = useState([]);
  const [isConnected, setIsConnected] = useState(false);
  const [loadingOlder, setLoadingOlder] = useState(false);
  const [hasMore, setHasMore] = useState(true);
  const [showLeaveModal, setShowLeaveModal] = useState(false);
  const [isLeaving, setIsLeaving] = useState(false);
  const messagesEndRef = useRef(null);
  const messagesContainerRef = useRef(null);

  // Heats state
  const [myHeats, setMyHeats] = useState([]);
  const [userHeats, setUserHeats] = useState(new Map());
  const [showHeatsBanner, setShowHeatsBanner] = useState(false);
  const [hideMyHeats, setHideMyHeats] = useState(false);
  const [showHeatsModal, setShowHeatsModal] = useState(false);

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

  // Fetch event data and check participation
  useEffect(() => {
    const fetchEvent = async () => {
      try {
        setLoading(true);

        // Get all events with participation info
        const allEvents = await eventsAPI.getAll();
        const eventData = allEvents.find(e => e.slug === slug);

        if (eventData) {
          setEvent(eventData);
          setIsParticipant(eventData.isJoined);
        } else {
          setEvent(null);
          setIsParticipant(false);
        }
      } catch (err) {
        console.error('Error loading event:', err);
        setEvent(null);
        setIsParticipant(false);
      } finally {
        setLoading(false);
      }
    };

    fetchEvent();
  }, [slug]);

  // Load heats data and checked-in users
  useEffect(() => {
    if (!event || !isParticipant) return;

    const loadData = async () => {
      try {
        // Load my heats
        const myHeatsData = await heatsAPI.getMyHeats(slug);
        setMyHeats(myHeatsData);
        setShowHeatsBanner(myHeatsData.length === 0);

        // Load all users' heats
        const allHeatsData = await heatsAPI.getAllHeats(slug);
        const heatsMap = new Map();
        allHeatsData.forEach((userHeat) => {
          heatsMap.set(userHeat.userId, userHeat.heats);
        });
        setUserHeats(heatsMap);

        // Load all checked-in users (participants)
        const eventDetails = await eventsAPI.getDetails(slug);
        if (eventDetails.data && eventDetails.data.participants) {
          const participants = eventDetails.data.participants
            .map(p => ({
              userId: p.userId,
              username: p.username,
              avatar: p.avatar || `https://api.dicebear.com/7.x/avataaars/svg?seed=${p.username}`,
              firstName: p.firstName,
              lastName: p.lastName,
            }))
            .filter(p => p.userId !== user.id); // Exclude current user
          setCheckedInUsers(participants);
        }
      } catch (error) {
        console.error('Failed to load data:', error);
      }
    };

    loadData();
  }, [event, isParticipant, slug, user.id]);

  useEffect(() => {
    scrollToBottom();
  }, [messages]);

  useEffect(() => {
    if (!event) return;

    // Connect to Socket.IO
    const socket = connectSocket();

    if (!socket) {
      console.error('Failed to connect to socket');
      return;
    }

    // Socket event listeners
    socket.on('connect', () => {
      setIsConnected(true);
      // Join event room
      socket.emit('join_event_room', { slug });
    });

    socket.on('disconnect', () => {
      setIsConnected(false);
    });

    // Receive message history (initial 20 messages)
    socket.on('message_history', (history) => {
      setMessages(history);
      setHasMore(history.length === 20);
    });

    // Receive new messages
    socket.on('event_message', (message) => {
      setMessages((prev) => [...prev, message]);
    });

    // Receive active users list
    socket.on('active_users', (users) => {
      // Filter out duplicates and current user
      const uniqueUsers = users
        .filter((u, index, self) =>
          index === self.findIndex((t) => t.userId === u.userId)
        )
        .filter((u) => u.userId !== user.id);
      setActiveUsers(uniqueUsers);
    });

    // User joined notification
    socket.on('user_joined', (userData) => {
      console.log(`${userData.username} joined the room`);
    });

    // User left notification
    socket.on('user_left', (userData) => {
      console.log(`${userData.username} left the room`);
    });

    // Heats updated notification
    socket.on('heats_updated', (data) => {
      const { userId, heats } = data;

      // Update userHeats map
      setUserHeats((prev) => {
        const newMap = new Map(prev);
        if (heats && heats.length > 0) {
          newMap.set(userId, heats);
        } else {
          newMap.delete(userId);
        }
        return newMap;
      });

      // If it's the current user, update myHeats
      if (userId === user.id) {
        setMyHeats(heats || []);
        setShowHeatsBanner(heats.length === 0);
      }
    });

    // Cleanup
    return () => {
      socket.emit('leave_event_room');
      socket.off('connect');
      socket.off('disconnect');
      socket.off('message_history');
      socket.off('event_message');
      socket.off('active_users');
      socket.off('user_joined');
      socket.off('user_left');
      socket.off('heats_updated');
    };
  }, [event, slug, user.id]);

  const handleSendMessage = (e) => {
    e.preventDefault();
    if (!newMessage.trim()) return;

    const socket = getSocket();
    if (!socket || !socket.connected) {
      alert('Not connected to chat server');
      return;
    }

    // Send message via Socket.IO
    socket.emit('send_event_message', {
      content: newMessage,
    });

    setNewMessage('');
  };

  const loadOlderMessages = async () => {
    if (loadingOlder || !hasMore || messages.length === 0) return;

    setLoadingOlder(true);
    try {
      const oldestMessageId = messages[0].id;
      const response = await eventsAPI.getMessages(slug, oldestMessageId, 20);

      if (response.data.length > 0) {
        // Save current scroll position
        const container = messagesContainerRef.current;
        const oldScrollHeight = container.scrollHeight;
        const oldScrollTop = container.scrollTop;

        // Prepend older messages
        setMessages((prev) => [...response.data, ...prev]);
        setHasMore(response.hasMore);

        // Restore scroll position (adjust for new content)
        setTimeout(() => {
          const newScrollHeight = container.scrollHeight;
          container.scrollTop = oldScrollTop + (newScrollHeight - oldScrollHeight);
        }, 0);
      } else {
        setHasMore(false);
      }
    } catch (error) {
      console.error('Failed to load older messages:', error);
    } finally {
      setLoadingOlder(false);
    }
  };

  const handleMatchWith = (userId) => {
    // TODO: Implement match request
    alert(`Match request sent to user!`);
    setTimeout(() => {
      navigate(`/matches/1/chat`);
    }, 1000);
  };

  const handleHeatsSave = () => {
    setShowHeatsBanner(false);
    setShowHeatsModal(false);
    // Heats will be updated via Socket.IO heats_updated event
  };

  const formatHeat = (heat) => {
    const parts = [
      heat.competitionType?.abbreviation || '',
      heat.division?.abbreviation || '',
      heat.heatNumber,
    ];
    if (heat.role) {
      parts.push(heat.role.charAt(0)); // L or F
    }
    return parts.join(' ');
  };

  const shouldHideUser = (userId) => {
    if (!hideMyHeats || myHeats.length === 0) return false;

    const targetUserHeats = userHeats.get(userId);
    if (!targetUserHeats || targetUserHeats.length === 0) return false;

    // Hide if ANY of their heats match ANY of my heats (same division + competition_type + heat_number)
    return targetUserHeats.some((targetHeat) =>
      myHeats.some(
        (myHeat) =>
          myHeat.divisionId === targetHeat.divisionId &&
          myHeat.competitionTypeId === targetHeat.competitionTypeId &&
          myHeat.heatNumber === targetHeat.heatNumber
      )
    );
  };

  // Combine checked-in users with online status
  const getAllDisplayUsers = () => {
    const activeUserIds = new Set(activeUsers.map(u => u.userId));

    // Merge checked-in users with online status
    const allUsers = checkedInUsers.map(user => ({
      ...user,
      isOnline: activeUserIds.has(user.userId),
    }));

    // Sort: online first, then offline
    return allUsers.sort((a, b) => {
      if (a.isOnline === b.isOnline) return 0;
      return a.isOnline ? -1 : 1;
    });
  };

  const handleLeaveEvent = async () => {
    try {
      setIsLeaving(true);
      await eventsAPI.leave(slug);

      // Disconnect socket
      const socket = getSocket();
      if (socket) {
        socket.emit('leave_event_room');
      }

      // Redirect to events page
      navigate('/events');
    } catch (error) {
      console.error('Failed to leave event:', error);
      alert('Failed to leave event. Please try again.');
    } finally {
      setIsLeaving(false);
      setShowLeaveModal(false);
    }
  };

  // Infinite scroll - detect scroll to top
  useEffect(() => {
    const container = messagesContainerRef.current;
    if (!container) return;

    const handleScroll = () => {
      if (container.scrollTop < 100 && !loadingOlder && hasMore) {
        loadOlderMessages();
      }
    };

    container.addEventListener('scroll', handleScroll);
    return () => container.removeEventListener('scroll', handleScroll);
  }, [loadingOlder, hasMore, messages]);

  if (loading) {
    return (
      <Layout>
        <div className="max-w-4xl mx-auto flex items-center justify-center min-h-[400px]">
          <div className="flex flex-col items-center gap-3">
            <Loader2 className="w-12 h-12 animate-spin text-primary-600" />
            <p className="text-gray-600">Loading event...</p>
          </div>
        </div>
      </Layout>
    );
  }

  if (!event) {
    return (
      <Layout>
        <div className="max-w-4xl mx-auto">
          <div className="bg-red-50 border border-red-200 rounded-md p-4 text-red-700">
            Event not found
          </div>
        </div>
      </Layout>
    );
  }

  // Check if user is participant
  if (!isParticipant) {
    return (
      <Layout>
        <div className="max-w-4xl mx-auto">
          <div className="bg-white rounded-lg shadow-md p-8">
            <div className="text-center">
              <div className="w-16 h-16 bg-amber-100 rounded-full flex items-center justify-center mx-auto mb-4">
                <QrCode className="w-8 h-8 text-amber-600" />
              </div>
              <h2 className="text-2xl font-bold text-gray-900 mb-2">
                Check-in Required
              </h2>
              <p className="text-gray-600 mb-6">
                You need to check in at the event venue by scanning the QR code to access this chat.
              </p>

              <div className="bg-amber-50 border border-amber-200 rounded-lg p-4 mb-6">
                <p className="text-sm text-amber-800 font-medium mb-1">
                  {event.name}
                </p>
                <p className="text-sm text-amber-700">
                  {event.location}
                </p>
              </div>

              <div className="flex gap-3 justify-center">
                <Link
                  to="/events"
                  className="px-6 py-2 border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors"
                >
                  Back to Events
                </Link>
                {import.meta.env.DEV && (
                  <Link
                    to={`/events/${slug}/details`}
                    className="px-6 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors"
                  >
                    View QR Code (dev)
                  </Link>
                )}
              </div>
            </div>
          </div>
        </div>
      </Layout>
    );
  }

  return (
    <Layout>
      <div className="max-w-6xl mx-auto">
        <div className="bg-white rounded-lg shadow-md overflow-hidden">
          {/* Header */}
          <div className="bg-primary-600 text-white p-4">
            <div className="flex items-start justify-between">
              <div className="flex-1">
                <h2 className="text-2xl font-bold">{event.name}</h2>
                <p className="text-primary-100 text-sm">{event.location}</p>
                <div className="mt-2">
                  <span className={`text-xs px-2 py-1 rounded ${isConnected ? 'bg-green-500' : 'bg-red-500'}`}>
                    {isConnected ? '● Connected' : '● Disconnected'}
                  </span>
                </div>
              </div>
              {myHeats.length > 0 && (
                <button
                  onClick={() => setShowHeatsModal(true)}
                  className="flex items-center gap-2 px-3 py-2 bg-primary-700 hover:bg-primary-800 rounded-md transition-colors text-sm"
                >
                  <Edit2 className="w-4 h-4" />
                  Edit Heats
                </button>
              )}
            </div>
          </div>

          {/* Heats Banner */}
          {showHeatsBanner && (
            <HeatsBanner
              slug={slug}
              onSave={handleHeatsSave}
              onDismiss={() => setShowHeatsBanner(false)}
            />
          )}

          <div className="flex h-[calc(100vh-280px)]">
            {/* Participants Sidebar */}
            <div className="w-64 border-r bg-gray-50 p-4 overflow-y-auto">
              <div className="mb-4">
                <h3 className="font-semibold text-gray-900 mb-2">
                  Participants ({getAllDisplayUsers().filter(u => !shouldHideUser(u.userId)).length})
                </h3>
                <p className="text-xs text-gray-500 mb-3">
                  {activeUsers.length} online
                </p>

                {/* Filter Checkbox */}
                {myHeats.length > 0 && (
                  <label className="flex items-center gap-2 text-sm text-gray-700 cursor-pointer hover:text-gray-900">
                    <input
                      type="checkbox"
                      checked={hideMyHeats}
                      onChange={(e) => setHideMyHeats(e.target.checked)}
                      className="rounded border-gray-300 text-primary-600 focus:ring-primary-500"
                    />
                    <Filter className="w-3 h-3" />
                    <span>Hide users from my heats</span>
                  </label>
                )}
              </div>

              {getAllDisplayUsers().filter(u => !shouldHideUser(u.userId)).length === 0 && (
                <p className="text-sm text-gray-500">No other participants</p>
              )}
              <div className="space-y-2">
                {getAllDisplayUsers()
                  .filter((displayUser) => !shouldHideUser(displayUser.userId))
                  .map((displayUser) => {
                    const thisUserHeats = userHeats.get(displayUser.userId) || [];
                    const hasHeats = thisUserHeats.length > 0;

                    return (
                      <div
                        key={displayUser.userId}
                        className="flex items-center justify-between p-2 hover:bg-gray-100 rounded-lg"
                      >
                        <div className="flex items-center space-x-2 flex-1 min-w-0">
                          <div className="relative flex-shrink-0">
                            <img
                              src={displayUser.avatar}
                              alt={displayUser.username}
                              className="w-8 h-8 rounded-full"
                            />
                            {/* Online/Offline indicator */}
                            <div
                              className={`absolute bottom-0 right-0 w-2.5 h-2.5 rounded-full border-2 border-gray-50 ${
                                displayUser.isOnline ? 'bg-green-500' : 'bg-gray-400'
                              }`}
                              title={displayUser.isOnline ? 'Online' : 'Offline'}
                            />
                          </div>
                          <div className="flex-1 min-w-0">
                            <p className={`text-sm font-medium truncate ${
                              displayUser.isOnline ? 'text-gray-900' : 'text-gray-500'
                            }`}>
                              {displayUser.username}
                            </p>
                            {/* Heat Badges */}
                            {hasHeats && (
                              <div className="flex flex-wrap gap-1 mt-1">
                                {thisUserHeats.slice(0, 3).map((heat, idx) => (
                                  <span
                                    key={idx}
                                    className="text-xs px-1.5 py-0.5 bg-amber-100 text-amber-800 rounded font-mono"
                                  >
                                    {formatHeat(heat)}
                                  </span>
                                ))}
                                {thisUserHeats.length > 3 && (
                                  <span className="text-xs px-1.5 py-0.5 bg-gray-200 text-gray-700 rounded font-mono">
                                    +{thisUserHeats.length - 3}
                                  </span>
                                )}
                              </div>
                            )}
                          </div>
                        </div>
                        <button
                          onClick={() => handleMatchWith(displayUser.userId)}
                          disabled={!hasHeats}
                          className={`p-1 rounded flex-shrink-0 ${
                            hasHeats
                              ? 'text-primary-600 hover:bg-primary-50'
                              : 'text-gray-300 cursor-not-allowed'
                          }`}
                          title={hasHeats ? 'Connect' : 'User has not declared heats'}
                        >
                          <UserPlus className="w-4 h-4" />
                        </button>
                      </div>
                    );
                  })}
              </div>
            </div>

            {/* Chat Area */}
            <div className="flex-1 flex flex-col">
              {/* Messages */}
              <div ref={messagesContainerRef} className="flex-1 overflow-y-auto p-4 space-y-4">
                {/* Loading older messages indicator */}
                {loadingOlder && (
                  <div className="flex justify-center py-2">
                    <Loader2 className="w-5 h-5 animate-spin text-primary-600" />
                  </div>
                )}

                {messages.length === 0 && (
                  <div className="text-center text-gray-500 py-8">
                    No messages yet. Start the conversation!
                  </div>
                )}
                {messages.map((message) => {
                  const isOwnMessage = message.userId === user.id;
                  return (
                    <div
                      key={message.id}
                      className={`flex ${isOwnMessage ? 'justify-end' : 'justify-start'}`}
                    >
                      <div className={`flex items-start space-x-2 max-w-md ${isOwnMessage ? 'flex-row-reverse space-x-reverse' : ''}`}>
                        <img
                          src={message.avatar}
                          alt={message.username}
                          className="w-8 h-8 rounded-full"
                        />
                        <div>
                          <div className="flex items-baseline space-x-2 mb-1">
                            <span className="text-sm font-medium text-gray-900">
                              {message.username}
                            </span>
                            <span className="text-xs text-gray-500">
                              {new Date(message.createdAt).toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' })}
                            </span>
                          </div>
                          <div
                            className={`rounded-lg px-4 py-2 ${
                              isOwnMessage
                                ? 'bg-primary-600 text-white'
                                : 'bg-gray-100 text-gray-900'
                            }`}
                          >
                            {message.content}
                          </div>
                        </div>
                      </div>
                    </div>
                  );
                })}
                <div ref={messagesEndRef} />
              </div>

              {/* Message Input */}
              <div className="border-t p-4">
                <form onSubmit={handleSendMessage} className="flex space-x-2">
                  <input
                    type="text"
                    value={newMessage}
                    onChange={(e) => setNewMessage(e.target.value)}
                    placeholder="Write a message..."
                    disabled={!isConnected}
                    className="flex-1 px-4 py-2 border border-gray-300 rounded-lg focus:ring-primary-500 focus:border-primary-500 disabled:opacity-50"
                  />
                  <button
                    type="submit"
                    disabled={!isConnected}
                    className="px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors disabled:opacity-50"
                  >
                    <Send className="w-5 h-5" />
                  </button>
                </form>
              </div>
            </div>
          </div>

          {/* Leave Event Button */}
          <div className="mt-4 flex justify-center">
            <button
              onClick={() => setShowLeaveModal(true)}
              className="flex items-center gap-2 px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors font-medium"
            >
              <LogOut size={16} />
              Leave Event
            </button>
          </div>
        </div>

        {/* Leave Confirmation Modal */}
        {showLeaveModal && (
          <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4 z-50">
            <div className="bg-white rounded-lg shadow-xl max-w-md w-full p-6">
              <div className="flex items-center gap-3 mb-4">
                <div className="w-12 h-12 rounded-full bg-red-100 flex items-center justify-center">
                  <AlertTriangle className="text-red-600" size={24} />
                </div>
                <div>
                  <h3 className="text-lg font-semibold text-gray-900">Leave Event?</h3>
                  <p className="text-sm text-gray-600">This action cannot be undone</p>
                </div>
              </div>

              <p className="text-gray-700 mb-6">
                Are you sure you want to leave <strong>{event.name}</strong>?
                You will need to scan the QR code again to rejoin.
              </p>

              <div className="flex gap-3">
                <button
                  onClick={() => setShowLeaveModal(false)}
                  disabled={isLeaving}
                  className="flex-1 px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors font-medium disabled:opacity-50"
                >
                  Cancel
                </button>
                <button
                  onClick={handleLeaveEvent}
                  disabled={isLeaving}
                  className="flex-1 px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors font-medium disabled:opacity-50 flex items-center justify-center gap-2"
                >
                  {isLeaving ? (
                    <>
                      <Loader2 className="animate-spin" size={16} />
                      Leaving...
                    </>
                  ) : (
                    <>
                      <LogOut size={16} />
                      Leave Event
                    </>
                  )}
                </button>
              </div>
            </div>
          </div>
        )}

        {/* Edit Heats Modal */}
        {showHeatsModal && (
          <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4 z-50">
            <div className="bg-white rounded-lg shadow-xl max-w-4xl w-full max-h-[90vh] overflow-y-auto">
              <div className="sticky top-0 bg-white border-b px-6 py-4 flex items-center justify-between">
                <h3 className="text-lg font-semibold text-gray-900">Edit Your Competition Heats</h3>
                <button
                  onClick={() => setShowHeatsModal(false)}
                  className="text-gray-400 hover:text-gray-600"
                >
                  <X className="w-5 h-5" />
                </button>
              </div>
              <div className="p-6">
                <HeatsBanner
                  slug={slug}
                  onSave={handleHeatsSave}
                  onDismiss={() => setShowHeatsModal(false)}
                />
              </div>
            </div>
          </div>
        )}
      </div>
    </Layout>
  );
};

export default EventChatPage;
