/* eslint-disable react/no-array-index-key */
import React, { FC, isValidElement } from 'react';
import styled from '@emotion/styled';
import { css } from '@emotion/react';
import { ArrowLeftOutlined, CaretDownOutlined, EllipsisOutlined } from '@ant-design/icons';
import useMedia from 'react-use/lib/useMedia';
import Button from '../../button';

import SimplePagination, { SimplePaginationProps } from '../../simple-pagination';
import { Title, TitleProps } from './Title';
import Dropdown from '../../dropdown';
import Menu from '../../menu';
import Space from '../../space';
import { ContentButtonProps, createButton } from '../../button/button';

interface MenuGroupDescriptor {
  /** 标题 */
  title: React.ReactNode;
  /** 禁用 */
  disabled?: boolean;
  /** 行为 */
  actions: {
    /** 内容 */
    content: React.ReactNode;
    /** 图标 */
    icon?: React.ReactNode;
    /** 禁用 */
    disabled?: boolean;
    /** 点击回调 */
    onClick?: () => void;
  }[];
}

export interface HeaderProps extends TitleProps {
  /** 返回回调 */
  onBack?: () => void;

  /** 主按钮 */
  primaryAction?: ContentButtonProps | React.ReactNode;

  /** 次级按钮组 */
  secondaryActions?: ContentButtonProps[];

  /** 额外的需要显示的东西 显示在左侧 */
  additionalMetaData?: React.ReactNode | string;

  /** 下拉菜单 */
  actionGroups?: MenuGroupDescriptor[];

  /** 额外的需要显示的东西 显示在右侧 */
  additionalNavigation?: React.ReactNode;

  /** 页面级分页 */
  pagination?: SimplePaginationProps;

  breadcrumb?: React.ReactNode;

  headerStyle?: React.CSSProperties;
}

const StyledHeader = styled.div`
  position: relative;
  padding: 24px 24px 0;

  ${({ theme }) => css`
    @media (min-width: ${theme.breakpoints.sm}) {
      padding-right: 0;
      padding-left: 0;
    }
  `}
`;

const HeaderRowCondensed = styled.div<{ hasBack: boolean }>`
  display: flex;
  align-items: flex-start;
  justify-content: space-between;

  ${({ hasBack }) =>
    hasBack &&
    css`
      @media (max-width: 991px) {
        display: grid;
        grid-template-areas:
          'breadcrumbs actions'
          'title title';
        grid-template-columns: auto 1fr;
        gap: 8px 16px;
      }
    `}
`;

const HeaderRow = styled.div`
  display: flex;
  justify-content: space-between;

  margin-top: 8px;
`;

const HeaderTitleWrapper = styled.div`
  flex: 1 1 auto;
  grid-area: title;
  align-self: center;
`;

const HeaderBreadcrumbWrapper = styled.div`
  flex: 0 0 auto;
  grid-area: breadcrumbs;

  max-width: 100%;

  margin-right: 16px;
`;

const HeaderLeftAlign = styled.div`
  display: flex;
  align-content: flex-start;
  align-items: center;
`;

const HeaderAdditionalMetaData = styled.div<{ hasOnBack: boolean }>`
  margin-left: 0;

  @media (min-width: 992px) {
    margin-left: ${({ hasOnBack }) => hasOnBack && '52px'};
  }
`;

const HeaderRightAlign = styled.div`
  display: flex;
  flex: 1 1 auto;
  grid-area: actions;
  align-items: flex-start;
  justify-content: flex-end;

  margin-left: 16px;
  white-space: nowrap;
`;

const HeaderAdditionalNavigationWrapper = styled.div`
  display: flex;
  flex: 1 0 auto;
  justify-content: flex-end;

  margin: 0 8px;
  margin-right: 0;

  @media (min-width: 490px) {
    margin: 0 32px;
    margin-right: 0;
  }
`;

const HeaderPrimaryActionWrapper = styled.div`
  flex: 0 0 auto;

  margin-top: 0;
  margin-left: 10px;
`;

const IconButton = styled.div`
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;

  width: 36px;

  min-height: 36px;

  margin: 0;
  padding: 2px;
  cursor: pointer;

  ${({ theme }) => css`
    color: #6d7175;
    border: 1px solid #babfc3;
    border-radius: ${theme.radii.md};

    :hover {
      background-color: ${theme.colors.gray[50]};

      svg {
        fill: ${theme.colors.gray[600]};
      }
    }

    :active {
      background-color: #f1f2f3;

      svg {
        fill: ${theme.colors.gray[700]};
      }
    }
  `}
`;

export function isPrimaryAction(x: ContentButtonProps | React.ReactNode): x is ContentButtonProps {
  return !isValidElement(x) && x !== undefined;
}

