import React, { useState } from 'react';
import styled from 'styled-components';

import type { JSX } from 'react';
import type { PageAction } from '@redocly/theme/core/types';

import { PageActionsMenuItem } from '@redocly/theme/components/PageActions/PageActionsMenuItem';
import { DropdownMenuItem } from '@redocly/theme/components/Dropdown/DropdownMenuItem';
import { Link } from '@redocly/theme/components/Link/Link';
import { ButtonGroup } from '@redocly/theme/components/Button/ButtonGroup';
import { Button } from '@redocly/theme/components/Button/Button';
import { Dropdown } from '@redocly/theme/components/Dropdown/Dropdown';
import { DropdownMenu } from '@redocly/theme/components/Dropdown/DropdownMenu';
import { Spinner } from '@redocly/theme/icons/Spinner/Spinner';
import { CheckmarkFilledIcon } from '@redocly/theme/icons/CheckmarkFilledIcon/CheckmarkFilledIcon';
import { PageActionType, usePageActions } from '@redocly/theme/core/hooks';

type ActionState = 'idle' | 'processing' | 'done';

type PageActionProps = {
  pageSlug?: string;
  mcpUrl?: string;
  actions?: PageActionType[];
};

const ACTION_DONE_DISPLAY_DURATION = 1000;

export function PageActions(props: PageActionProps): JSX.Element | null {
  const { pageSlug, mcpUrl } = props;

  const actions = usePageActions(pageSlug || '/', mcpUrl, props.actions);

  const [actionState, setActionState] = useState<ActionState>('idle');

  if (!actions.length) {
    return null;
  }

  const buttonAction = actions[0];

  const handleActionClick = async (action: PageAction) => {
    if (!('onClick' in action)) {
      return;
    }

    setActionState('processing');

    await action.onClick();
    setActionState('done');
    setTimeout(() => {
      setActionState('idle');
    }, ACTION_DONE_DISPLAY_DURATION);
  };

  const menuItems = actions.map((action, index) => {
    const key = `${action.title}-${index}`;
    const hasLink = 'link' in action;

    const content = hasLink ? (
      <LinkMenuItem key={`${key}-link`} to={action.link} tabIndex={-1} external>
        <PageActionsMenuItem pageAction={action} />
      </LinkMenuItem>
    ) : (
      <PageActionsMenuItem pageAction={action} />
    );

    return (
      <StyledDropdownMenuItem key={key} onAction={() => handleActionClick(action)}>
        {content}
      </StyledDropdownMenuItem>
    );
  });

  return (
    <PageActionsWrapper data-component-name="PageActions/PageActions">
      <ButtonGroup variant="outlined" size="medium">
        <Button
          icon={renderIcon(buttonAction, actionState)}
          to={'link' in buttonAction ? buttonAction.link : undefined}
          external
          onClick={() => handleActionClick(buttonAction)}
        >
          {buttonAction.buttonText}
        </Button>
        {actions.length > 1 ? (
          <StyledDropdown
            withArrow
            trigger={<Button aria-label="More actions" />}
            placement="bottom"
            alignment="end"
          >
            <StyledDropdownMenu>{menuItems}</StyledDropdownMenu>
          </StyledDropdown>
        ) : null}
      </ButtonGroup>
    </PageActionsWrapper>
  );
}

function renderIcon(buttonAction: PageAction, actionState: ActionState) {
  switch (actionState) {
    case 'processing':
      return <Spinner color="var(--page-actions-processing-icon-color)" />;
    case 'done':
      return <CheckmarkFilledIcon color="var(--page-actions-done-icon-color)" />;
    default:
      return <buttonAction.iconComponent />;
  }
}

const PageActionsWrapper = styled.div`
  margin-left: auto;
  padding-left: var(--page-actions-padding-left);
  --button-color: var(--page-actions-button-text-color);

  .button-group-size-medium .button.button-size-medium {
    --button-icon-left-padding: var(--page-actions-button-padding);
  }
`;

const LinkMenuItem = styled(Link)`
  text-decoration: none;
  --link-decoration: none;
  --link-decoration-hover: none;
`;

const StyledDropdown = styled(Dropdown)`
  --dropdown-menu-z-index: calc(var(--z-index-raised) - 1);
`;

const StyledDropdownMenu = styled(DropdownMenu)`
  --dropdown-menu-max-height: var(--page-actions-dropdown-max-height);
`;

const StyledDropdownMenuItem = styled(DropdownMenuItem)`
  &:has(a) {
    padding: 0;
    & > a {
      display: inline-block;
      width: 100%;
      padding: var(--dropdown-menu-item-padding-vertical) var(--dropdown-menu-item-padding-horizontal);
    }
  }
`;
