import { useCallback } from 'react';

import { useHistory } from 'react-router-dom';

import { isFulfilled, isRejected } from '@reduxjs/toolkit';

import { openURL } from 'flavours/glitch/actions/search';
import { useAppDispatch } from 'flavours/glitch/store';

const isMentionClick = (element: HTMLAnchorElement) =>
  element.classList.contains('mention') &&
  !element.classList.contains('hashtag');

const isHashtagClick = (element: HTMLAnchorElement) =>
  element.textContent?.[0] === '#' ||
  element.previousSibling?.textContent?.endsWith('#');

export const useLinks = (skipHashtags?: boolean) => {
  const history = useHistory();
  const dispatch = useAppDispatch();

  const handleHashtagClick = useCallback(
    (element: HTMLAnchorElement) => {
      const { textContent } = element;

      if (!textContent) return;

      history.push(`/tags/${textContent.replace(/^#/, '')}`);
    },
    [history],
  );

  const handleMentionClick = useCallback(
    async (element: HTMLAnchorElement) => {
      const result = await dispatch(openURL({ url: element.href }));

      if (isFulfilled(result)) {
        if (result.payload.accounts[0]) {
          history.push(`/@${result.payload.accounts[0].acct}`);
        } else if (result.payload.statuses[0]) {
          history.push(
            `/@${result.payload.statuses[0].account.acct}/${result.payload.statuses[0].id}`,
          );
        } else {
          window.location.href = element.href;
        }
      } else if (isRejected(result)) {
        window.location.href = element.href;
      }
    },
    [dispatch, history],
  );

  const handleClick = useCallback(
    (e: React.MouseEvent) => {
      const target = (e.target as HTMLElement).closest('a');

      if (!target || e.button !== 0 || e.ctrlKey || e.metaKey) {
        return;
      }

      if (isMentionClick(target)) {
        e.preventDefault();
        void handleMentionClick(target);
      } else if (isHashtagClick(target) && !skipHashtags) {
        e.preventDefault();
        handleHashtagClick(target);
      }
    },
    [skipHashtags, handleMentionClick, handleHashtagClick],
  );

  return handleClick;
};
