// @ts-nocheck
import intl from 'react-intl-universal';
import { css } from '@emotion/css';
import { Formik, Form } from 'formik';
import { Intent } from '@blueprintjs/core';
import { sumBy, isEmpty, defaultTo } from 'lodash';
import { useHistory } from 'react-router-dom';

import {
  CreateEstimateFormSchema,
  EditEstimateFormSchema,
} from './EstimateForm.schema';

import EstimateFormHeader from './EstimateFormHeader';
import EstimateItemsEntriesField from './EstimateItemsEntriesField';
import EstimateFloatingActions from './EstimateFloatingActions';
import EstimateFormFooter from './EstimateFormFooter';
import EstimateFormDialogs from './EstimateFormDialogs';
import EstimtaeFormTopBar from './EstimtaeFormTopBar';
import {
  EstimateIncrementSyncSettingsToForm,
  EstimateSyncAutoExRateToForm,
} from './components';

import withSettings from '@/containers/Settings/withSettings';
import withCurrentOrganization from '@/containers/Organization/withCurrentOrganization';

import { AppToaster } from '@/components';
import { compose, transactionNumber, orderingLinesIndexes } from '@/utils';
import { useEstimateFormContext } from './EstimateFormProvider';
import {
  transformToEditForm,
  defaultEstimate,
  transfromsFormValuesToRequest,
  handleErrors,
  resetFormState,
} from './utils';
import { PageForm } from '@/components/PageForm';

/**6
 * Estimate form.
 */
function EstimateForm({
  // #withSettings
  estimateNextNumber,
  estimateNumberPrefix,
  estimateAutoIncrementMode,
  estimateCustomerNotes,
  estimateTermsConditions,

  // #withCurrentOrganization
  organization: { base_currency },
}) {
  const history = useHistory();
  const {
    estimate,
    isNewMode,
    submitPayload,
    createEstimateMutate,
    editEstimateMutate,
    saleEstimateState,
  } = useEstimateFormContext();

  const estimateNumber = transactionNumber(
    estimateNumberPrefix,
    estimateNextNumber,
  );
  // Initial values in create and edit mode.
  const initialValues = {
    ...(!isEmpty(estimate)
      ? { ...transformToEditForm(estimate) }
      : {
          ...defaultEstimate,
          // If the auto-increment mode is enabled, take the next estimate
          // number from the settings.
          ...(estimateAutoIncrementMode && {
            estimate_number: estimateNumber,
          }),
          entries: orderingLinesIndexes(defaultEstimate.entries),
          currency_code: base_currency,
          terms_conditions: defaultTo(estimateTermsConditions, ''),
          note: defaultTo(estimateCustomerNotes, ''),
          pdf_template_id: saleEstimateState?.defaultTemplateId,
        }),
  };

  // Handles form submit.
  const handleFormSubmit = (
    values,
    { setSubmitting, setErrors, resetForm },
  ) => {
    setSubmitting(true);

    const entries = values.entries.filter(
      (item) => item.item_id && item.quantity,
    );
    const totalQuantity = sumBy(entries, (entry) => parseInt(entry.quantity));

    // Validate the entries quantity should be bigger than zero.
    if (totalQuantity === 0) {
      AppToaster.show({
        message: intl.get('quantity_cannot_be_zero_or_empty'),
        intent: Intent.DANGER,
      });
      setSubmitting(false);
      return;
    }
    const form = {
      ...transfromsFormValuesToRequest(values),
      delivered: submitPayload.deliver,
    };
    // Handle the request success.
    const onSuccess = (response) => {
      AppToaster.show({
        message: intl.get(
          isNewMode
            ? 'the_estimate_has_been_created_successfully'
            : 'the_estimate_has_been_edited_successfully',
          { number: values.estimate_number },
        ),
        intent: Intent.SUCCESS,
      });
      setSubmitting(false);

      if (submitPayload.redirect) {
        history.push('/estimates');
      }
      if (submitPayload.resetForm) {
        resetFormState({ resetForm, initialValues, values });
      }
    };
    // Handle the request error.
    const onError = ({
      response: {
        data: { errors },
      },
    }) => {
      if (errors) {
        handleErrors(errors, { setErrors });
      }
      setSubmitting(false);
    };
    if (!isNewMode) {
      editEstimateMutate([estimate.id, form]).then(onSuccess).catch(onError);
    } else {
      createEstimateMutate(form).then(onSuccess).catch(onError);
    }
  };

  return (
    <Formik
      validationSchema={
        isNewMode ? CreateEstimateFormSchema : EditEstimateFormSchema
      }
      initialValues={initialValues}
      onSubmit={handleFormSubmit}
    >
      <Form
        className={css({
          overflow: 'hidden',
          display: 'flex',
          flexDirection: 'column',
          flex: 1
        })}
      >
        <PageForm flex={1}>
          <PageForm.Body>
            <EstimtaeFormTopBar />
            <EstimateFormHeader />
            <EstimateItemsEntriesField />
            <EstimateFormFooter />
          </PageForm.Body>

          <PageForm.Footer>
            <EstimateFloatingActions />
          </PageForm.Footer>
        </PageForm>

        {/*------- Dialogs -------*/}
        <EstimateFormDialogs />

        {/*------- Effects -------*/}
        <EstimateIncrementSyncSettingsToForm />
        <EstimateSyncAutoExRateToForm />
      </Form>
    </Formik>
  );
}

export default compose(
  withSettings(({ estimatesSettings }) => ({
    estimateNextNumber: estimatesSettings?.nextNumber,
    estimateNumberPrefix: estimatesSettings?.numberPrefix,
    estimateAutoIncrementMode: estimatesSettings?.autoIncrement,
    estimateCustomerNotes: estimatesSettings?.customerNotes,
    estimateTermsConditions: estimatesSettings?.termsConditions,
  })),
  withCurrentOrganization(),
)(EstimateForm);
