import { ofType } from 'redux-observable';
import { concat, of } from 'rxjs';
import { switchMap } from 'rxjs/operators';

import {
  AUTOMATIC_OPTIMIZATION,
  DEMAND_TAG_FORMAT,
  DEMAND_TAG_HB_GAM_PLATFORMS,
  DEMAND_TAG_PAGE,
  DEMAND_TAG_PAGE_BUSINESS_MODEL,
  DEMAND_TAG_PAGE_SOURCE,
  DEMAND_TAG_PAGE_TYPE_VALUES,
  DEMAND_TAG_SUPPLY_CHAIN_OVERRIDE,
  DEMAND_TAG_SUPPLY_CHAIN_VALUE,
  DEMAND_TAG_TARGETING_VIEWABILITY_TYPE,
  DEMAND_TAG_VIEWABILITY_TARGETING,
  FLOOR_PRICE,
  SOURCE_TAG_OPTIONS,
  SUPPLY_TAG_PAGE,
} from '../../constants';
import { PCN_GET_MARKETPLACE_DASHBOARD } from '@/modules/@common/acl/constants';

import * as selectors from '../selectors';
import {
  setActiveTabIndexAction,
  setAutomaticOptimizationTabAction,
  setPricingTabAction,
  setSettingsTabAction,
  setSupplyTabAction,
  setTargetingTabAction,
  validateTagAction,
} from '../slices';
import { hasPermission } from '@/modules/@common/user/helpers';
import { getUserPermissionsSelector } from '@/modules/@common/user/redux/selectors';

