import {useCallback, useMemo} from 'react';
import {useSortable} from '@dnd-kit/sortable';
import styled from '@emotion/styled';

import type {ButtonProps} from 'sentry/components/button';
import {Button} from 'sentry/components/button';
import DropdownButton from 'sentry/components/dropdownButton';
import type {MenuItemProps} from 'sentry/components/dropdownMenu';
import {DropdownMenu} from 'sentry/components/dropdownMenu';
import FeatureBadge from 'sentry/components/featureBadge';
import ExternalLink from 'sentry/components/links/externalLink';
import {IconAdd} from 'sentry/icons';
import {t} from 'sentry/locale';
import {space} from 'sentry/styles/space';
import {trackAnalytics} from 'sentry/utils/analytics';
import {hasCustomMetrics} from 'sentry/utils/metrics/features';
import useOrganization from 'sentry/utils/useOrganization';
import {DataSet} from 'sentry/views/dashboards/widgetBuilder/utils';

import {DisplayType} from './types';
import WidgetWrapper from './widgetWrapper';

export const ADD_WIDGET_BUTTON_DRAG_ID = 'add-widget-button';

const initialStyles = {
  x: 0,
  y: 0,
  scaleX: 1,
  scaleY: 1,
};

type Props = {
  onAddWidget: (dataset: DataSet) => void;
};

function AddWidget({onAddWidget}: Props) {
  const {setNodeRef, transform} = useSortable({
    disabled: true,
    id: ADD_WIDGET_BUTTON_DRAG_ID,
    transition: null,
  });

  const organization = useOrganization();

  return (
    <WidgetWrapper
      key="add"
      ref={setNodeRef}
      displayType={DisplayType.BIG_NUMBER}
      layoutId={ADD_WIDGET_BUTTON_DRAG_ID}
      style={{originX: 0, originY: 0}}
      animate={
        transform
          ? {
              x: transform.x,
              y: transform.y,
              scaleX: transform?.scaleX && transform.scaleX <= 1 ? transform.scaleX : 1,
              scaleY: transform?.scaleY && transform.scaleY <= 1 ? transform.scaleY : 1,
            }
          : initialStyles
      }
      transition={{
        duration: 0.25,
      }}
    >
      {hasCustomMetrics(organization) ? (
        <InnerWrapper>
          <AddWidgetButton
            onAddWidget={onAddWidget}
            aria-label="Add Widget"
            data-test-id="widget-add"
          />
        </InnerWrapper>
      ) : (
        <InnerWrapper onClick={() => onAddWidget(DataSet.EVENTS)}>
          <AddButton
            data-test-id="widget-add"
            icon={<IconAdd size="lg" isCircled color="inactive" />}
            aria-label={t('Add widget')}
          />
        </InnerWrapper>
      )}
    </WidgetWrapper>
  );
}

const AddButton = styled(Button)`
  border: none;
  &,
  &:focus,
  &:active,
  &:hover {
    background: transparent;
    box-shadow: none;
  }
`;

export default AddWidget;

export function AddWidgetButton({onAddWidget, ...buttonProps}: Props & ButtonProps) {
  const organization = useOrganization();

  const handleAction = useCallback(
    (dataset: DataSet) => {
      trackAnalytics('dashboards_views.widget_library.opened', {
        organization,
      });
      onAddWidget(dataset);
    },
    [organization, onAddWidget]
  );

  const items = useMemo(() => {
    const menuItems: MenuItemProps[] = [
      {
        key: DataSet.EVENTS,
        label: t('Errors and Transactions'),
        onAction: () => handleAction(DataSet.EVENTS),
      },
      {
        key: DataSet.ISSUES,
        label: t('Issues'),
        details: t('States, Assignment, Time, etc.'),
        onAction: () => handleAction(DataSet.ISSUES),
      },
    ];

    if (organization.features.includes('dashboards-rh-widget')) {
      menuItems.push({
        key: DataSet.RELEASES,
        label: t('Releases'),
        details: t('Sessions, Crash rates, etc.'),
        onAction: () => handleAction(DataSet.RELEASES),
      });
    }

    if (hasCustomMetrics(organization)) {
      menuItems.push({
        key: DataSet.METRICS,
        label: t('Custom Metrics'),
        onAction: () => handleAction(DataSet.METRICS),
        trailingItems: <FeatureBadge type="beta" />,
      });
    }

    return menuItems;
  }, [handleAction, organization]);

  return (
    <DropdownMenu
      items={items}
      trigger={triggerProps => (
        <DropdownButton
          {...triggerProps}
          {...buttonProps}
          data-test-id="widget-add"
          size="sm"
          icon={<IconAdd isCircled />}
        >
          {t('Add Widget')}
        </DropdownButton>
      )}
      menuTitle={
        <MenuTitle>
          {t('Dataset')}
          <ExternalLink href="https://docs.sentry.io/product/dashboards/widget-builder/#choose-your-dataset">
            {t('Learn more')}
          </ExternalLink>
        </MenuTitle>
      }
    />
  );
}

const InnerWrapper = styled('div')<{onClick?: () => void}>`
  width: 100%;
  height: 110px;
  border: 2px dashed ${p => p.theme.border};
  border-radius: ${p => p.theme.borderRadius};
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: ${p => (p.onClick ? 'pointer' : '')};
`;

const MenuTitle = styled('span')`
  display: flex;
  gap: ${space(1)};

  & > a {
    font-weight: normal;
  }
`;