/* eslint-disable sonarjs/cognitive-complexity */
import { PolicyTable, ReloadButton, Validation } from './Components';
import { columns } from './lib/config';
import { makeEltKaskoRequest } from './lib/make-request';
import type { Row, StoreSelector } from './types';
import { getEltKasko } from '@/api/elt/query';
import { STALE_TIME } from '@/constants/request';
import { MAX_FRANCHISE, MAX_INSURANCE, MIN_INSURANCE } from '@/constants/values';
import helper from '@/process/elt/lib/helper';
import { useStore } from '@/stores/hooks';
import { useApolloClient } from '@apollo/client';
import type { QueryFunctionContext } from '@tanstack/react-query';
import { useQueries } from '@tanstack/react-query';
import { observer } from 'mobx-react-lite';
import { Flex } from 'ui/grid';

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

export const Kasko = observer(() => {
  const store = useStore();
  const { $tables, $calculation } = store;

  const apolloClient = useApolloClient();

  const { init } = helper({ apolloClient, store });

  const queries = useQueries({
    queries: $tables.elt.kasko.getRows.map((row) => {
      const { id, key } = row;

      return {
        cacheTime: 0,
        enabled: false,
        initialData: {
          ...row,
          error: '',
          kaskoSum: 0,
          paymentPeriods: [
            {
              kaskoSum: 0,
            },
          ],
          sum: 0,
        },
        queryFn: async (context: QueryFunctionContext) => {
          const payload = await makeEltKaskoRequest({ apolloClient, store }, row);
          const res = await getEltKasko(payload, context);
          const companyRes = res[id];

          return { ...companyRes, id, key };
        },
        queryKey: ['elt', 'kasko', id],
        refetchOnWindowFocus: false,
        staleTime: STALE_TIME,
      };
    }),
  });

  async function handleOnClick() {
    const { kasko } = await init();
    $tables.elt.kasko.setRows(kasko);

    const kaskoCompanyIds = $tables.insurance
      .row('kasko')
      .getOptions('insuranceCompany')
      .map((x) => x.value);
    const values = $calculation.$values.getValues();

    queries
      .filter(({ data }) => data?.key && kaskoCompanyIds.includes(data.key))
      .forEach(({ refetch, data }) => {
        if (data?.key) $tables.elt.kasko.setRow({ key: data?.key, status: 'fetching' });

        refetch()
          .then((res) => {
            if (res.data) {
              const {
                key,
                kaskoSum = 0,
                message,
                skCalcId,
                totalFranchise = 0,
                requestId,
                paymentPeriods,
              } = res.data;
              let { error } = res.data;

              if (totalFranchise > MAX_FRANCHISE) {
                error ||= `Франшиза по страховке превышает максимально допустимое значение: ${Intl.NumberFormat(
                  'ru',
                  {
                    currency: 'RUB',
                    style: 'currency',
                  }
                ).format(MAX_FRANCHISE)}`;
              }

              if (kaskoSum > MAX_INSURANCE) {
                error ||= `Сумма по страховке превышает максимально допустимое значение по стоимости КАСКО: ${Intl.NumberFormat(
                  'ru',
                  {
                    currency: 'RUB',
                    style: 'currency',
                  }
                ).format(MAX_INSURANCE)}`;
              }

              if (kaskoSum < MIN_INSURANCE) {
                error ||= `Сумма по страховке не должна быть меньше допустимого значения по стоимости КАСКО: ${Intl.NumberFormat(
                  'ru',
                  {
                    currency: 'RUB',
                    style: 'currency',
                  }
                ).format(MIN_INSURANCE)}`;
              }

              $tables.elt.kasko.setRow({
                key,
                message: error || message,
                numCalc: 0,
                requestId,
                skCalcId,
                status: error ? 'error' : null,
                sum: values.leasingPeriod <= 16 ? kaskoSum : paymentPeriods?.at(0)?.kaskoSum || 0,
                totalFranchise,
              });
            }
          })
          .catch((error) => {
            if (data?.key)
              $tables.elt.kasko.setRow({
                key: data?.key,
                message: error,
                numCalc: 0,
                requestId: '',
                skCalcId: '',
                status: 'error',
                sum: 0,
                totalFranchise: 0,
              });
          });
      });
  }

  function handleOnSelectRow(row: Row) {
    $tables.insurance.row('kasko').column('insuranceCompany').setValue(row.key);
    $tables.insurance.row('kasko').column('insCost').setValue(row.sum);
    $calculation.element('tbxInsFranchise').setValue(row.totalFranchise);
  }

  type Column = (typeof columns)[number];
  const kaskoColumns = columns.map((column: Column) => {
    if (column.key === 'name') {
      return {
        ...column,
        title: 'Страховая компания КАСКО',
      };
    }

    if (column.key === 'status') {
      return {
        ...column,
        title: <ReloadButton storeSelector={storeSelector} onClick={() => handleOnClick()} />,
      };
    }

    return column;
  });

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