import styled, { css, FlattenSimpleInterpolation } from 'styled-components';

import {
  Breakpoint,
  getBreakpointValue,
} from '../../utils/responsiveBreakpoints';

import Select from '../Select/SingleSelect';

const hideIfLessThan = (
  breakpoint?: Breakpoint
): FlattenSimpleInterpolation => {
  const maxWidth =
    breakpoint !== undefined ? getBreakpointValue(breakpoint) : 0;
  return css`
    @media (max-width: ${maxWidth}px) {
      display: none;
    }
  `;
};

const stickHorizontally = (shouldStickHorizontally: boolean, left?: number) =>
  shouldStickHorizontally && left !== undefined
    ? css`
        position: sticky;
        left: ${left}px;
        z-index: 1;
        &:hover {
          z-index: 2;
        }
      `
    : css``;

const showDivider = (shouldShowDivider: boolean) =>
  shouldShowDivider
    ? css`
        :after {
          position: absolute;
          top: 0;
          right: 0;
          bottom: 0;
          width: ${({ theme }) => theme.sizes.table.columnDividerWidth};
          transform: translateX(100%);
          content: '';
          box-shadow: ${({ theme }) => theme.shadows.table.columnDivider};
        }
      `
    : css``;

const StyledTH = styled.th<{
  themeDisplayAtBreakpoint?: Breakpoint;
  themeHorizontallySticky: boolean;
  themeLeft?: number;
  themeShowDivider: boolean;
  themeSticky: boolean;
  themeWidth?: string | number;
}>`
  box-sizing: border-box;
  font-size: ${({ theme }) => theme.fontSizes.table.header};
  line-height: ${({ theme }) => theme.lineHeights.table.header};
  font-weight: ${({ theme }) => theme.fontWeights.table.header};
  color: ${({ theme }) => theme.colors.table.headerText};
  background-color: ${({ theme }) => theme.colors.table.headerBackground};

  margin: 0;
  padding: ${({ theme }) => theme.space.table.headerPadding};
  width: ${({ themeWidth }) =>
    typeof themeWidth === 'string' ? themeWidth : undefined};

  ${(props): FlattenSimpleInterpolation =>
    hideIfLessThan(props.themeDisplayAtBreakpoint)};

  ${({ themeSticky }) => {
    switch (themeSticky) {
      case true:
        return css`
          position: sticky;
          top: 0;
          z-index: 1;
        `;
      case false:
        return css``;
    }
  }};

  ${({ themeHorizontallySticky, themeLeft }) =>
    stickHorizontally(themeHorizontallySticky, themeLeft)};

  ${({ themeShowDivider }) => showDivider(themeShowDivider)};
`;

const StyledInnerTH = styled.div<{ themeAlign: 'left' | 'right' }>`
  display: flex;
  align-items: center;

  margin: 0;
  padding: 0;

  ${({ themeAlign }) => {
    switch (themeAlign) {
      case 'left':
        return css`
          text-align: left;
          justify-content: flex-start;
        `;
      case 'right':
        return css`
          text-align: right;
          justify-content: flex-end;
        `;
    }
  }};
`;

const StyledTD = styled.td<{
  themeAlign?: 'left' | 'right';
  themeDisplayAtBreakpoint?: Breakpoint;
  themeHorizontallySticky: boolean;
  themeLeft?: number;
  themeShowDivider: boolean;
  themeWidth?: string;
}>`
  background-color: inherit;

  ${(props): FlattenSimpleInterpolation =>
    hideIfLessThan(props.themeDisplayAtBreakpoint)};

  ${({ themeAlign }) => {
    switch (themeAlign) {
      case undefined:
      case 'left':
        return css`
          text-align: left;
        `;
      case 'right':
        return css`
          text-align: right;
        `;
    }
  }};
  width: ${(props): string | undefined => props.themeWidth};

  ${({ themeHorizontallySticky, themeLeft }) =>
    stickHorizontally(themeHorizontallySticky, themeLeft)};

  ${({ themeShowDivider }) => showDivider(themeShowDivider)};
`;

const nestedRowStyle = css`
  > tr {
    margin: 0;
    padding: 0;
    background-color: ${({ theme }) => theme.colors.table.background};

    &:hover {
      background-color: ${({ theme }) => theme.colors.table.rowFocusBackground};
    }

    > td {
      overflow-wrap: break-word;

      font-size: ${({ theme }) => theme.fontSizes.table.cell};
      line-height: ${({ theme }) => theme.lineHeights.table.cell};
      font-weight: ${({ theme }) => theme.fontWeights.table.cell};
      color: ${({ theme }) => theme.colors.table.cellText};

      margin: 0;
      padding: ${({ theme }) => theme.space.table.cellPadding};
      border-bottom: ${({ theme }) => theme.borderWidths.table.cell} solid
        ${({ theme }) => theme.colors.table.cellBorder};
    }
  }
`;

