import React, { Fragment } from 'react';
import styled from 'styled-components';
import remcalc from 'remcalc';
import { Margin } from 'styled-components-spacing';
import Flex, { FlexItem } from 'styled-flex-component';
import { Field } from 'redux-form';

import {
  P as BaseP,
  H3 as BaseH3,
  Divider,
  TagList as BaseTagList,
  Input,
  Toggle as BaseToggle,
  Small,
  Button,
  FormGroup,
  FormLabel,
  PublicIcon,
  PrivateIcon,
  CopiableField,
  FormMeta,
  TagItem
} from 'joyent-ui-toolkit';

const TagList = styled(BaseTagList)`
  margin-bottom: ${remcalc(-6)};
`;

const SmallBordered = styled(Small)`
  padding-right: ${remcalc(12)};
  margin-right: ${remcalc(12)};
  border-right: ${remcalc(1)} solid ${props => props.theme.grey};
`;

const H3 = styled(BaseH3)`
  margin: 0;
`;

const P = styled(BaseP)`
  margin: 0;
`;

const Toggle = styled(BaseToggle)`
  margin: 0 6px;
`;

const ShortDivider = styled(Divider)`
  margin-left: 0;
  margin-right: 0;
`;

const Form = styled.form`
  margin-bottom: 0;
`;

export const Header = () => (
  <Margin bottom="5">
    <H3>CNS Default Hostnames</H3>
    <Margin top="2">
      <P>
        Default hostnames are automatically generated from both the instance
        name and any attached networks.
      </P>
    </Margin>
  </Margin>
);

export const Footer = ({ enabled, submitting, onToggle }) => (
  <Fragment>
    <Margin bottom="3">
      <FormGroup name="cns-enabled">
        <Flex alignCenter>
          <FormLabel disabled={submitting}>Disabled CNS</FormLabel>
          <Margin left="1">
            <Toggle checked={enabled} onChange={onToggle} disabled={submitting}>
              Enabled CNS
            </Toggle>
          </Margin>
        </Flex>
      </FormGroup>
    </Margin>
  </Fragment>
);

export const HostnamesHeader = () => (
  <Margin vertical="5">
    <H3>CNS Service hostnames</H3>
    <Margin top="2">
      <P>
        CNS service hostnames are created by attaching a CNS service name to one
        or more instances. You can serve multiple instances under the same
        hostname by assigning them to a matching CNS service name.
      </P>
    </Margin>
  </Margin>
);

export const AddServiceForm = ({
  handleSubmit,
  submitting,
  disabled,
  pristine,
  invalid
}) => (
  <Margin bottom="3">
    <Form onSubmit={handleSubmit}>
      <Flex wrap alignCenter={invalid} alignEnd={!invalid}>
        <FlexItem>
          <Flex collumn>
            <FormGroup name="name" field={Field}>
              <FormLabel>Attach to new CNS service name</FormLabel>
              <Margin top="0.5">
                <Input
                  onBlur={null}
                  type="text"
                  placeholder="Example: mySQLdb"
                  disabled={disabled || submitting}
                />
                <FormMeta />
              </Margin>
            </FormGroup>
          </Flex>
        </FlexItem>
        <FlexItem>
          <Margin left="2">
            <Button
              type="submit"
              disabled={submitting}
              loading={submitting}
              inline
            >
              Add
            </Button>
          </Margin>
        </FlexItem>
      </Flex>
    </Form>
  </Margin>
);

export const Hostname = ({
  copy,
  values = [],
  network,
  service,
  noMargin,
  ...hostname
}) => (
  <Fragment>
    <Margin bottom={noMargin ? '0' : '3'}>
      <Flex>
        <SmallBordered bold noMargin>
          {network && service
            ? 'Network CNS service'
            : network
              ? 'Network'
              : service ? 'CNS service' : 'Instance name'}{' '}
          hostname{values.length === 1 ? '' : 's'}
        </SmallBordered>
        <FlexItem>
          <Margin bottom="0.5" right="1">
            {hostname.public ? <PublicIcon /> : <PrivateIcon />}
          </Margin>
        </FlexItem>
        <FlexItem>
          <Small noMargin>{hostname.public ? 'Public' : 'Private'}</Small>
        </FlexItem>
      </Flex>
      {values.map((value, i) => (
        <Margin
          top="0.5"
          bottom={
            values.length !== 1 && values.length !== i + 1 ? '1' : undefined
          }
        >
          {copy ? (
            <CopiableField disabled md="12" text={value} />
          ) : (
            <Input onBlur={null} disabled monospace fluid value={value} />
          )}
        </Margin>
      ))}
    </Margin>
  </Fragment>
);

const DefaultHostnames = ({ hostnames, copy }) => (
  <Fragment>
    <Header />
    <Flex column>
      {hostnames.map(({ value, ...hostname }) => (
        <Hostname copy={copy} key={value} value={value} {...hostname} />
      ))}
    </Flex>
  </Fragment>
);

const CnsHostnames = ({
  hostnames = [],
  services = [],
  onRemoveService = () => null,
  children = null,
  copy = false
}) => (
  <Fragment>
    <HostnamesHeader />
    {children}
    {services.length ? (
      <Margin bottom="3">
        <FormLabel>Existing CNS service name(s)</FormLabel>
        <Margin top="1">
          <TagList>
            {services.map((value, index) => (
              <Margin right="1" bottom="1">
                <TagItem
                  active
                  fill="rgba(66, 134, 244, 0.1)"
                  key={value}
                  onRemoveClick={
                    onRemoveService && (() => onRemoveService(value))
                  }
                  id={`cns-tag-${index}`}
                >
                  {value}
                </TagItem>
              </Margin>
            ))}
          </TagList>
        </Margin>
      </Margin>
    ) : null}
    {hostnames.length &&
    hostnames.filter(({ values }) => values.length).length ? (
      <Margin top="5">
        <Flex column>
          {hostnames.map(({ value, ...hostname }, index) => (
            <Hostname
              copy={copy}
              key={value}
              value={value}
              noMargin={index === hostnames.length - 1}
              {...hostname}
            />
          ))}
        </Flex>
      </Margin>
    ) : null}
  </Fragment>
);

export default ({
  copy,
  hostnames = [],
  services = [],
  onRemoveService,
  children = null
}) => (
  <Fragment>
    <DefaultHostnames
      copy={copy}
      hostnames={hostnames.filter(({ service }) => !service)}
    />
    <Margin top="2">
      <ShortDivider height={remcalc(1)} />
    </Margin>
    <Margin top="5">
      <CnsHostnames
        copy={copy}
        services={services}
        hostnames={hostnames.filter(({ service }) => service)}
        onRemoveService={onRemoveService}
      >
        {children}
      </CnsHostnames>
    </Margin>
  </Fragment>
);
