/* eslint-disable sonarjs/cognitive-complexity */
import { PolicyTable, ReloadButton, Validation } from './Components';
import { columns } from './lib/config';
import { makeEltOsagoRequest } from './lib/make-request';
import type { Row, StoreSelector } from './types';
import { getEltOsago } from '@/api/elt/query';
import { MAX_INSURANCE, MIN_INSURANCE } from '@/constants/values';
import helper from '@/process/elt/lib/helper';
import { useStore } from '@/stores/hooks';
import { defaultRow } from '@/stores/tables/elt/default-values';
import { useApolloClient } from '@apollo/client';
import { observer } from 'mobx-react-lite';
import { omit, sift } from 'radash';
import { useCallback } from 'react';
import { Flex } from 'ui/grid';

const storeSelector: StoreSelector = ({ osago }) => osago;

const initialData = {
  ...omit(defaultRow, ['name', 'key', 'id']),
  error: null,
  premiumSum: 0,
};

export const Osago = observer(() => {
  const store = useStore();
  const { $tables } = store;
  const apolloClient = useApolloClient();
  const { init } = helper({ apolloClient, store });

  const handleOnClick = useCallback(async () => {
    $tables.elt.osago.abortController?.abort();
    $tables.elt.osago.abortController = new AbortController();

    const { osago } = await init();
    $tables.elt.osago.setRows(osago);
    const osagoCompanyIds = sift(
      $tables.insurance
        .row('osago')
        .getOptions('insuranceCompany')
        .map((x) => x.value)
    );
    osagoCompanyIds.forEach((key) => {
      const row = $tables.elt.osago.getRow(key);
      if (row) {
        row.status = 'fetching';
        $tables.elt.osago.setRow(row);
        makeEltOsagoRequest({ apolloClient, store }, row)
          .then((payload) =>
            getEltOsago(payload, { signal: $tables.elt.osago.abortController.signal })
          )
          .then((res) => {
            if (res) {
              const { numCalc, premiumSum = 0, message, skCalcId } = res;
              let { error } = res;
              if (premiumSum > MAX_INSURANCE) {
                error ||= `Сумма по страховке превышает максимально допустимое значение по стоимости ОСАГО: ${Intl.NumberFormat(
                  'ru',
                  {
                    currency: 'RUB',
                    style: 'currency',
                  }
                ).format(MAX_INSURANCE)}`;
              }
              if (premiumSum < MIN_INSURANCE) {
                error ||= `Сумма по страховке не должна быть меньше допустимого значения по стоимости ОСАГО: ${Intl.NumberFormat(
                  'ru',
                  {
                    currency: 'RUB',
                    style: 'currency',
                  }
                ).format(MIN_INSURANCE)}`;
              }
              $tables.elt.osago.setRow({
                key,
                message: error || message,
                numCalc,
                skCalcId,
                status: error ? 'error' : null,
                sum: premiumSum,
              });
            }
          })
          .catch((error) => {
            const _err = error as Error;
            $tables.elt.osago.setRow({
              ...initialData,
              key,
              message: _err.message || String(error),
              status: 'error',
            });
          });
      }
    });
  }, [$tables.elt.osago, $tables.insurance, apolloClient, init, store]);

  function handleOnSelectRow(row: Row) {
    $tables.insurance.row('osago').column('insuranceCompany').setValue(row.key);
    $tables.insurance.row('osago').column('insCost').setValue(row.sum);
  }

  type Column = (typeof columns)[number];
  const osagoColumns = columns.map((column: Column) => {
    if (column.key === 'name') {
      return {
        ...column,
        title: 'Страховая компания ОСАГО',
      };
    }
    if (column.key === 'status') {
      return {
        ...column,
        title: <ReloadButton storeSelector={storeSelector} onClick={() => handleOnClick()} />,
      };
    }
    if (column.key === 'totalFranchise') {
      return {
        ...column,
        render: () => 'Не требуется',
      };
    }

    return column;
  });

  return (
    <Flex flexDirection="column">
      <Validation storeSelector={storeSelector} />
      <PolicyTable
        storeSelector={storeSelector}
        columns={osagoColumns}
        onSelectRow={(row) => handleOnSelectRow(row)}
      />
    </Flex>
  );
});
