// @flow
import React from 'react';
import styled, { withTheme } from 'styled-components';
import { Grid, GridItem, Box, SectionHeader, Span } from '../../..';
import type {
  ColorPaletteColorNameKey,
  ColorPalette,
} from '../branding.proptypes';
import type { SpaceKey } from '../../spacing';

const SwatchSection = styled(Box)`
  flex: ${(props) => props.flex};
  height: ${(props) => props.height};
  border-radius: ${(props) =>
    props.borderRadius ? props.borderRadius : '10px'};
  border: ${(props) =>
    props.borderColor ? `2px solid ${props.borderColor}` : undefined};
`;

const UpperSpan = styled(Span)`
  padding-top: 10px;
  padding-bottom: 2px;
  font-size: 12px;
`;

const LowerSpan = styled(Span)`
  padding-bottom: ${(props) => props.paddingBottom};
`;

const ColorName = ({
  diffColor = false,
  name,
  code,
  label,
  paddingBottom,
}: {|
  diffColor?: boolean,
  name: ColorPaletteColorNameKey,
  code: string,
  label?: string,
  paddingBottom?: string,
|}) => {
  const colorName = diffColor ? 'greyscale-dark' : name;
  return (
    <>
      <UpperSpan bold colorName={colorName}>
        {code.toUpperCase()}
      </UpperSpan>
      <LowerSpan
        paddingBottom={paddingBottom}
        bold
        fontSize="f1"
        colorName={colorName}
      >
        {label == null ? name : label}
      </LowerSpan>
    </>
  );
};

const LowerBox = styled(Box)`
  margin-right: -10px;
  border-radius: 5px;
  border: 2px solid ${(props) => props.borderColor};
`;

const BigBox = styled(Box)`
  height: 425px;
`;

const AaBox = styled(Box)`
  flex: 1;
  padding-top: 95px;
`;

const AaSpan = styled(Span)`
  padding-top: ${(props) => props.paddingTop};
`;

const BasicGridItem = withTheme(({ theme }) => (
  <GridItem sm={4} xl={3}>
    <SectionHeader>Basics</SectionHeader>
    <SwatchSection
      height="500px"
      borderColor={theme.colorPalette['greyscale-light']}
      colorName="background"
    >
      <Box
        stacked="column"
        justify="end"
        align="end"
        spacing={['pt1', 'pr3', 'pb2']}
      >
        <ColorName
          diffColor
          code={theme.colorPalette['greyscale-dark']}
          name="background"
        />
      </Box>
      <BigBox stacked="row">
        <SwatchSection
          height="410px"
          flex={3}
          borderColor={theme.colorPalette['greyscale-light']}
          colorName="white"
          spacing={['ml1']}
        >
          <Box stacked="column" justify="end" align="end" spacing={['pr2']}>
            <ColorName
              paddingBottom="30px"
              diffColor
              code={theme.colorPalette.white}
              name="white"
            />
            <ColorName
              paddingBottom="10px"
              code={theme.colorPalette['greyscale-black']}
              name="greyscale-black"
            />
            <ColorName
              paddingBottom="10px"
              code={theme.colorPalette['greyscale-darker']}
              name="greyscale-darker"
            />
            <ColorName
              paddingBottom="10px"
              code={theme.colorPalette['greyscale-dark']}
              name="greyscale-dark"
            />
            <ColorName
              paddingBottom="30px"
              code={theme.colorPalette['greyscale-medium']}
              name="greyscale-medium"
            />
            <LowerBox
              spacing={['pr1', 'pb1', 'pl5']}
              borderColor={theme.colorPalette['greyscale-light']}
              stacked="column"
              justify="end"
              align="end"
            >
              <ColorName
                code={theme.colorPalette['greyscale-light']}
                name="greyscale-light"
              />
            </LowerBox>
          </Box>
        </SwatchSection>

        <AaBox stacked="column" align="center" hide={['sm', 'md']}>
          <Span colorName="greyscale-black" bold fontSize="f3">
            Aa
          </Span>
          <AaSpan
            colorName="greyscale-darker"
            paddingTop="35px"
            bold
            fontSize="f3"
          >
            Aa
          </AaSpan>
          <AaSpan
            colorName="greyscale-dark"
            paddingTop="35px"
            bold
            fontSize="f3"
          >
            Aa
          </AaSpan>
          <AaSpan
            colorName="greyscale-medium"
            paddingTop="35px"
            bold
            fontSize="f3"
          >
            Aa
          </AaSpan>
        </AaBox>
      </BigBox>
    </SwatchSection>
  </GridItem>
));

const SmallFontSpan = styled(Span)`
  font-size: 12px;
`;

const StyledSpan = ({
  colorName,
  code,
}: {|
  colorName: ColorPaletteColorNameKey,
  code: string,
|}) => (
  <SmallFontSpan bold colorName={colorName}>
    {code.toUpperCase()}
  </SmallFontSpan>
);

const BoxWithBorder = styled(Box)`
  border-radius: 5px;
  border: 1px solid ${(props) => props.borderColor};
`;