export default (action$, state$) =>
  action$.pipe(
    ofType(validateTagAction.type),
    switchMap((action) => {
      const state = state$.value;
      const userPermissions = getUserPermissionsSelector(state);
      const isAdminMP = hasPermission(PCN_GET_MARKETPLACE_DASHBOARD, userPermissions);

      const pageConfig = selectors.pageConfigSelector(state);
      const supply = selectors.supplySelector(state);
      const automaticOptimization = selectors.automaticOptimizationSelector(state);
      const settings = selectors.settingsSelector(state);
      const pricing = selectors.pricingSelector(state);
      const targeting = selectors.targetingSelector(state);

      const { type } = pageConfig;
      const {
        name: supplyName,
        source: supplyTagSource,
        format: supplyTagFormat,
        platformId: supplyPlatformId,
        floorPrice: { floor: supplyFloor, viewableFloor: supplyViewableFloor, firstRequestFloor },
        automaticFloorPrice,
        fillRateThreshold,
        minimumFloor,
        maximumFloor,
      } = supply;

      const { status: optimizationStatus, kpiGap } = automaticOptimization;

      const {
        name: demandName,
        source: demandTagSource,
        platformId: demandPlatformId,
        type: tagType,
        url: adServerUrl,
        platform,
        platforms,
        supplyChainOverride,
        supplyChainValue,
        supplyChainNode,
        bidMappingFileName,
        bidMappingFileData,
        flightsDates,
        floorPrice: { override: demandFloorOverride, floor: demandFloor, viewableFloor: demandViewableFloor },
        maxFloor,
        videoId,
      } = settings;

      const { model, source, seatId, adUnitId, type: pricingType } = pricing;

      const { viewability, viewabilityTargeting, viewabilityThreshold } = targeting;

      if (type === SUPPLY_TAG_PAGE) {
        if (supplyName?.length > 250) {
          return concat(
            of(
              setSupplyTabAction({
                errors: {
                  name: 'The Name field can’t exceed 250 characters',
                },
              }),
            ),
          );
        }

        if (isAdminMP) {
          if (supplyTagSource !== SOURCE_TAG_OPTIONS[0].value && !supplyPlatformId?.length) {
            return concat(
              of(
                setSupplyTabAction({
                  errors: {
                    platformId: 'Field cannot be empty',
                  },
                }),
              ),
            );
          }

          if (supplyTagFormat !== DEMAND_TAG_FORMAT.sponsored) {
            if (!supplyViewableFloor?.toString()?.length) {
              return concat(
                of(
                  setSupplyTabAction({
                    errors: {
                      viewableFloor: 'Required',
                    },
                  }),
                ),
              );
            }

            if (supplyTagFormat !== DEMAND_TAG_FORMAT.sponsored && !supplyFloor?.toString()?.length) {
              return concat(
                of(
                  setSupplyTabAction({
                    errors: {
                      floor: 'Required',
                    },
                  }),
                ),
              );
            }

            if (!firstRequestFloor?.toString()?.length) {
              return concat(
                of(
                  setSupplyTabAction({
                    errors: {
                      firstRequestFloor: 'Field cannot be empty',
                    },
                  }),
                ),
              );
            }
          }

          if (automaticFloorPrice) {
            if (!fillRateThreshold?.toString()?.length) {
              return concat(
                of(
                  setSupplyTabAction({
                    errors: {
                      fillRateThreshold: 'Field cannot be empty',
                    },
                  }),
                ),
              );
            }

            if (!(+fillRateThreshold >= 0 && +fillRateThreshold <= 1)) {
              return concat(
                of(
                  setSupplyTabAction({
                    errors: {
                      fillRateThreshold: 'Fill Rate Threshold must be 0-100',
                    },
                  }),
                ),
              );
            }

            if (!minimumFloor?.toString()?.length) {
              return concat(
                of(
                  setSupplyTabAction({
                    errors: {
                      minimumFloor: 'Field cannot be empty',
                    },
                  }),
                ),
              );
            }

            if (+minimumFloor < 0) {
              return concat(
                of(
                  setSupplyTabAction({
                    errors: {
                      minimumFloor: 'Minimum Floor must be >= 0',
                    },
                  }),
                ),
              );
            }

            if (!maximumFloor?.toString()?.length) {
              return concat(
                of(
                  setSupplyTabAction({
                    errors: {
                      maximumFloor: 'Field cannot be empty',
                    },
                  }),
                ),
              );
            }

            if (+maximumFloor < +minimumFloor) {
              return concat(
                of(
                  setSupplyTabAction({
                    errors: {
                      maximumFloor: 'Maximum Floor must be >= Minimum Floor',
                    },
                  }),
                ),
              );
            }
          }

          if (optimizationStatus === AUTOMATIC_OPTIMIZATION.enabled && !kpiGap?.length) {
            return concat(
              of(setActiveTabIndexAction(2)),
              of(
                setAutomaticOptimizationTabAction({
                  errors: {
                    kpiGap: 'Required',
                  },
                }),
              ),
            );
          }
        }
      }

      if (type === DEMAND_TAG_PAGE) {
        if (demandName?.length > 250) {
          return concat(
            of(setActiveTabIndexAction(1)),
            of(
              setSettingsTabAction({
                errors: {
                  name: 'The Name field can’t exceed 250 characters',
                },
              }),
            ),
          );
        }

        if (demandTagSource !== SOURCE_TAG_OPTIONS[0].value && !demandPlatformId?.length) {
          return concat(
            of(setActiveTabIndexAction(1)),
            of(
              setSettingsTabAction({
                errors: {
                  platformId: 'Field cannot be empty',
                },
              }),
            ),
          );
        }

        if (
          flightsDates &&
          (typeof flightsDates?.startDate !== 'number' || typeof flightsDates?.endDate !== 'number')
        ) {
          return concat(
            of(
              setSettingsTabAction({
                errors: {
                  flightsDates: 'Required',
                },
              }),
            ),
          );
        }

        if (tagType === DEMAND_TAG_PAGE_TYPE_VALUES.tag) {
          if (!/^\S*$/.test(adServerUrl.trim())) {
            return concat(
              of(setActiveTabIndexAction(1)),
              of(
                setSettingsTabAction({
                  errors: {
                    url: 'Invalid URL',
                  },
                }),
              ),
            );
          }
        }

        if (tagType === DEMAND_TAG_PAGE_TYPE_VALUES.hb) {
          if (!platform?.connectorId?.length) {
            return concat(
              of(setActiveTabIndexAction(1)),
              of(
                setSettingsTabAction({
                  errors: {
                    platform: 'Required',
                  },
                }),
              ),
            );
          }

          if (platform?.connectorId?.length && platforms?.length) {
            const curPlatform = platforms?.find((item) => item.id === platform.connectorId);

            const errors = curPlatform.params.reduce((acc, cur) => {
              if (cur.required && !platform[cur.name]) {
                return {
                  ...acc,
                  [cur.name]: 'Required',
                };
              }

              if (cur.type === 'ARRAY') {
                let errorText = null;
                try {
                  JSON.parse(platform[cur.name]);
                  // eslint-disable-next-line @typescript-eslint/no-unused-vars
                } catch (error) {
                  errorText = 'Invalid Array';
                }

                if (errorText) {
                  return {
                    ...acc,
                    [cur.name]: errorText,
                  };
                }
              }

              return acc;
            }, {});

            if (Object.keys(errors)?.length) {
              return concat(
                of(setActiveTabIndexAction(1)),
                of(
                  setSettingsTabAction({
                    errors: {
                      ...errors,
                    },
                  }),
                ),
              );
            }
          }

          if (platform?.code?.toUpperCase() === 'APS' && (!bidMappingFileName?.length || !bidMappingFileData?.length)) {
            return concat(
              of(setActiveTabIndexAction(1)),
              of(
                setSettingsTabAction({
                  errors: {
                    bidMapping: 'Required',
                  },
                }),
              ),
            );
          }

          if (DEMAND_TAG_HB_GAM_PLATFORMS.includes(platform?.code) && !maxFloor?.toString()?.length) {
            return concat(
              of(setActiveTabIndexAction(1)),
              of(
                setSettingsTabAction({
                  errors: {
                    maxFloor: 'Required',
                  },
                }),
              ),
            );
          }

          if (
            supplyChainOverride === DEMAND_TAG_SUPPLY_CHAIN_OVERRIDE.enabled &&
            supplyChainValue === DEMAND_TAG_SUPPLY_CHAIN_VALUE.custom &&
            !supplyChainNode?.length
          ) {
            return concat(
              of(setActiveTabIndexAction(1)),
              of(
                setSettingsTabAction({
                  errors: {
                    supplyChainNode: 'Required',
                  },
                }),
              ),
            );
          }

          if (
            supplyChainOverride === DEMAND_TAG_SUPPLY_CHAIN_OVERRIDE.enabled &&
            supplyChainValue === DEMAND_TAG_SUPPLY_CHAIN_VALUE.custom &&
            supplyChainNode?.length &&
            supplyChainNode?.trim()?.match(/\s+/g)
          ) {
            return concat(
              of(setActiveTabIndexAction(1)),
              of(
                setSettingsTabAction({
                  errors: {
                    supplyChainNode: 'Supply Chain value is not valid',
                  },
                }),
              ),
            );
          }
        }

        if (tagType === DEMAND_TAG_PAGE_TYPE_VALUES.mp4) {
          if (!videoId?.length) {
            return concat(
              of(setActiveTabIndexAction(1)),
              of(
                setSettingsTabAction({
                  errors: {
                    videoId: 'Required',
                  },
                }),
              ),
            );
          }
        }

        if (model === DEMAND_TAG_PAGE_BUSINESS_MODEL[1].value) {
          if (!source?.length) {
            return concat(
              of(setActiveTabIndexAction(2)),
              of(
                setPricingTabAction({
                  errors: {
                    source: 'Required',
                  },
                }),
              ),
            );
          }

          if (seatId?.length > 200) {
            return concat(
              of(setActiveTabIndexAction(2)),
              of(
                setPricingTabAction({
                  errors: {
                    seatId: 'The Seat Id field can’t exceed 200 characters',
                  },
                }),
              ),
            );
          }

          if (!pricingType?.length) {
            return concat(
              of(setActiveTabIndexAction(2)),
              of(
                setPricingTabAction({
                  errors: {
                    type: 'Required',
                  },
                }),
              ),
            );
          }

          if (adUnitId?.length > 200) {
            return concat(
              of(setActiveTabIndexAction(2)),
              of(
                setPricingTabAction({
                  errors: {
                    adUnitId: 'The Ad Unit Id field can’t exceed 200 characters',
                  },
                }),
              ),
            );
          }

          if (source === DEMAND_TAG_PAGE_SOURCE[0].value) {
            if (!seatId?.length) {
              return concat(
                of(setActiveTabIndexAction(2)),
                of(
                  setPricingTabAction({
                    errors: {
                      seatId: 'Required',
                    },
                  }),
                ),
              );
            }

            if (!adUnitId?.length) {
              return concat(
                of(setActiveTabIndexAction(2)),
                of(
                  setPricingTabAction({
                    errors: {
                      adUnitId: 'Required',
                    },
                  }),
                ),
              );
            }
          }

          if (source === DEMAND_TAG_PAGE_SOURCE[1].value) {
            if (!adUnitId?.length) {
              return concat(
                of(setActiveTabIndexAction(2)),
                of(
                  setPricingTabAction({
                    errors: {
                      adUnitId: 'Required',
                    },
                  }),
                ),
              );
            }
          }
        }

        if (demandFloorOverride === FLOOR_PRICE.override) {
          if (!demandViewableFloor?.toString()?.length) {
            return concat(
              of(
                setSettingsTabAction({
                  errors: {
                    viewableFloor: 'Required',
                  },
                }),
              ),
            );
          }

          if (!demandFloor?.toString()?.length) {
            return concat(
              of(
                setSettingsTabAction({
                  errors: {
                    floor: 'Required',
                  },
                }),
              ),
            );
          }
        }

        if (
          viewability[DEMAND_TAG_TARGETING_VIEWABILITY_TYPE.inView] &&
          viewability[DEMAND_TAG_TARGETING_VIEWABILITY_TYPE.nonInView] &&
          viewabilityTargeting === DEMAND_TAG_VIEWABILITY_TARGETING.enabled &&
          !viewabilityThreshold?.toString()?.length
        ) {
          return concat(
            of(setActiveTabIndexAction(3)),
            of(
              setTargetingTabAction({
                errors: {
                  viewabilityThreshold: 'Required',
                },
              }),
            ),
          );
        }
      }

      return concat(of(action.payload()));
    }),
  );
