import clsx from 'clsx';
import React from 'react';
import { Data } from '../../../../../types/data';
import { IconName, Icons } from '../../../../Icons';
import { ColumnRenderer } from '../../../List.model';
import classes from './ExternalLinkRenderer.scss';

export type ExternalLinkResolver<T extends Data> = (
  /** Row data */
  item: T,
  /** Whether or not the external icon is shown (default: true) */
  showNewTabIcon?: boolean,
) => string | undefined;

/**
 * Renders an external link for an item.
 * If the resolver does not return a URL for an item, no link will be rendered for that item.
 *
 * @param resolver Callback function. Row data is passed as an argument.
 * @param showNewTabIcon Optional boolean that determines whether or not the external icon is shown (default: true)
 * @returns A string that should be a valid url
 *
 * @example
 * <List
 *   {...otherProps}
 *   columns=[{
 *     propertyName: 'title'
 *     render: createExternalLinkRenderer(data => `https://www.example.com/${data.id}`)
 * }]/>
 */
export const createExternalLinkRenderer = <T extends Data>(
  resolver: ExternalLinkResolver<T>,
  showNewTabIcon = true,
): ColumnRenderer<T> => {
  const ExternalLinkRenderer = (val: unknown, data: T): JSX.Element => {
    const url = resolver(data);
    const value = String(val);

    if (!url) {
      // if there is no url, we will just render the value
      return <p title={value}>{value}</p>;
    }

    const handleClick = (event: React.SyntheticEvent): void => {
      event.stopPropagation(); // prevent other events from propagating up
    };

    return (
      <a
        className={clsx(classes.container, {
          [classes.noIcon]: !showNewTabIcon,
        })}
        href={url}
        target="_blank"
        rel="noopener noreferrer"
        onClick={handleClick}
      >
        <p title={value}>{value}</p>
        {showNewTabIcon && (
          <Icons icon={IconName.External} className={classes.externalIcon} />
        )}
      </a>
    );
  };
  return ExternalLinkRenderer;
};