function PrimaryActionMarkup({
  primaryAction,
}: {
  primaryAction: ContentButtonProps | React.ReactNode;
}) {
  let content = primaryAction;
  if (isPrimaryAction(primaryAction)) {
    const type = primaryAction.type === undefined ? 'primary' : primaryAction.type;

    content = createButton(primaryAction, {
      type,
    });
  }

  return <HeaderPrimaryActionWrapper>{content}</HeaderPrimaryActionWrapper>;
}

export const Header: FC<HeaderProps> = ({
  subtitle,
  titleMetadata,
  title,
  pagination,
  thumbnail,
  onBack,
  secondaryActions = [],
  actionGroups = [],
  primaryAction,
  additionalMetaData,
  additionalNavigation,
  breadcrumb,
  headerStyle,
}) => {
  const isNavigationCollapsed = useMedia('(max-width: 768px)');

  let actionMenuMarkup;

  actionMenuMarkup = isNavigationCollapsed ? (
    <Dropdown
      overlay={
        <Menu>
          {secondaryActions.map(({ content, onClick, disabled, icon }, index) => (
            <Menu.Item
              key={index}
              disabled={disabled}
              onClick={({ domEvent }) => onClick && onClick(domEvent)}
            >
              {icon}
              {content}
            </Menu.Item>
          ))}
          {actionGroups.map((actionItem, index) => (
            <Menu.ItemGroup
              key={`actionItem-${index}`}
              title={actionItem.title}
              disabled={actionItem.disabled}
            >
              {actionItem.actions.map((item, i) => (
                <Menu.Item key={`item-${i}`} disabled={item.disabled} onClick={item.onClick}>
                  {item.icon}
                  {item.content}
                </Menu.Item>
              ))}
            </Menu.ItemGroup>
          ))}
        </Menu>
      }
      trigger={['click']}
    >
      <IconButton>
        <EllipsisOutlined style={{ fontSize: 22 }} />
      </IconButton>
    </Dropdown>
  ) : (
    <Space size={[10, 0]} wrap style={{ justifyContent: 'flex-end', rowGap: 8 }}>
      {secondaryActions.map(({ content, ...rest }, index) => (
        <Button {...rest} key={index}>
          {content}
        </Button>
      ))}
      {actionGroups.map((actionItem, index) => (
        <Dropdown
          disabled={actionItem.disabled}
          key={index}
          overlay={
            <Menu>
              {actionItem.actions.map((item, i) => (
                <Menu.Item key={i} disabled={item.disabled} onClick={item.onClick}>
                  {item.icon}
                  {item.content}
                </Menu.Item>
              ))}
            </Menu>
          }
          trigger={['click']}
        >
          <Button type="text">
            {actionItem.title}
            <CaretDownOutlined />
          </Button>
        </Dropdown>
      ))}
    </Space>
  );

  if (actionGroups.length === 0 && secondaryActions.length === 0) {
    actionMenuMarkup = null;
  }

  const paginationMarkup = pagination ? (
    <SimplePagination style={{ marginLeft: 10 }} {...pagination} />
  ) : null;

  const primaryActionMarkup = primaryAction ? (
    <PrimaryActionMarkup primaryAction={primaryAction} />
  ) : null;

  return (
    <StyledHeader style={headerStyle}>
      <HeaderRowCondensed hasBack={!!onBack}>
        {onBack ? (
          <HeaderBreadcrumbWrapper>
            <IconButton onClick={onBack}>
              <ArrowLeftOutlined style={{ fontSize: 18 }} />
            </IconButton>
          </HeaderBreadcrumbWrapper>
        ) : null}

        <HeaderTitleWrapper>
          <Title
            subtitle={subtitle}
            thumbnail={thumbnail}
            title={title}
            titleMetadata={titleMetadata}
            breadcrumb={breadcrumb}
          />
        </HeaderTitleWrapper>

        <HeaderRightAlign>
          {actionMenuMarkup}
          {primaryActionMarkup}
          {paginationMarkup}
        </HeaderRightAlign>
      </HeaderRowCondensed>

      {additionalMetaData || additionalNavigation ? (
        <HeaderRow>
          <HeaderLeftAlign>
            <HeaderAdditionalMetaData hasOnBack={!!onBack}>
              {additionalMetaData}
            </HeaderAdditionalMetaData>
          </HeaderLeftAlign>

          <HeaderRightAlign>
            <HeaderAdditionalNavigationWrapper>
              {additionalNavigation}
            </HeaderAdditionalNavigationWrapper>
          </HeaderRightAlign>
        </HeaderRow>
      ) : null}
    </StyledHeader>
  );
};
