import React, { useEffect } from 'react';
import { Controller, useForm } from 'react-hook-form';
import { ErrorMessage } from '@hookform/error-message';
import {
  Box,
  FormStatusMessage,
  Grid,
  GridItem,
  Input,
  MainButton,
  SingleSelect,
  Text,
  TextArea,
} from '@nova-hf/ui';
import { IContext } from 'beta/typings/context';
import Wrapper from 'components/app-layout/Wrapper';
import { Segment } from 'components/segment/Segment';
import { inject } from 'mobx-react';
import { useRouter } from 'next/router';
import { useSnackbar } from 'notistack';

import Authentication from '../../store/authentication';
import {
  TicketSource,
  TicketType,
  useCreateTicketMutation,
  useCustomerNameByNationalIdQuery,
  ZendeskGroup,
} from '../../typings/graphql';
import { useTranslation } from '../../utils/i18n';

type SkraMalProps = {
  authentication: Authentication;
};

type TicketInput = {
  customerName: string;
  phoneNumber: string;
  email: string;
  subject: string;
  body: string;
  salesNumber: string;
  nationalId: string;
  group: ZendeskGroup;
};

const COLOR = 'pink';

export const SkraMal = ({ authentication }: SkraMalProps) => {
  const { t } = useTranslation('service');
  const { enqueueSnackbar } = useSnackbar();
  const router = useRouter();
  const { data: customerData } = useCustomerNameByNationalIdQuery({
    variables: { input: { nationalId: router?.query?.kt?.toString() ?? '' } },
    skip: !router?.query?.kt && !authentication.isStaff,
  });

  const {
    control,
    handleSubmit,
    formState: { isValid },
    watch,
    setValue,
  } = useForm<TicketInput>({
    defaultValues: {
      customerName: '',
      email: '',
      phoneNumber: '',
      subject: '',
      body: '',
      salesNumber: '',
      nationalId: '',
      group: ZendeskGroup.SalesAndService,
    },
    delayError: 500,
    mode: 'onChange',
  });

  const { customerName, email, phoneNumber, subject, body, salesNumber, nationalId, group } =
    watch();

  const [createTicket, { loading: consolationLoading, error: consolationError }] =
    useCreateTicketMutation({
      onCompleted(data) {
        if (data?.createTicket?.ticket?.id) {
          window.location.href = `https://novadesk.zendesk.com/agent/tickets/${data?.createTicket?.ticket?.id}`;
        }
      },
      onError(error) {
        if (error) {
          enqueueSnackbar(t('zendesk.error'), {
            variant: 'error',
          });
        }
      },
    });

  const onSubmit = () => {
    if (customerName && (email || phoneNumber)) {
      createTicket({
        variables: {
          input: {
            contact: {
              phoneNumber: phoneNumber,
              email: email,
              name: customerName,
            },
            source: TicketSource.NovaPortal,
            group: group,
            ticketType: TicketType.General,
            subject: subject,
            body: body,
            salesNumber: salesNumber,
            nationalId: nationalId,
          },
        },
      });
    }
  };

  useEffect(() => {
    if (!router.isReady) return;
    const { name, email, phoneNumber } = router.query;
    setValue(
      'customerName',
      customerData?.customerByNationalId?.name
        ? customerData?.customerByNationalId?.name
        : String(name ?? ''),
    );
    setValue(
      'email',
      customerData?.customerByNationalId?.email
        ? customerData?.customerByNationalId?.email
        : String(email ?? ''),
    );
    setValue(
      'phoneNumber',
      customerData?.customerByNationalId?.primaryPhoneNumber
        ? customerData?.customerByNationalId?.primaryPhoneNumber
        : String(phoneNumber ?? ''),
    );
    setValue(
      'nationalId',
      customerData?.customerByNationalId?.nationalId
        ? customerData?.customerByNationalId?.nationalId
        : String(nationalId ?? ''),
    );
  }, [router.isReady, router.query, customerData]);

  const groups = [
    { value: ZendeskGroup.SalesAndService, label: t('zendesk.groups.salesAndService') },
    { value: ZendeskGroup.PaymentIssues, label: t('zendesk.groups.paymentIssues') },
    { value: ZendeskGroup.RepairIssues, label: t('zendesk.groups.repairIssues') },
    { value: ZendeskGroup.TecnhicalIssues, label: t('zendesk.groups.technicalIssues') },
  ];

  if (!authentication.isStaff) return null;

  return (
    <Wrapper header="dark">
      <Segment>
        <Box display="flex" flexDirection="column" gap={5}>
          <Text variant="h4">{t('zendesk.new')}</Text>
          <Text>{t('zendesk.description')}</Text>
          <Box renderAs="form" onSubmit={handleSubmit(onSubmit)}>
            <Grid gridTemplate={{ sm: 4 }}>
              <GridItem gridColumn={{ sm: 'span4', md: 'span2' }}>
                <Controller
                  name="customerName"
                  control={control}
                  rules={{
                    required: t('zendesk.customerNameError'),
                  }}
                  render={({ field, formState: { errors } }) => {
                    const { name, value, onChange } = field;
                    return (
                      <Box>
                        <Input
                          id="name"
                          label={t('zendesk.name')}
                          isBold={false}
                          required
                          value={value ?? ''}
                          onChange={onChange}
                          name={name}
                        />
                        <ErrorMessage
                          errors={errors}
                          name={name}
                          render={({ message }) => (
                            <FormStatusMessage message={message} status="error" />
                          )}
                        />
                      </Box>
                    );
                  }}
                />
              </GridItem>
              <GridItem gridColumn={{ sm: 'span4', md: 'span2' }}>
                <Controller
                  name="phoneNumber"
                  control={control}
                  render={({ field, formState: { errors } }) => {
                    const { name, value, onChange } = field;
                    return (
                      <Box>
                        <Input
                          id="phoneNumber"
                          label={t('zendesk.phoneNumber')}
                          isBold={false}
                          value={value ?? ''}
                          onChange={onChange}
                          name={name}
                        />
                        <ErrorMessage
                          errors={errors}
                          name={name}
                          render={({ message }) => (
                            <FormStatusMessage message={message} status="error" />
                          )}
                        />
                      </Box>
                    );
                  }}
                />
              </GridItem>
              <GridItem gridColumn={{ sm: 'span4', md: 'span2' }}>
                <Controller
                  name="nationalId"
                  control={control}
                  render={({ field, formState: { errors } }) => {
                    const { name, value, onChange } = field;
                    return (
                      <Box>
                        <Input
                          id="nationalId"
                          label={t('zendesk.nationalId')}
                          isBold={false}
                          value={value ?? ''}
                          onChange={onChange}
                          name={name}
                        />
                        <ErrorMessage
                          errors={errors}
                          name={name}
                          render={({ message }) => (
                            <FormStatusMessage message={message} status="error" />
                          )}
                        />
                      </Box>
                    );
                  }}
                />
              </GridItem>
              <GridItem gridColumn={{ sm: 'span4', md: 'span2' }}>
                <Controller
                  name="email"
                  control={control}
                  render={({ field, formState: { errors } }) => {
                    const { name, value, onChange } = field;
                    return (
                      <Box>
                        <Input
                          id="email"
                          label={t('zendesk.email')}
                          isBold={false}
                          value={value ?? ''}
                          onChange={onChange}
                          name={name}
                        />
                        <ErrorMessage
                          errors={errors}
                          name={name}
                          render={({ message }) => (
                            <FormStatusMessage message={message} status="error" />
                          )}
                        />
                      </Box>
                    );
                  }}
                />
              </GridItem>
              <GridItem gridColumn={{ sm: 'span4', md: 'span2' }}>
                <Controller
                  name="group"
                  control={control}
                  render={({ field, formState: { errors } }) => {
                    const { name } = field;
                    return (
                      <Box>
                        <SingleSelect
                          color="pink"
                          defaultMenuIsOpen={false}
                          id="group"
                          label={t('zendesk.groups.label')}
                          maxMenuHeight={250}
                          placeholder={t('zendesk.groups.salesAndService')}
                          onChange={(e) => {
                            setValue(
                              'group',
                              e?.value ? (e?.value as ZendeskGroup) : ZendeskGroup.SalesAndService,
                            );
                          }}
                          isClearable={false}
                          options={groups.map((group) => ({
                            label: group.label,
                            value: group.value,
                          }))}
                          required
                          isDisabled={consolationLoading}
                        />
                        <ErrorMessage
                          errors={errors}
                          name={name}
                          render={({ message }) => (
                            <FormStatusMessage message={message} status="error" />
                          )}
                        />
                      </Box>
                    );
                  }}
                />
              </GridItem>
              <GridItem gridColumn={{ sm: 'span4', md: 'span2' }}>
                <Controller
                  name="subject"
                  control={control}
                  rules={{
                    required: t('zendesk.titleError'),
                  }}
                  render={({ field, formState: { errors } }) => {
                    const { name, value, onChange } = field;
                    return (
                      <Box>
                        <Input
                          id="subject"
                          label={t('zendesk.title')}
                          isBold={false}
                          required
                          value={value ?? ''}
                          onChange={onChange}
                          name={name}
                        />
                        <ErrorMessage
                          errors={errors}
                          name={name}
                          render={({ message }) => (
                            <FormStatusMessage message={message} status="error" />
                          )}
                        />
                      </Box>
                    );
                  }}
                />
              </GridItem>
              <GridItem gridColumn={{ sm: 'span4' }}>
                <Controller
                  name="body"
                  control={control}
                  rules={{
                    required: t('zendesk.descriptionError'),
                  }}
                  render={({ field, formState: { errors } }) => {
                    const { name, value, onChange } = field;
                    return (
                      <Box>
                        <TextArea
                          id="body"
                          label={t('zendesk.descriptionForm')}
                          isBold={false}
                          required
                          value={value ?? ''}
                          onChange={onChange}
                          name={name}
                        />
                        <ErrorMessage
                          errors={errors}
                          name={name}
                          render={({ message }) => (
                            <FormStatusMessage message={message} status="error" />
                          )}
                        />
                      </Box>
                    );
                  }}
                />
              </GridItem>
              <GridItem gridColumn={{ sm: 'span4', md: 'span2' }}>
                <Controller
                  name="salesNumber"
                  control={control}
                  rules={{
                    required: t('zendesk.salesNumberError'),
                  }}
                  render={({ field, formState: { errors } }) => {
                    const { name, value, onChange } = field;
                    return (
                      <Box>
                        <Input
                          id="salesNumber"
                          label={t('zendesk.salesNumber')}
                          isBold={false}
                          required
                          value={value ?? ''}
                          onChange={onChange}
                          name={name}
                        />
                        <ErrorMessage
                          errors={errors}
                          name={name}
                          render={({ message }) => (
                            <FormStatusMessage message={message} status="error" />
                          )}
                        />
                      </Box>
                    );
                  }}
                />
              </GridItem>
              {consolationError && (
                <GridItem gridColumn={{ sm: 'span4' }}>
                  <FormStatusMessage message={t('zendesk.formError')} status="error" />
                </GridItem>
              )}
              <GridItem gridColumn={{ sm: 'span4' }}>
                <Box
                  display="flex"
                  marginTop={6}
                  marginBottom={10}
                  justifyContent="flex-end"
                  flexDirection={{ sm: 'column', md: 'row' }}
                >
                  <Box display="flex" width={{ sm: '100%', md: '4/12' }}>
                    <MainButton
                      text={t('zendesk.confirm')}
                      colorScheme={COLOR}
                      isSubmitButton
                      isLoading={consolationLoading}
                      isDisabled={!isValid}
                    />
                  </Box>
                </Box>
              </GridItem>
            </Grid>
          </Box>
        </Box>
      </Segment>
    </Wrapper>
  );
};

SkraMal.getInitialProps = ({ pathname }: IContext) => {
  return {
    pathname,
    namespacesRequired: ['service'],
  };
};

export default inject('authentication')(SkraMal);
