import { Errored } from 'dashboard/core/components/errored';
import { CustomModal } from 'dashboard/core/components/modal';
import { ModalContext } from 'dashboard/core/contexts/modals';
import { useLDAPGroups } from 'dashboard/core/utils/ldap';
import {
  serviceFullyFilled,
  updateService,
} from 'dashboard/core/utils/service';
import { DisplayError } from 'dashboard/definitions/errors';
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,
  FormGroup,
  FormGroupOrientation,
  Input,
  InputType,
  JustifyContent,
  Layout,
  LoadingSpinner,
  Position,
  StyledLayout,
} from 'twitch-core-ui';

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

interface Props {
  service: twirp.IService;
  onSaveSuccess: (service: twirp.IService) => void;
}

export const EditServiceModal = ({ service, onSaveSuccess }: Props) => {
  const { ldapGroups, loading, error } = useLDAPGroups();

  const modalContext = useContext(ModalContext);

  const [updatedService, setUpdatedService] = useState(service);
  const [errorText, setErrorText] = useState('');
  const [enableSave, setEnableSave] = useState(false);

  const handleFormEventChange = (
    e: React.FormEvent<
      HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement
    >,
  ) => {
    const updatedServiceCopy: twirp.IService = _.cloneDeep(updatedService);
    _.set(updatedServiceCopy, e.currentTarget.name, e.currentTarget.value);

    const updatedEnableSave =
      !_.isEqual(service, updatedServiceCopy) &&
      serviceFullyFilled(updatedServiceCopy);

    setUpdatedService(updatedServiceCopy);
    setEnableSave(updatedEnableSave);
  };

  const handleSave = () => {
    const onError = (e: Error) => {
      const customMsg = e && e.message ? ': ' + e.message : '';
      setErrorText(`${DisplayError.EDIT_SERVICE}${customMsg}`);
    };
    const onSuccess = (s: twirp.IService) => {
      onSaveSuccess(s);
      modalContext.hideModal();
    };
    updateService(updatedService, onSuccess, onError);
  };

  if (loading) {
    return (
      <StyledLayout
        display={Display.Flex}
        justifyContent={JustifyContent.Center}
      >
        <LoadingSpinner />
      </StyledLayout>
    );
  } else if (error) {
    return (
      <StyledLayout
        display={Display.Flex}
        justifyContent={JustifyContent.Center}
      >
        <Errored text="Could not load LDAP groups" />
      </StyledLayout>
    );
  }

  return (
    <Layout
      display={Display.Flex}
      flexDirection={FlexDirection.Column}
      position={Position.Relative}
    >
      <CustomModal
        title="Edit Service"
        isOpen={true}
        onClose={modalContext.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={handleFormEventChange}
              defaultValue={service.ldapGroup as string}
            />
          </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={handleFormEventChange}
              value={updatedService.serviceCatalogUrl as string}
              name={'serviceCatalogUrl'}
            />
          </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}
          >
            <Layout>
              <Button
                disabled={!enableSave}
                type={ButtonType.Success}
                size={ButtonSize.Large}
                onClick={handleSave}
              >
                Update Service
              </Button>
            </Layout>
          </Layout>
        </Layout>
      </CustomModal>
    </Layout>
  );
};
