import React, { useEffect, useState } from 'react';
import { Controller, useForm } from 'react-hook-form';
import { ErrorMessage } from '@hookform/error-message';
import {
  AutoComplete,
  Box,
  FormStatusMessage,
  Grid,
  GridItem,
  Input,
  MainButton,
  makeToast,
  MultiSelect,
  NumberInput,
  SingleSelect,
  Text,
} from '@nova-hf/ui';
import { OptionsType } from '@nova-hf/ui/umd/ts/src/form-elements/react-select-components/ReactSelectWrapper';
import { CUSTOMER_DELEGATES } from 'beta/graphql/queries/customer';
import { emailValidate } from 'beta/utils/helpers';
import { useRouter } from 'next/router';
import {
  AddDelegateInput,
  RoleType,
  useAddDelegateMutation,
  useCustomersQuery,
  useDelegateLazyQuery,
} from 'typings/graphql';
import { useTranslation } from 'utils/i18n';

const COLOR = 'pink';
export const createOption = (label: string) => ({
  label,
  value: label.toLowerCase().replace(/\W/g, ''),
});
export const createMultiOptons = (
  options: OptionsType[] | RoleType[],
  values: (RoleType | null | undefined)[],
) => options.filter((c) => values.some((s) => s === c.value));

const titles: OptionsType[] = [
  { value: 'cto', label: 'Framkvæmdastjóri' },
  { value: 'cfo', label: 'Fjármálastjóri' },
  { value: 'tech', label: 'Tæknilegur tengiliður' },
  { value: 'staff', label: 'Almennur starfsmaður' },
  { value: 'office', label: 'Skrifstofustjóri' },
  { value: 'hr', label: 'Mannauðsstjóri' },
];

export const roles: OptionsType[] | RoleType[] = [
  { value: RoleType.BillContact, label: 'Fær reikninga' },
  { value: RoleType.PortalContact, label: 'Full réttindi' },
  { value: RoleType.TechnicalContact, label: 'Tæknilegur' },
  { value: RoleType.Unknown, label: 'Engin' },
];

type AddDelegateProps = {
  customerId: string;
};

