import { CustomModal } from 'dashboard/core/components/modal';
import { ModalContext } from 'dashboard/core/contexts/modals';
import {
  createService,
  isInvalidServiceCatalogURL,
  serviceCatalogID,
} from 'dashboard/core/utils/service';
import { code } from 'dashboard/generated/controlplane';
import { LDAPGroupSelect } from 'dashboard/pages/services/components/ldap-group-select';
import * as _ from 'lodash';
import * as React from 'react';
import { useContext, useState } from 'react';
import {
  Button,
  ButtonSize,
  ButtonType,
  Color,
  CoreText,
  Display,
  FlexDirection,
  FontSize,
  FormGroup,
  FormGroupOrientation,
  Input,
  InputType,
  JustifyContent,
  Layout,
  Position,
} from 'twitch-core-ui';

import twirp = code.justin.tv.eventbus.controlplane;

const SERVICE_CATALOG_LINK = 'serviceCatalogUrl';

interface Props {
  ldapGroups: string[];
  existingServiceCatalogIDs: string[];
  onCreateSuccess: (service: twirp.IService) => void;
}
export const CreateServiceModal = ({
  ldapGroups,
  existingServiceCatalogIDs,
  onCreateSuccess,
}: Props) => {
  const [ldapGroup, setLDAPGroup] = useState<string>(
    ldapGroups.length === 0 ? '' : ldapGroups[0],
  );
  const [serviceCatalogURL, setServiceCatalogURL] = useState('');
  const [
    serviceCatalogURLValidationError,
    setServiceCatalogURLValidationError,
  ] = useState<string | null>(null);
  const [errorText, setErrorText] = useState('');
  const { hideModal } = useContext(ModalContext);

  const handleSubmit = () => {
    createService(
      {
        ldapGroup,
        serviceCatalogUrl: serviceCatalogURL,
      },
      (service) => {
        hideModal();
        onCreateSuccess(service);
      },
      (err) => setErrorText(err.message),
    );
  };

  const handleServiceCatalogURLChange = (
    e: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
  ) => {
    const url = e.currentTarget.value;
    let validationError: string | null = null;

    if (url === '') {
      setServiceCatalogURLValidationError(null);
      return;
    } else if (isInvalidServiceCatalogURL(url)) {
      validationError = 'Invalid service catalog URL';
    } else if (_.includes(existingServiceCatalogIDs, serviceCatalogID(url))) {
      validationError = 'Service already registered with the EventBus';
    }

    setServiceCatalogURL(url);
    setServiceCatalogURLValidationError(validationError);
  };

  const handleLDAPGroupChange = (
    e: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
  ) => {
    setLDAPGroup(e.currentTarget.value);
  };

  const createServiceButtonEnabled =
    serviceCatalogURLValidationError === null &&
    ldapGroup !== '' &&
    serviceCatalogURL !== '';

  return (
    <Layout
      display={Display.Flex}
      flexDirection={FlexDirection.Column}
      position={Position.Relative}
    >
      <CustomModal title="Add Your Service" isOpen={true} onClose={hideModal}>
        <Layout margin={{ y: 1 }}>
          <FormGroup
            required
            label="LDAP Group"
            id="ldap-group"
            hint="The owner of this service"
            orientation={FormGroupOrientation.Horizontal}
          >
            <LDAPGroupSelect
              ldapGroups={ldapGroups}
              onChange={handleLDAPGroupChange}
            />
          </FormGroup>
        </Layout>
        <Layout margin={{ y: 1 }}>
          <FormGroup
            required
            label="Service Catalog URL"
            id="service-catalog-link"
            hint="The service's entry, e.g. https://catalog.xarth.tv/services/126/details"
            orientation={FormGroupOrientation.Horizontal}
          >
            <Input
              type={InputType.Text}
              onChange={handleServiceCatalogURLChange}
              name={SERVICE_CATALOG_LINK}
              error={serviceCatalogURLValidationError !== null}
            />
            {serviceCatalogURLValidationError && (
              <CoreText italic color={Color.Error} fontSize={FontSize.Size8}>
                {serviceCatalogURLValidationError}
              </CoreText>
            )}
          </FormGroup>
        </Layout>
        <Layout display={Display.Flex} justifyContent={JustifyContent.Between}>
          <Layout>
            {errorText && <CoreText color={Color.Error}>{errorText}</CoreText>}
          </Layout>
          <Layout
            display={Display.Flex}
            justifyContent={JustifyContent.Between}
            className="tw-font-size-6"
          >
            <Layout>
              <Button
                disabled={!createServiceButtonEnabled}
                type={ButtonType.Success}
                size={ButtonSize.Large}
                onClick={handleSubmit}
              >
                Register Service
              </Button>
            </Layout>
          </Layout>
        </Layout>
      </CustomModal>
    </Layout>
  );
};
