/**
 * TEAM: frontend_infra
 * @flow strict
 */

import * as React from "react";
import {StyleSheet, css} from "aphrodite";
import Text from "../Text";
import IconButton from "../button/IconButton";
import Icon from "../Icon";
import Link from "../Link";

import latitudeColors from "../colors";

const sizes = {
  xs: 20,
  s: 24,
  m: 30,
  l: 40,
};

const spacing = {
  xs: 7,
  s: 7,
  m: 8,
  l: 12,
};

// Todo: this component should eventually be extended to include a filename edit
// mode and be used in DocumentUploader and FileUploader

type Props = {|
  /** The information to display */
  +filename: string,
  /** The url the file pill redirects to when the text is clicked. Links will be
   * opened in a new tab.
   */
  +href: string,
  /** The function invoked when the trash icon is clicked. If onRemove is not
   * provided, there will not be a trash icon */
  +onRemove?: () => mixed,
  /** The size of the file pill */
  +size?: $Keys<typeof sizes>,
|};

/**
 * @short A compact display component for files that have been uploaded
 * @brandStatus V2
 * @status Beta
 * @category Data Display
 *
 * FilePills are used for indicated the filename of attachments.
 */
export default function FilePill({
  filename,
  href,
  onRemove,
  size = "m",
}: Props): React.Element<"span"> {
  const style = {
    height: sizes[size],
    padding: `0 ${spacing[size]}px`,
  };

  const shortFilename = truncateMiddle(filename, 25);

  return (
    <span className={css(styles.filePill)} style={style}>
      <Text
        scale="subtext"
        overflow="hidden"
        textOverflow="ellipsis"
        color="grey60"
        whiteSpace="nowrap"
      >
        <Link href={href} openInNewTab={true} className={css(styles.link)}>
          {shortFilename}{" "}
          {!onRemove ? (
            <span style={{paddingLeft: "2px"}}>
              <Icon
                iconName="export"
                size="xs"
                color="grey60"
                deprecatedAllowColorInheritance={false}
              />
            </span>
          ) : null}
        </Link>
      </Text>
      {onRemove ? (
        <span style={{paddingLeft: "4px"}}>
          <IconButton
            type="button"
            kind="blank"
            iconName="trash"
            onClick={onRemove}
            height={{type: "customDontUse", height: 12}}
          />
        </span>
      ) : null}
    </span>
  );
}

const styles = StyleSheet.create({
  filePill: {
    boxSizing: "border-box",
    display: "inline-flex",
    position: "relative",
    alignItems: "center",
    border: `solid 2px ${latitudeColors.grey20}`,
    maxWidth: "100%",
    background: latitudeColors.grey10,
    overflow: "hidden",
  },
  link: {
    color: latitudeColors.grey60,
  },
});

// This was copied from the internal tools/TextFormatTools.js
function truncateMiddle(str: string, maxLength: number) {
  // A maxLength under 4 would return just the ellipsis.
  if (str == null || maxLength < 4 || str.length <= maxLength) {
    return str;
  }
  // The length of the ellipsis (3) is counted towards the max length.
  // The first half will have the extra character if maxLength is even.
  const firstHalf = str.substring(0, Math.ceil((maxLength - 3) / 2));
  const secondHalf = str.substring(
    str.length - Math.floor((maxLength - 3) / 2)
  );
  return `${firstHalf}...${secondHalf}`;
}
