/* eslint-disable @typescript-eslint/naming-convention */
import type { ApolloClient } from '@apollo/client';
import { gql } from '@apollo/client';
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import type * as CRMTypes from 'gql/crm.types';
import { reaction } from 'mobx';
import type RootStore from 'stores/root';
import ValidationHelper from 'stores/validation/helper';
import { normalizeOptions } from 'tools/entity';
import { makeDisposable } from 'tools/mobx';
import type { AgentsFields, AgentsRewardConditionsFields, AgentsSumFields } from './types';

dayjs.extend(utc);

const QUERY_GET_REWARD_CONDITIONS = gql`
  query GetRewardConditions($agentid: Uuid!, $currentDate: DateTime) {
    evo_reward_conditions(
      evo_agent_accountid: $agentid
      evo_datefrom_param: { lte: $currentDate }
      evo_dateto_param: { gte: $currentDate }
      statecode: 0
      evo_agency_agreementid_param: { has: true }
    ) {
      label: evo_name
      value: evo_reward_conditionid
      evo_reward_summ
    }
  }
`;

export function fillAgentRewardReaction(
  store: RootStore,
  apolloClient: ApolloClient<object>,
  agentParams: {
    agentField: AgentsFields;
    rewardConditionField: AgentsRewardConditionsFields;
  }
) {
  const { $calculation, $process } = store;
  const { agentField, rewardConditionField } = agentParams;

  reaction(
    () => $calculation.element(agentField).getValue(),
    async (agentid) => {
      if (!agentid) {
        $calculation.element(rewardConditionField).reset();

        return;
      }
      const {
        data: { evo_reward_conditions },
      } = await apolloClient.query<
        CRMTypes.GetRewardConditionsQuery,
        CRMTypes.GetRewardConditionsQueryVariables
      >({
        query: QUERY_GET_REWARD_CONDITIONS,
        variables: {
          agentid,
          currentDate: dayjs().toISOString(),
        },
      });

      if (evo_reward_conditions?.length) {
        $calculation
          .element(rewardConditionField)
          .setOptions(normalizeOptions(evo_reward_conditions));
      }
    }
  );
}

const QUERY_GET_REWARD_SUMM = gql`
  query GetRewardSumm($conditionId: Uuid!) {
    evo_reward_condition(evo_reward_conditionid: $conditionId) {
      evo_reward_summ
    }
  }
`;

export function fillAgentRewardSummReaction(
  store: RootStore,
  apolloClient: ApolloClient<object>,
  agentParams: {
    rewardConditionField: AgentsRewardConditionsFields;
    rewardSummField: AgentsSumFields;
  }
) {
  const { $calculation, $process } = store;
  const { rewardConditionField, rewardSummField } = agentParams;

  makeDisposable(
    () =>
      reaction(
        () => $calculation.element(rewardConditionField).getValue(),
        async (rewardConditionId) => {
          if (!rewardConditionId) {
            $calculation.element(rewardSummField).reset();

            return;
          }

          const {
            data: { evo_reward_condition },
          } = await apolloClient.query<
            CRMTypes.GetRewardSummQuery,
            CRMTypes.GetRewardSummQueryVariables
          >({
            query: QUERY_GET_REWARD_SUMM,
            variables: {
              conditionId: rewardConditionId,
            },
          });

          if (evo_reward_condition?.evo_reward_summ) {
            $calculation.element(rewardSummField).setValue(evo_reward_condition.evo_reward_summ);
          } else {
            $calculation.element(rewardSummField).resetValue();
          }
        }
      ),
    () => $process.has('LoadKP')
  );

  reaction(
    () => $calculation.element(rewardConditionField).getValue(),
    (rewardConditionId) => {
      if (!rewardConditionId) {
        $calculation.element(rewardSummField).block();
      } else {
        $calculation.element(rewardSummField).unblock();
      }
    }
  );
}

const QUERY_GET_REWARD_CONDITION = gql`
  query GetRewardCondition($conditionId: Uuid!) {
    evo_reward_condition(evo_reward_conditionid: $conditionId) {
      evo_reward_summ
      evo_reduce_reward
      evo_min_reward_summ
      evo_agency_agreementidData {
        evo_required_reward
      }
    }
  }
`;

export function validateAgentRewardSumm(
  store: RootStore,
  apolloClient: ApolloClient<object>,
  agentParams: {
    rewardConditionField: AgentsRewardConditionsFields;
    rewardSummField: AgentsSumFields;
  }
) {
  const { $calculation } = store;
  const { rewardConditionField, rewardSummField } = agentParams;

  const validationHelper = new ValidationHelper();

  reaction(
    () => $calculation.element(rewardSummField).getValue(),
    async (rewardSumm) => {
      const conditionId = $calculation.element(rewardConditionField).getValue();
      if (!conditionId) {
        validationHelper.removeErrors();

        return;
      }

      const {
        data: { evo_reward_condition },
      } = await apolloClient.query<
        CRMTypes.GetRewardConditionQuery,
        CRMTypes.GetRewardConditionQueryVariables
      >({
        query: QUERY_GET_REWARD_CONDITION,
        variables: {
          conditionId,
        },
      });

      if (!evo_reward_condition) {
        validationHelper.removeErrors();

        return;
      }

      if (evo_reward_condition.evo_reward_summ) {
        $calculation
          .element(rewardSummField)
          .validate({
            invalid: rewardSumm > evo_reward_condition?.evo_reward_summ,
            message: 'Вознаграждение указано больше условия по агентскому договору!',
          })
          .err((removeError) => {
            validationHelper.add(removeError);
          });
      }

      if (
        evo_reward_condition?.evo_reduce_reward !== null &&
        evo_reward_condition.evo_reward_summ
      ) {
        $calculation
          .element(rewardSummField)
          .validate({
            invalid:
              evo_reward_condition.evo_reduce_reward === false &&
              rewardSumm < evo_reward_condition.evo_reward_summ,
            message: 'Вознаграждение указано меньше условия по агентскому договору!',
          })
          .err((removeError) => {
            validationHelper.add(removeError);
          });
      }

      if (evo_reward_condition?.evo_min_reward_summ !== null) {
        $calculation
          .element(rewardSummField)
          .validate({
            invalid: rewardSumm < evo_reward_condition?.evo_min_reward_summ,
            message: 'Вознаграждение указано меньше условия по агентскому договору!',
          })
          .err((removeError) => {
            validationHelper.add(removeError);
          });
      }

      $calculation
        .element(rewardSummField)
        .validate({
          invalid:
            evo_reward_condition?.evo_agency_agreementidData?.evo_required_reward === true &&
            rewardSumm === 0,
          message: 'Согласно агентскому договору обязательна выплата АВ. Заложите АВ в расчет',
        })
        .err((removeError) => {
          validationHelper.add(removeError);
        });
    }
  );
}
