import { useContext, useEffect, useMemo, useState } from 'react';
import { socket } from '@/socket/socket.ts';
import { Crown, Sword } from 'lucide-react';
import {
  ContextMenu,
  ContextMenuContent,
  ContextMenuItem,
  ContextMenuTrigger,
} from '@/components/ui/context-menu.tsx';
import zdjecie from '../../../../assets/turtleProfileImg3.webp';
import { ParticipantsProps } from '@/types/types.ts';
import { useChat } from '@/context/chat/useChat.ts';
import { axiosClient } from '@/utils/axiosClient.ts';
import { AuthContext } from '@/utils/AuthProvider.tsx';

function ParticipantsBar() {
  const { setMe, initializeContact, setGroupOwner, currentContact, me } =
    useChat();
  const [participants, setParticipants] = useState<ParticipantsProps[]>([]);
  const { user } = useContext(AuthContext);
  const getParticipants = async () => {
    try {
      const response = await axiosClient.get(
        `/api/chat/groups/getMembers/${currentContact?.conversation_id}`,
      );
      console.log(
        'getParticipants for: ',
        currentContact?.conversation_id,
        'response: ',
        response.data,
      );
      setParticipants(response.data);
    } catch (e) {
      console.error('Failed to get chat participants: ', e);
    }
  };

  const handleRemoveUser = async (userId: string) => {
    socket?.emit(
      'remove user from group',
      {
        group_id: currentContact?.conversation_id,
        user_id: userId,
      },
      (response: { status: 'ok' | 'error'; message: string }) => {
        if (response.status == 'ok') {
          console.log(response.message);
        } else {
          console.error('Failed to remove user from group: ', response.message);
        }
      },
    );
    // setParticipants((prevMembers) =>
    //   prevMembers.filter((member) => member.user_id !== userId),
    // );
  };

  const handleAddToAdministrators = async (userId: string) => {
    socket?.emit(
      'added administrator',
      { group_id: currentContact?.conversation_id, user_id: userId },
      (response: { status: 'ok' | 'error'; message: string }) => {
        if (response.status == 'ok') {
          console.log(response.message);
        } else {
          console.error(
            'Failed to add user to administrators: ',
            response.message,
          );
        }
      },
    );
  };

  const handleRemoveFromAdministrators = async (userId: string) => {
    socket?.emit(
      'removed administrator',
      { group_id: currentContact?.conversation_id, user_id: userId },
      (response: { status: 'ok' | 'error'; message: string }) => {
        if (response.status == 'ok') {
          console.log(response.message);
        } else {
          console.error(
            'Failed to remove user from administrators: ',
            response.message,
          );
        }
      },
    );
  };

  useEffect(() => {
    if (participants.length > 0 && user?.id) {
      const userIsAdmin = participants.some(
        (participant) => participant.user_id === user.id && participant.isadmin,
      );
      const userIsOwner = participants.some(
        (participant) => participant.user_id === user.id && participant.isowner,
      );

      const whoIsOwner = participants.find(
        (participant) => participant.isowner,
      );
      setGroupOwner(whoIsOwner?.user_id);
      setMe({ isGroupAdmin: userIsAdmin, isGroupOwner: userIsOwner });
    }
  }, [participants, user?.id]);

  useEffect(() => {
    if (currentContact) {
      getParticipants();
    }
  }, [currentContact]);

  const sortedParticipants = useMemo(() => {
    return [...participants].sort((a, b) => {
      if (a.isowner !== b.isowner) {
        return b.isowner ? 1 : -1;
      }

      if (a.isadmin !== b.isadmin) {
        return b.isadmin ? 1 : -1;
      }

      return a.username.localeCompare(b.username);
    });
  }, [participants]);

  useEffect(() => {
    if (!socket || !currentContact) return;

    const handleAddedToGroup = (msg: {
      username: string;
      user_id: string;
      group_id: string;
      isadmin: boolean;
      isowner: boolean;
    }) => {
      const { group_id } = msg;
      if (
        msg.group_id == currentContact?.conversation_id &&
        msg.user_id == user?.id
      ) {
        initializeContact({
          read: true,
          username: msg.username,
          user_id: msg.user_id,
          id: currentContact?.id,
          type: 'group',
          conversation_id: msg.group_id,
          last_active: new Date().toString(),
          last_message: '',
          last_message_sender: '',
          last_message_time: '',
        });
      }

      if (group_id === currentContact.conversation_id) {
        setParticipants((prevMembers) => {
          const existingMember = prevMembers.some(
            (m) => m.user_id === msg.user_id,
          );
          if (existingMember) {
            return prevMembers;
          }
          return [...prevMembers, msg];
        });
      }
    };

    const handleLeftGroup = (msg: { user_id: string; group_id: string }) => {
      if (
        msg.group_id == currentContact?.conversation_id &&
        msg.user_id == user?.id
      ) {
        setParticipants([]);
        initializeContact(currentContact);
      }
      setParticipants((prevMembers) =>
        prevMembers.filter((member) => member.user_id !== msg.user_id),
      );
    };

    const handleAddToAdmins = (msg: { user_id: string; group_id: string }) => {
      if (msg.group_id === currentContact.conversation_id) {
        setParticipants((prevMembers) =>
          prevMembers.map((member) =>
            member.user_id === msg.user_id
              ? { ...member, isadmin: true }
              : member,
          ),
        );
      }
    };

    const handleRemoveFromAdmins = (msg: {
      user_id: string;
      group_id: string;
    }) => {
      console.log('(socket) removed administrator: ', msg);
      if (msg.group_id === currentContact.conversation_id) {
        if (msg.user_id === user?.id) {
          setMe({ isGroupAdmin: false, isGroupOwner: false });
        }
        setParticipants((prevMembers) =>
          prevMembers.map((member) =>
            member.user_id === msg.user_id
              ? { ...member, isadmin: false }
              : member,
          ),
        );
      }
    };

    socket.on('added administrator', handleAddToAdmins);
    socket.on('removed administrator', handleRemoveFromAdmins);
    socket.on('added to group', handleAddedToGroup);
    socket.on('left group', handleLeftGroup);

    return () => {
      socket?.off('added to group');
      socket?.off('left group');
    };
  }, [socket, currentContact, currentContact, user?.id]);

  const ParticipantsList = sortedParticipants?.map(
    (participant: ParticipantsProps) => (
      <ContextMenu key={participant.user_id}>
        <ContextMenuTrigger>
          <li className="p-2 hover:bg-zinc-800 rounded-2xl flex items-center justify-between group m-2">
            <span className="flex items-center gap-2">
              <div className="flex items-center justify-center w-8 h-8  overflow-hidden rounded-full bg-gray-100">
                <img
                  src={zdjecie}
                  alt="Profile image"
                  className="h-full w-full object-cover"
                />
              </div>

              {participant.username}
              {participant.isowner ? (
                <span className="flex items-center text-yellow-400 text-xs">
                  <Crown className="h-3 w-3" />
                </span>
              ) : null}
              {participant.isadmin && (
                <span className="flex items-center text-green-300 text-xs">
                  <Sword className="h-3 w-3" />
                  <span className="ml-1 opacity-0 group-hover:opacity-100 transition-opacity">
                    admin
                  </span>
                </span>
              )}
            </span>
          </li>
        </ContextMenuTrigger>
        {user?.id !== participant.user_id &&
        me.isGroupAdmin &&
        (!participant.isadmin || me.isGroupOwner) ? (
          <ContextMenuContent className="p-0">
            <ContextMenuItem
              className="bg-zinc-900 text-white outline-1 hover:bg-zinc-800 hover:cursor-pointer"
              onClick={() => handleRemoveUser(participant.user_id)}
            >
              <p>Remove from group</p>
            </ContextMenuItem>
            {!participant.isadmin ? (
              <ContextMenuItem
                className="bg-zinc-900 text-white outline-1 hover:bg-zinc-800 hover:cursor-pointer"
                onClick={() => handleAddToAdministrators(participant.user_id)}
              >
                <p>Add to group administrator</p>
              </ContextMenuItem>
            ) : null}
            {participant.isadmin ? (
              <ContextMenuItem
                className="bg-zinc-900 text-white outline-1 hover:bg-zinc-800 hover:cursor-pointer"
                onClick={() =>
                  handleRemoveFromAdministrators(participant.user_id)
                }
              >
                <p>Remove from administrator</p>
              </ContextMenuItem>
            ) : null}
          </ContextMenuContent>
        ) : null}
      </ContextMenu>
    ),
  );

  if (!currentContact) {
    return null;
  }

  return (
    <div className="border-l border-zinc-800  bg-zinc-950 h-full w-full flex flex-col ml-auto">
      <h1 className="text-xl font-semibold text-gray-200 text-left p-4 border-b border-zinc-800">
        Members
      </h1>
      <ul className=" rounded">{ParticipantsList}</ul>
    </div>
  );
}

export default ParticipantsBar;
