import {
  AnimateSlideDown,
  Dropdown,
  DropdownItem,
  DropdownSeparator,
  IconAlertCircle,
  IconArrowUpRight,
  IconImage,
  IconLoading,
  location,
  MeatballMenu,
  SubtleButton,
  SubtleButtonLink,
  Tooltip
} from "@heydovetail/ui-components";
import React from "react";
import { styled } from "typestyle-react";
import { AttachmentService } from "../../AttachmentService";
import { Attachment } from "../../util/attrs";
import { humanAttachmentTitle } from "../../util/text";
import { AttachmentDownloadUrlSubscribe } from "./AttachmentDownloadUrlSubscribe";
import { AttachmentInfoDropdown } from "./AttachmentInfoDropdown";

export function ToolbarItems(props: {
  attachment: Attachment;
  attachmentService: AttachmentService;
  hasPreview: boolean;
  onRemove: () => void;
  onHidePreview?: () => void;
  onShowPreview?: () => void;
}) {
  const { name, hidePreview, type } = props.attachment;
  const icon = type !== undefined ? iconForType(type) : null;

  return (
    <>
      <Details>
        {icon !== null ? <Icon>{icon}</Icon> : null}
        <Name>{humanAttachmentTitle(name)}</Name>
      </Details>
      <AttachmentDownloadUrlSubscribe attachment={props.attachment} attachmentService={props.attachmentService}>
        {(attachmentDownloadUrl): React.ReactElement<{}> => {
          switch (attachmentDownloadUrl.type) {
            case "refreshing":
            case "pending":
              return (
                <SubtleButton disabled onClick={() => {}}>
                  <IconLoading />
                </SubtleButton>
              );
            case "unavailable":
              return (
                <Tooltip text="This attachment is currently unavailable">
                  <SubtleButton disabled onClick={() => {}}>
                    <IconAlertCircle />
                  </SubtleButton>
                </Tooltip>
              );
            case "available":
              return (
                <SubtleButtonLink location={location.external(attachmentDownloadUrl.url, { openInNewTab: true })}>
                  <IconArrowUpRight />
                </SubtleButtonLink>
              );
          }
        }}
      </AttachmentDownloadUrlSubscribe>

      <MeatballMenu align="right" subtle>
        {({ dismiss, push }) => (
          <Dropdown onLeafClick={dismiss}>
            {props.hasPreview ? (
              hidePreview ? (
                <DropdownItem value="Show preview" action={props.onShowPreview} />
              ) : (
                <DropdownItem value="Hide preview" action={props.onHidePreview} />
              )
            ) : null}
            <DropdownItem
              branch
              value="Show info"
              action={() =>
                push(
                  <AnimateSlideDown>
                    <AttachmentInfoDropdown attachment={props.attachment} />
                  </AnimateSlideDown>
                )
              }
            />
            <DropdownSeparator />
            <DropdownItem value="Remove" action={props.onRemove} />
          </Dropdown>
        )}
      </MeatballMenu>
    </>
  );
}

const Details = styled("div", {
  alignItems: "center",
  display: "flex",
  flexGrow: 1,
  // When used in an attachment card, and the user drags when a mouse, this
  // prevents the dragged preview from being just the name or icon, and instead
  // causes the drag to happen on the card container, which means the entire
  // card is rendered in a dragged preview.
  pointerEvents: "none"
});

const Name = styled("div", {
  fontSize: "14px",
  fontWeight: 600
});

const Icon = styled("div", {
  marginRight: "12px"
});

function iconForType(type: string): React.ReactElement<{}> | null {
  if (type.match(/^image\//) !== null) {
    return <IconImage />;
  }

  return null;
}
