import { useMemo } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import Link from 'next/link';
import { usePagesManifest, usePagePathPrefix, usePageType, useRouterPath } from "../../../hooks/election/index.js";
import { resolveElectionLink } from "../../../utils/election/index.js";
import { useTrackStandardEvent } from "../../../hooks/tracking/index.js";
import classes from './styles.module.scss';

/**
 * A link for navigating an elections rig. Does not handle styling. This
 * is just for the navigational behavior. This component leverages several
 * atoms to correctly render links:
 * - `pagePathPrefix` gets appended to a resolved page path
 * - `pageType` determines if the link renders as a `next/link` (when page type
 *   is `page`) or a native `<a>` tag (otherwise)
 * - `pagesManifest` is used to look up page paths
 *
 * Because of this behavior, the proper way to get links to work in the context
 * of embeds is to set the `pagePathPrefix` to a full URL prefix (e.g.,
 * `https://www.politico.com/path/prefix`) and `pageType` to `embed`. That way,
 * page links will link to the absolute URLs of the pages.
 *
 * Also note that because on-page links are rendered with `next/link`, in the
 * context of a rig page the `pagePathPrefix` should not be the whole
 * deployment prefix, but rather _just_ the prefix of the page in the context
 * of the Next app. For example, if the pages are published at the prefix
 * `/2024-election/results/` and the Next page being used to render the pages
 * is at `src/pages/example/[[...page]].js` then the appropriate path prefix is
 * just `/example`.
 */
const ElectionLink = function ElectionLink(props) {
  const {
    to,
    children,
    tracking,
    ...restProps
  } = props;
  const pageType = usePageType();
  const pagePathPrefix = usePagePathPrefix();
  const manifest = usePagesManifest();
  const routerPath = useRouterPath();
  const {
    targetType,
    url
  } = useMemo(() => resolveElectionLink({
    manifest,
    pagePathPrefix,
    link: to,
    currentUrl: routerPath
  }), [manifest, pagePathPrefix, to, routerPath]);
  const track = useTrackStandardEvent({
    component: 'ElectionLink',
    event: targetType,
    context: tracking?.context,
    detail: tracking?.linkName || url
  });
  const targetProps = useMemo(() => {
    if (targetType === 'external') {
      return {
        target: '_blank',
        rel: 'noopener noreferrer'
      };
    }
    if (pageType === 'embed') {
      return {
        target: '_top'
      };
    }
    return {};
  }, [targetType, pageType]);
  const nativeLinkProps = {
    ...restProps,
    className: classnames(classes.link, restProps.className),
    onClick: track
  };
  if (!url) {
    return children;
  }
  if (pageType !== 'page') {
    return <a {...nativeLinkProps} {...targetProps} href={url}>
        {children}
      </a>;
  }
  return <Link href={url} legacyBehavior>
      <a {...nativeLinkProps} {...targetProps}>
        {children}
      </a>
    </Link>;
};
ElectionLink.defaultProps = {
  to: undefined,
  children: undefined,
  tracking: {}
};
ElectionLink.propTypes = {
  /**
   * The place to link to, usually a page role.
   */
  to: PropTypes.string,
  /**
   * The contents of the link.
   */
  children: PropTypes.oneOfType([PropTypes.node, PropTypes.arrayOf(PropTypes.node)]),
  /**
   * Tracking configuration
   */
  tracking: PropTypes.shape({
    context: PropTypes.string,
    linkName: PropTypes.string
  })
};
export default ElectionLink;