import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
import { useAppSelector } from '@/redux/hooks/useAppSelector';
import { MAIN_MAP } from '@/redux/map/map.constants';
import { mapModelIdSelector, mapOpenedMapsSelector } from '@/redux/map/map.selectors';
import { closeMap, closeMapAndSetMainMapActive, setActiveMap } from '@/redux/map/map.slice';
import { OppenedMap } from '@/redux/map/map.types';
import { mainMapModelSelector } from '@/redux/models/models.selectors';
import { PluginsEventBus } from '@/services/pluginsManager/pluginsEventBus';
import { Button } from '@/shared/Button';
import { Icon } from '@/shared/Icon';
import { MouseEvent } from 'react';
import { twMerge } from 'tailwind-merge';
import { getComments } from '@/redux/comment/thunks/getComments';
import { commentSelector } from '@/redux/comment/comment.selectors';
import { hideComments, showComments } from '@/redux/comment/comment.slice';

export const MapNavigation = (): JSX.Element => {
  const dispatch = useAppDispatch();
  const openedMaps = useAppSelector(mapOpenedMapsSelector);
  const currentModelId = useAppSelector(mapModelIdSelector);
  const mainMapModel = useAppSelector(state => mainMapModelSelector(state));

  const isActive = (modelId: number): boolean => currentModelId === modelId;
  const isNotMainMap = (modelName: string): boolean => modelName !== MAIN_MAP;

  const commentsOpen = useAppSelector(commentSelector).isOpen;

  const onCloseSubmap = (event: MouseEvent<HTMLDivElement>, map: OppenedMap): void => {
    event.stopPropagation();
    if (isActive(map.modelId)) {
      dispatch(
        closeMapAndSetMainMapActive({
          modelId: mainMapModel.idObject,
          currentModelId: map.modelId,
        }),
      );

      PluginsEventBus.dispatchEvent('onSubmapClose', map.modelId);
      PluginsEventBus.dispatchEvent('onSubmapOpen', mainMapModel.idObject);
    } else {
      dispatch(closeMap({ modelId: map.modelId }));
    }
  };

  const onSubmapTabClick = (map: OppenedMap): void => {
    dispatch(setActiveMap(map));
    if (currentModelId !== map.modelId) {
      PluginsEventBus.dispatchEvent('onSubmapClose', currentModelId);
      PluginsEventBus.dispatchEvent('onSubmapOpen', map.modelId);
    }
  };

  const toggleComments = async (): Promise<void> => {
    if (!commentsOpen) {
      await dispatch(getComments());
      dispatch(showComments());
    } else {
      dispatch(hideComments());
    }
  };

  return (
    <div className="flex h-10 w-full flex-row flex-nowrap justify-between overflow-y-auto bg-white-pearl text-xs shadow-primary">
      <div className="flex flex-row items-center justify-start">
        {openedMaps.map(map => (
          <Button
            key={map.modelId}
            className={twMerge(
              'relative h-10 whitespace-nowrap',
              isActive(map.modelId) ? 'bg-[#EBF4FF]' : 'font-normal',
            )}
            variantStyles={isActive(map.modelId) ? 'secondary' : 'ghost'}
            onClick={(): void => onSubmapTabClick(map)}
          >
            <span className="max-w-[256px] truncate">{map.modelName}</span>

            {isNotMainMap(map.modelName) && (
              // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
              <div onClick={(event): void => onCloseSubmap(event, map)} data-testid="close-icon">
                <Icon name="close" className="ml-3 h-5 w-5 fill-font-400" />
              </div>
            )}
          </Button>
        ))}
      </div>
      <div className="flex items-center">
        <Button
          className="mx-4 flex-none"
          variantStyles="secondary"
          onClick={() => toggleComments()}
        >
          {commentsOpen ? 'Hide Comments' : 'Show Comments'}
        </Button>
      </div>
    </div>
  );
};