const StyledTHead = styled.thead`
  margin: 0;
  padding: 0;
  background-color: ${({ theme }) => theme.colors.table.headerBackground};

  ${nestedRowStyle};
`;

const StyledTBody = styled.tbody`
  margin: 0;
  padding: 0;

  ${nestedRowStyle};
`;

const StyledTable = styled.table<{ themeFixedLayout: boolean }>`
  width: 100%;
  text-align: left;
  border-collapse: separate;
  border-spacing: 0;
  margin: 0;
  padding: 0;

  > ${StyledTHead} > tr > ${StyledTH}:first-child {
    border-top-left-radius: ${({ theme }) => theme.radii.table.header};
    border-bottom-left-radius: ${({ theme }) => theme.radii.table.header};
  }

  > ${StyledTHead} > tr > ${StyledTH}:last-child {
    border-top-right-radius: ${({ theme }) => theme.radii.table.header};
    border-bottom-right-radius: ${({ theme }) => theme.radii.table.header};
  }

  ${({ themeFixedLayout }) => {
    switch (themeFixedLayout) {
      case true:
        return css`
          table-layout: fixed;
        `;
      case false:
        return css``;
    }
  }};
`;

const StyledTableWrapper = styled.div<{
  themeSticky: boolean;
}>`
  background: ${({ theme }) => theme.colors.table.background};
  margin: 0;
  padding: 0;

  ${({ themeSticky }) => {
    switch (themeSticky) {
      case true:
        return css``;
      case false:
        return css`
          overflow-x: auto;
        `;
    }
  }};
`;

const StyledSortingArrows = styled.div`
  font-size: ${({ theme }) => theme.fontSizes.table.sortingIcon};
  line-height: ${({ theme }) => theme.lineHeights.table.sortingIcon};

  display: flex;

  flex-direction: column;
  margin: 0;
  padding: 0;
  margin-left: ${({ theme }) => theme.space.table.sortingIconMarginLeft};
`;

const StyledExpandableIcon = styled.div`
  display: flex;
  justify-content: center;
  align-items: center;
  box-sizing: border-box;
  margin: 0;
  padding: 0;

  border: ${({ theme }) => theme.borderWidths.table.expandableIcon} solid
    ${({ theme }) => theme.colors.table.expandableIconBorder};
  border-radius: ${({ theme }) => theme.radii.table.expandableIcon};

  width: ${({ theme }) => theme.sizes.table.expandableIcon};
  height: ${({ theme }) => theme.sizes.table.expandableIcon};

  font-size: ${({ theme }) => theme.fontSizes.table.expandableIcon};
`;

const StyledPaginationWrapper = styled.div`
  margin: 0;
  padding: 0;
  margin-top: ${({ theme }) => theme.space.table.paginationMarginTop};
  display: flex;
  justify-content: flex-end;
`;

const StyledItemsPerPageSelect = styled(Select)`
  input {
    width: ${({ theme }) => theme.sizes.table.itemsPerPageInputWidth};
  }
`;

const StyledFilterWrapper = styled.div`
  margin: 0 0 0 auto;
  padding: 0;
`;

const StyledFilterTargetWrapper = styled.div`
  display: flex;
  margin: 0;
  padding: 0;
`;

const StyledEmptyTableContent = styled.div`
  display: flex;
  justify-content: center;
  box-sizing: border-box;
  font-size: ${({ theme }) => theme.fontSizes.table.cell};
  margin: ${({ theme }) => theme.space.table.emptyContentMargin};
  padding: ${({ theme }) => theme.space.table.emptyContentPadding};
  color: ${({ theme }) => theme.colors.table.emptyText};
`;

export {
  StyledTH,
  StyledInnerTH,
  StyledTD,
  StyledTHead,
  StyledTBody,
  StyledSortingArrows,
  StyledExpandableIcon,
  StyledPaginationWrapper,
  StyledItemsPerPageSelect,
  StyledFilterWrapper,
  StyledFilterTargetWrapper,
  StyledTableWrapper,
  StyledEmptyTableContent,
  StyledTable as default,
};