const SingleSwatch = ({
  colorPalette,
  mainColor,
  boxColor,
  label,
  spacing = [],
}: {|
  spacing?: Array<string>,
  colorPalette: ColorPalette,
  label?: string,
  mainColor: ColorPaletteColorNameKey,
  boxColor: ColorPaletteColorNameKey,
|}) => (
  <SwatchSection
    height="140px"
    borderRadius="10px"
    colorName={mainColor}
    stacked="column"
    justify="space-between"
    align="end"
    spacing={['pr1', 'pt1', 'pb1', ...spacing]}
  >
    {label == null ? (
      <StyledSpan code={colorPalette[mainColor]} colorName="white" />
    ) : (
      <>
        <StyledSpan code={colorPalette[mainColor]} colorName={boxColor} />
        <Span bold colorName={boxColor}>
          {label}
        </Span>
      </>
    )}
    <BoxWithBorder
      stacked="column"
      justify="space-between"
      align="end"
      spacing={['pl1', 'pr1', 'pb1', 'ml1']}
      borderColor={colorPalette[boxColor]}
    >
      <ColorName code={colorPalette[boxColor]} name={boxColor} label="Text" />
    </BoxWithBorder>
  </SwatchSection>
);

const SmallBox = styled(Box)`
  height: 40px;
`;

const DoubleSwatch = ({
  topColor,
  bottomColor,
  boxColor,
  colorPalette,
  spacing,
}: {|
  topColor: ColorPaletteColorNameKey,
  bottomColor: ColorPaletteColorNameKey,
  boxColor: ColorPaletteColorNameKey,
  colorPalette: ColorPalette,
  spacing?: SpaceKey | SpaceKey[],
|}) => (
  <SwatchSection
    spacing={spacing}
    height="180px"
    borderRadius="10px"
    colorName={topColor}
  >
    <SmallBox
      stacked="column"
      justify="start"
      align="end"
      spacing={['pr1', 'pt1']}
    >
      <StyledSpan code={colorPalette[topColor]} colorName="white" />
    </SmallBox>
    <SingleSwatch
      mainColor={bottomColor}
      boxColor={boxColor}
      colorPalette={colorPalette}
    />
  </SwatchSection>
);

const FlexWrapBox = styled(Box)`
  display: flex;
  flex-wrap: wrap;
`;

const WealthsimpleGridItem = withTheme(({ theme: { colorPalette } }) => (
  <GridItem sm={3}>
    <SectionHeader>Branding</SectionHeader>
    <FlexWrapBox>
      <DoubleSwatch
        spacing={['mr2', 'mb1']}
        colorPalette={colorPalette}
        topColor="brand-secondary-dark"
        bottomColor="brand-secondary-base"
        boxColor="white"
      />
      <DoubleSwatch
        colorPalette={colorPalette}
        topColor="brand-primary-dark"
        bottomColor="brand-primary-base"
        boxColor="white"
      />
    </FlexWrapBox>
    <FlexWrapBox>
      <SingleSwatch
        label="Secondary"
        mainColor="brand-secondary-bg"
        boxColor="brand-secondary-fg"
        colorPalette={colorPalette}
      />
      <SingleSwatch
        spacing={['ml1', 'mb1']}
        label="Primary"
        mainColor="brand-primary-bg"
        boxColor="brand-primary-fg"
        colorPalette={colorPalette}
      />
    </FlexWrapBox>
  </GridItem>
));

const BannerItem = withTheme(({ theme: { colorPalette } }) => (
  <>
    <SectionHeader>Banners/errors/warnings</SectionHeader>
    <FlexWrapBox>
      <SingleSwatch
        label="Success"
        mainColor="success-bg"
        boxColor="success-fg"
        colorPalette={colorPalette}
      />
      <SingleSwatch
        spacing={['ml1', 'mb1']}
        label="Info"
        mainColor="info-bg"
        boxColor="info-fg"
        colorPalette={colorPalette}
      />
      <SingleSwatch
        spacing={['ml1', 'mb1']}
        label="Error"
        mainColor="error-bg"
        boxColor="error-fg"
        colorPalette={colorPalette}
      />
    </FlexWrapBox>
  </>
));

const AuxiliaryItem = withTheme(({ theme: { colorPalette } }) => (
  <>
    <SectionHeader>Auxiliary Colors</SectionHeader>
    <FlexWrapBox>
      <SingleSwatch
        label="aux-1"
        mainColor="aux-1"
        boxColor="white"
        colorPalette={colorPalette}
      />
      <SingleSwatch
        spacing={['ml1', 'mb1']}
        label="aux-2"
        mainColor="aux-2"
        boxColor="white"
        colorPalette={colorPalette}
      />
      <SingleSwatch
        spacing={['ml1', 'mb1']}
        label="aux-3"
        mainColor="aux-3"
        boxColor="white"
        colorPalette={colorPalette}
      />
      <SingleSwatch
        spacing={['ml1', 'mb1']}
        label="aux-4"
        mainColor="aux-4"
        boxColor="white"
        colorPalette={colorPalette}
      />
    </FlexWrapBox>
  </>
));

const ColorGrid = styled(Grid)`
  margin-left: 0;
  margin-right: 0;
  padding-left: 10px;
`;

export const Palette = () => (
  <ColorGrid>
    <BasicGridItem />
    <WealthsimpleGridItem />
    <GridItem sm={5}>
      <BannerItem />
      <AuxiliaryItem />
    </GridItem>
  </ColorGrid>
);