export const AddDelegate = ({ customerId }: AddDelegateProps) => {
  const router = useRouter();
  const { t } = useTranslation('stillingar');
  const [isEditingDelegate, setIsEditingDelegate] = useState(false);
  const [customerName, setCustomerName] = useState('');
  const [nationalIds, setNationalIds] = useState<OptionsType[]>([]);
  const [addDelegateMutation, { loading: loadingAdd }] = useAddDelegateMutation({
    refetchQueries: [{ query: CUSTOMER_DELEGATES, variables: { input: { id: customerId } } }],
    awaitRefetchQueries: true,
  });

  const { control, setValue, handleSubmit, formState } = useForm<AddDelegateInput>({
    reValidateMode: 'onChange',
    defaultValues: {
      id: customerId,
      nationalId: '',
      roleEmail: '',
      rolePhoneNumber: '',
      roleTypes: [],
      roleTitle: '',
    },
  });

  const { data: customersData } = useCustomersQuery({
    variables: {
      input: {
        perPage: 20,
        page: 2,
      },
    },
  });

  const [delegateQuery] = useDelegateLazyQuery({
    onCompleted: (data) => {
      if (data.delegate?.id && data.delegate.__typename === 'Delegate') {
        setIsEditingDelegate(true);
        setValue('nationalId', data?.delegate?.customer?.nationalId ?? '');
        setValue('roleEmail', data?.delegate?.roleEmail ?? '');
        setValue('rolePhoneNumber', data?.delegate?.rolePhoneNumber ?? '');
        setValue('roleTitle', data?.delegate?.roleTitle ?? '');
        handleAddingRoleTypes(createMultiOptons(roles, data.delegate.roleTypes ?? []) ?? []);
        setCustomerName(data.delegate.customer.name ?? '');
      }
    },
  });

  useEffect(() => {
    if (router.query.delegateId) {
      delegateQuery({
        variables: {
          input: {
            id: (router.query.customerId as string) ?? '',
            delegateId: (router.query.delegateId as string) ?? '',
          },
        },
      });
    }
  }, [router.query]);

  useEffect(() => {
    if (customersData && !!customersData.customers.customers.length) {
      const nationalIdsOptions: OptionsType[] = customersData.customers.customers.map(
        (customer) => {
          return {
            value: customer.id,
            label: customer.nationalId ?? '',
            description: customer.name ?? '',
          };
        },
      );
      setNationalIds(nationalIdsOptions);
    }
  }, [customersData]);

  const handleNationalIdChange = (value: OptionsType) => {
    setValue('nationalId', value.label.replace(/-/g, ''));
    if (value.description) setCustomerName(value.description);
  };

  const handleAddingRoleTypes = (options: OptionsType[]) => {
    const selectedTypes: RoleType[] = options.map((option) => {
      const roleType: RoleType = RoleType[option.value];
      return roleType;
    });
    setValue('roleTypes', [...selectedTypes]);
  };

  const onSubmit = async (addDelegateForm: AddDelegateInput) => {
    try {
      const { data: addDelegateData } = await addDelegateMutation({
        variables: { input: { ...addDelegateForm } },
      });
      if (addDelegateData?.addDelegate.delegate?.id) {
        router.push({
          pathname: `/beta/${customerId}/stillingar`,
          query: { tab: 'tengilidir' },
        });
      }
      if (addDelegateData?.addDelegate?.error?.message) {
        makeToast.danger(
          t('contactsTab.addDelegateError'),
          addDelegateData.addDelegate.error.message,
        );
      }
    } catch (error) {
      if (error instanceof Error) {
        makeToast.danger(t('contactsTab.addDelegateError'), error.message);
      }
    }
  };

  return (
    <Box
      renderAs="form"
      paddingTop={8}
      display="flex"
      flexDirection="column"
      gap={15}
      onSubmit={handleSubmit(onSubmit)}
    >
      <Grid gridTemplate={{ sm: 4, md: 12 }} rowGap={12}>
        <GridItem gridColumn={{ sm: 'span4', md: 'span12' }}>
          <Text variant="h5" marginBottom={3}>
            {isEditingDelegate ? t('contactsTab.editDelegate') : t('contactsTab.addDelegate')}
          </Text>
          {!isEditingDelegate && (
            <Text marginBottom={4}>{t('contactsTab.addDelegateDescription')}</Text>
          )}
        </GridItem>
        <GridItem gridColumn={{ sm: 'span4', md: 'span6', lg: 'span6' }}>
          <Controller
            name="nationalId"
            control={control}
            rules={{
              required: true,
              minLength: {
                value: 10,
                message: t('contactsTab.nationalIdInvalid'),
              },
              maxLength: {
                value: 10,
                message: t('contactsTab.nationalIdInvalid'),
              },
            }}
            render={({ field, formState: { errors } }) => {
              return (
                <>
                  <AutoComplete
                    options={nationalIds}
                    required
                    label={t('contactsTab.delegateLabel')}
                    id="delegate-national-id"
                    placeholder={t('contactsTab.delegatePlaceholder')}
                    onChange={(option) => option && handleNationalIdChange(option)}
                    value={createOption(field.value)}
                    isClearable
                    isDisabled={loadingAdd || isEditingDelegate}
                    instanceId="delegate-national-id"
                  />
                  <ErrorMessage
                    errors={errors}
                    name="nationalId"
                    render={({ message }) => (
                      <FormStatusMessage
                        message={
                          errors.nationalId?.type === 'required'
                            ? t('contactsTab.nationalIdRequired')
                            : message
                        }
                        status="error"
                      />
                    )}
                  />
                </>
              );
            }}
          />
        </GridItem>
        <GridItem gridColumn={{ sm: 'span4', md: 'span6', lg: 'span6' }}>
          <Input label="Nafn" id="name" name="delegate-name" value={customerName} disabled />
        </GridItem>
        <GridItem gridColumn={{ sm: 'span4', md: 'span6', lg: 'span6' }}>
          <Controller
            name="roleTitle"
            control={control}
            rules={{
              required: true,
            }}
            render={({ field }) => {
              return (
                <SingleSelect
                  color={COLOR}
                  options={titles}
                  label={t('contactsTab.roleLabel')}
                  id="delegate-role"
                  required
                  instanceId="delegate-role"
                  placeholder={t('contactsTab.rolePlaceholder')}
                  isClearable={false}
                  onChange={(e) => setValue('roleTitle', e?.label)}
                  value={createOption(field.value ?? '')}
                  isDisabled={formState.isSubmitting || loadingAdd}
                />
              );
            }}
          />
        </GridItem>
        <GridItem gridColumn={{ sm: 'span4', md: 'span6', lg: 'span6' }}>
          <Controller
            name="roleTypes"
            control={control}
            rules={{
              required: true,
            }}
            render={({ field }) => {
              const rolesValues = createMultiOptons(roles, field.value ?? []);
              return (
                <MultiSelect
                  color={COLOR}
                  options={roles}
                  required
                  label={t('contactsTab.roleTypeLabel')}
                  id="delegate-role-types"
                  instanceId="delegate-role-types"
                  placeholder={t('contactsTab.roleTypePlaceholder')}
                  onChange={(e) => handleAddingRoleTypes(e as OptionsType[])}
                  isMulti
                  value={rolesValues}
                  isDisabled={formState.isSubmitting || loadingAdd}
                />
              );
            }}
          />
        </GridItem>
        <GridItem gridColumn={{ sm: 'span4', md: 'span6', lg: 'span6' }}>
          <Controller
            name="roleEmail"
            control={control}
            rules={{
              validate: {
                email: (value) => {
                  return !value || emailValidate(value ?? '');
                },
              },
            }}
            render={({ field, formState: { errors } }) => {
              const { value, ...rest } = field;
              return (
                <>
                  <Input
                    label={t('contactsTab.emailLabel')}
                    id="email"
                    autoComplete="off"
                    value={value ?? ''}
                    disabled={formState.isSubmitting || loadingAdd}
                    {...rest}
                  />
                  <ErrorMessage
                    errors={errors}
                    name="roleEmail"
                    render={({ message }) => (
                      <FormStatusMessage
                        message={
                          errors.roleEmail?.type === 'email'
                            ? t('contactsTab.emailInvalid')
                            : message
                        }
                        status="error"
                      />
                    )}
                  />
                </>
              );
            }}
          />
        </GridItem>
        <GridItem gridColumn={{ sm: 'span4', md: 'span6', lg: 'span6' }}>
          <Controller
            name="rolePhoneNumber"
            control={control}
            rules={{
              minLength: {
                value: 7,
                message: t('contactsTab.telInvalid'),
              },
              maxLength: {
                value: 7,
                message: t('contactsTab.telInvalid'),
              },
            }}
            render={({ field, formState: { errors } }) => {
              const { value, ...rest } = field;
              return (
                <>
                  <NumberInput
                    numberType="tel"
                    label={t('contactsTab.telLabel')}
                    id="tel"
                    autoComplete="off"
                    value={value ?? ''}
                    {...rest}
                  />
                  <ErrorMessage
                    errors={errors}
                    name="rolePhoneNumber"
                    render={({ message }) => <FormStatusMessage message={message} status="error" />}
                  />
                </>
              );
            }}
          />
        </GridItem>
        <GridItem gridColumn={{ sm: 'span4', md: '9/12', lg: '8/12' }}>
          <MainButton
            text={isEditingDelegate ? t('contactsTab.saveChanges') : t('contactsTab.addDelegate')}
            icon={isEditingDelegate ? 'checkMark' : 'add'}
            isLoading={loadingAdd}
            isDisabled={formState.isSubmitting || loadingAdd}
            dottedShadow="none"
            isSubmitButton
          />
        </GridItem>
      </Grid>
    </Box>
  );
};
