import { createQueryKeys } from '@lukemorales/query-key-factory';

import {
  getMalwareApiClient,
  getScanCompareApiClient,
  getSearchApiClient,
} from '@/api/api';
import {
  ModelMalware,
  ModelNodeIdentifierNodeTypeEnum,
  ModelScanCompareReq,
  ModelScanInfo,
  ModelScanInfoStatusEnum,
  ModelScanResultsReq,
  SearchSearchNodeReq,
  SearchSearchScanReq,
} from '@/api/generated';
import { DF404Error } from '@/components/error/404';
import { MalwaresCountsCardData } from '@/features/malwares/pages/landing/MalwareCountsCard';
import { getResponseErrors } from '@/utils/403';
import { apiWrapper } from '@/utils/api';
import { SeverityEnum } from '@/utils/enum';
import { SCAN_STATUS_FILTER_TYPE, SCAN_STATUS_GROUPS } from '@/utils/scan';

export const malwareQueries = createQueryKeys('malware', {
  scanList: (filters: {
    page?: number;
    nodeTypes?: string[];
    order?: {
      sortBy: string;
      descending: boolean;
    };
    malwareScanStatus?: SCAN_STATUS_FILTER_TYPE;
    hosts?: string[];
    containers?: string[];
    images?: string[];
    clusters?: string[];
    registryAccounts?: string[];
    pageSize: number;
  }) => {
    const {
      page = 1,
      nodeTypes = [],
      malwareScanStatus,
      hosts,
      containers,
      images,
      clusters,
      pageSize,
      registryAccounts,
      order,
    } = filters;
    return {
      queryKey: [{ filters }],
      queryFn: async () => {
        type ScanResult = ModelScanInfo & {
          total: number;
          critical: number;
          high: number;
          medium: number;
          low: number;
          unknown: number;
        };
        const results: {
          scans: ScanResult[];
          currentPage: number;
          totalRows: number;
          message?: string;
        } = {
          scans: [],
          currentPage: 1,
          totalRows: 0,
        };

        const nodeFilters = {
          node_type: nodeTypes,
        } as {
          node_type?: string[];
          host_name?: string[];
          node_id?: string[];
          docker_image_id?: string[];
          malware_scan_status?: string[];
        };
        if (hosts && hosts?.length > 0) {
          nodeFilters.host_name = nodeFilters.host_name
            ? nodeFilters.host_name.concat(hosts)
            : hosts;
        }
        if (containers && containers?.length > 0) {
          nodeFilters.node_id = nodeFilters.node_id
            ? nodeFilters.node_id.concat(containers)
            : containers;
        }
        if (images && images?.length > 0) {
          nodeFilters.docker_image_id = nodeFilters.docker_image_id
            ? nodeFilters.docker_image_id.concat(images)
            : images;
        }
        if (malwareScanStatus) {
          nodeFilters.malware_scan_status = SCAN_STATUS_GROUPS[malwareScanStatus];
        }
        const scanRequestParams: SearchSearchScanReq = {
          node_filters: {
            filters: {
              match_filter: { filter_in: {} },
              order_filter: { order_fields: [] },
              contains_filter: { filter_in: { ...nodeFilters } },
              compare_filter: null,
              not_contains_filter: {
                filter_in: {},
              },
            },
            in_field_filter: null,
            window: {
              offset: 0,
              size: 0,
            },
          },
          scan_filters: {
            filters: {
              match_filter: { filter_in: {} },
              order_filter: { order_fields: [] },
              contains_filter: { filter_in: {} },
              compare_filter: null,
              not_contains_filter: {
                filter_in: {},
              },
            },
            in_field_filter: null,
            window: {
              offset: 0,
              size: 1,
            },
          },
          window: { offset: page * pageSize, size: pageSize },
        };
        if (order) {
          scanRequestParams.scan_filters.filters.order_filter.order_fields = [
            {
              field_name: order.sortBy,
              descending: order.descending,
            },
          ];
        } else {
          scanRequestParams.scan_filters.filters.order_filter.order_fields = [
            {
              field_name: 'updated_at',
              descending: true,
            },
          ];
        }

        if (registryAccounts?.length) {
          scanRequestParams.related_node_filter = {
            relation_ship: 'HOSTS',
            node_filter: {
              filters: {
                compare_filter: null,
                contains_filter: {
                  filter_in: {
                    node_id: registryAccounts,
                  },
                },
                match_filter: {
                  filter_in: {},
                },
                not_contains_filter: {
                  filter_in: {},
                },
                order_filter: {
                  order_fields: [],
                },
              },
              in_field_filter: null,
              window: {
                offset: 0,
                size: 0,
              },
            },
          };
        }

        if (clusters && clusters?.length > 0) {
          if (scanRequestParams.related_node_filter) {
            scanRequestParams.related_node_filter.next_filter = {
              relation_ship: 'INSTANCIATE',
              node_filter: {
                filters: {
                  compare_filter: null,
                  contains_filter: {
                    filter_in: {
                      node_id: clusters,
                    },
                  },
                  match_filter: {
                    filter_in: {},
                  },
                  not_contains_filter: {
                    filter_in: {},
                  },
                  order_filter: {
                    order_fields: [],
                  },
                },
                in_field_filter: null,
                window: {
                  offset: 0,
                  size: 0,
                },
              },
            };
          } else {
            scanRequestParams.related_node_filter = {
              relation_ship: 'HOSTS',
              node_filter: {
                filters: {
                  compare_filter: null,
                  contains_filter: {
                    filter_in: {},
                  },
                  match_filter: {
                    filter_in: {},
                  },
                  not_contains_filter: {
                    filter_in: {},
                  },
                  order_filter: {
                    order_fields: [],
                  },
                },
                in_field_filter: null,
                window: {
                  offset: 0,
                  size: 0,
                },
              },
              next_filter: {
                relation_ship: 'INSTANCIATE',
                node_filter: {
                  filters: {
                    compare_filter: null,
                    contains_filter: {
                      filter_in: {
                        node_id: clusters,
                      },
                    },
                    match_filter: {
                      filter_in: {},
                    },
                    not_contains_filter: {
                      filter_in: {},
                    },
                    order_filter: {
                      order_fields: [],
                    },
                  },
                  in_field_filter: null,
                  window: {
                    offset: 0,
                    size: 0,
                  },
                },
              },
            };
          }
        }

        const searchMalwaresScanApi = apiWrapper({
          fn: getSearchApiClient().searchMalwaresScan,
        });
        const resultPromise = searchMalwaresScanApi({
          searchSearchScanReq: scanRequestParams,
        });

        const countsResultApi = apiWrapper({
          fn: getSearchApiClient().searchMalwareScanCount,
        });
        const countsResultPromise = countsResultApi({
          searchSearchScanReq: {
            ...scanRequestParams,
            window: {
              ...scanRequestParams.window,
              size: 10 * scanRequestParams.window.size,
            },
          },
        });
        const [result, countsResult] = await Promise.all([
          resultPromise,
          countsResultPromise,
        ]);
        if (!result.ok) {
          throw result.error;
        }

        if (!countsResult.ok) {
          throw countsResult.error;
        }

        if (result.value === null) {
          return results;
        }

        results.scans = result.value.map((scan) => {
          const severities = scan.severity_counts as {
            critical: number;
            high: number;
            medium: number;
            low: number;
            unknown: number;
          };
          severities.critical = severities.critical ?? 0;
          severities.high = severities.high ?? 0;
          severities.medium = severities.medium ?? 0;
          severities.low = severities.low ?? 0;
          severities.unknown = severities.unknown ?? 0;

          return {
            ...scan,
            total:
              severities.critical + severities.high + severities.medium + severities.low,
            critical: severities.critical,
            high: severities.high,
            medium: severities.medium,
            low: severities.low,
            unknown: severities.unknown,
          };
        });

        results.currentPage = page;
        results.totalRows = page * pageSize + countsResult.value.count;

        return results;
      },
    };
  },
  scanResults: (filters: {
    scanId: string;
    page: number;
    pageSize: number;
    severity: string[];
    rules: string[];
    classes: string[];
    visibility: string[];
    order?: {
      sortBy: string;
      descending: boolean;
    };
  }) => {
    return {
      queryKey: [{ filters }],
      queryFn: async () => {
        const { scanId, visibility, severity, rules, classes, page, order, pageSize } =
          filters;
        // status api
        const statusMalwareScanApi = apiWrapper({
          fn: getMalwareApiClient().statusMalwareScan,
        });
        const statusMalwareScanResponse = await statusMalwareScanApi({
          modelScanStatusReq: {
            scan_ids: [scanId],
            bulk_scan_id: '',
          },
        });
        if (!statusMalwareScanResponse.ok) {
          if (statusMalwareScanResponse.error.response.status === 400) {
            const { message } = await getResponseErrors(statusMalwareScanResponse.error);
            return { message };
          } else if (statusMalwareScanResponse.error.response.status === 404) {
            throw new DF404Error('Scan not found');
          }
          throw statusMalwareScanResponse.error;
        }

        if (
          !statusMalwareScanResponse ||
          !statusMalwareScanResponse.value?.statuses?.[scanId]
        ) {
          throw new Error('Scan status not found');
        }

        const scanStatus = statusMalwareScanResponse.value?.statuses?.[scanId].status;

        const isScanRunning =
          scanStatus !== ModelScanInfoStatusEnum.Complete &&
          scanStatus !== ModelScanInfoStatusEnum.Error;
        const isScanError = scanStatus === ModelScanInfoStatusEnum.Error;

        if (isScanRunning || isScanError) {
          return {
            scanStatusResult: statusMalwareScanResponse.value.statuses[scanId],
          };
        }

        const scanResultsReq: ModelScanResultsReq = {
          fields_filter: {
            contains_filter: {
              filter_in: {},
            },
            match_filter: { filter_in: {} },
            order_filter: { order_fields: [] },
            compare_filter: null,
          },
          scan_id: scanId,
          window: {
            offset: page * pageSize,
            size: pageSize,
          },
        };

        if (severity.length) {
          scanResultsReq.fields_filter.contains_filter.filter_in!['file_severity'] =
            severity;
        }

        if (rules.length) {
          scanResultsReq.fields_filter.contains_filter.filter_in!['name'] = rules;
        }

        if (classes.length) {
          scanResultsReq.fields_filter.contains_filter.filter_in!['class'] = classes;
        }

        if (visibility.length === 1) {
          scanResultsReq.fields_filter.contains_filter.filter_in!['masked'] = [
            visibility.includes('masked') ? true : false,
          ];
        }

        if (order) {
          scanResultsReq.fields_filter.order_filter.order_fields?.push({
            field_name: order.sortBy,
            descending: order.descending,
          });
        }

        const resultMalwareScanApi = apiWrapper({
          fn: getMalwareApiClient().resultMalwareScan,
        });
        const resultMalwareScanPromise = resultMalwareScanApi({
          modelScanResultsReq: scanResultsReq,
        });

        const resultCountMalwareScanApi = apiWrapper({
          fn: getMalwareApiClient().resultCountMalwareScan,
        });
        const resultCountsPromise = resultCountMalwareScanApi({
          modelScanResultsReq: {
            ...scanResultsReq,
            window: {
              ...scanResultsReq.window,
              size: 10 * scanResultsReq.window.size,
            },
          },
        });

        const [resultMalwareScanResponse, resultCounts] = await Promise.all([
          resultMalwareScanPromise,
          resultCountsPromise,
        ]);

        if (!resultMalwareScanResponse.ok) {
          throw resultMalwareScanResponse.error;
        }

        const totalSeverity = Object.values(
          resultMalwareScanResponse.value?.severity_counts ?? {},
        ).reduce((acc, value) => {
          acc = acc + value;
          return acc;
        }, 0);

        if (!resultCounts.ok) {
          throw resultCounts.error;
        }

        return {
          scanStatusResult: statusMalwareScanResponse.value.statuses[scanId],
          data: {
            totalSeverity,
            severityCounts: {
              critical:
                resultMalwareScanResponse.value.severity_counts?.[
                  SeverityEnum.Critical
                ] ?? 0,
              high:
                resultMalwareScanResponse.value.severity_counts?.[SeverityEnum.High] ?? 0,
              medium:
                resultMalwareScanResponse.value.severity_counts?.[SeverityEnum.Medium] ??
                0,
              low:
                resultMalwareScanResponse.value.severity_counts?.[SeverityEnum.Low] ?? 0,
              unknown:
                resultMalwareScanResponse.value.severity_counts?.[SeverityEnum.Unknown] ??
                0,
            },
            tableData: resultMalwareScanResponse.value?.malwares ?? [],
            dockerImageName: resultMalwareScanResponse.value?.docker_image_name ?? '',
            pagination: {
              currentPage: page,
              totalRows: page * pageSize + resultCounts.value.count,
            },
          },
        };
      },
    };
  },
  top5MalwaresForScan: (filters: {
    scanId: string;
    severity: string[];
    rules: string[];
    classes: string[];
    visibility: string[];
  }) => {
    return {
      queryKey: [{ filters }],
      queryFn: async () => {
        const { scanId, severity, rules, classes, visibility } = filters;

        const scanResultsReq: ModelScanResultsReq = {
          fields_filter: {
            contains_filter: {
              filter_in: {},
            },
            match_filter: { filter_in: {} },
            order_filter: {
              order_fields: [
                {
                  field_name: 'file_sev_score',
                  descending: true,
                },
              ],
            },
            compare_filter: null,
          },
          scan_id: scanId,
          window: {
            offset: 0,
            size: 5,
          },
        };

        if (severity.length) {
          scanResultsReq.fields_filter.contains_filter.filter_in!['file_severity'] =
            severity;
        }

        if (rules.length) {
          scanResultsReq.fields_filter.contains_filter.filter_in!['name'] = rules;
        }

        if (classes.length) {
          scanResultsReq.fields_filter.contains_filter.filter_in!['class'] = classes;
        }

        if (visibility.length === 1) {
          scanResultsReq.fields_filter.contains_filter.filter_in!['masked'] = [
            visibility.includes('masked') ? true : false,
          ];
        }

        const resultMalwareScanApi = apiWrapper({
          fn: getMalwareApiClient().resultMalwareScan,
        });
        const resultMalwareScanResponse = await resultMalwareScanApi({
          modelScanResultsReq: scanResultsReq,
        });

        if (!resultMalwareScanResponse.ok) {
          if (resultMalwareScanResponse.error.response.status === 404) {
            throw new DF404Error('Scan not found');
          }
          throw resultMalwareScanResponse.error;
        }

        return {
          data: resultMalwareScanResponse.value?.malwares ?? [],
        };
      },
    };
  },
  top5MalwareAssets: (filters: { nodeType: 'image' | 'host' | 'container' }) => {
    const { nodeType } = filters;
    return {
      queryKey: [filters],
      queryFn: async () => {
        const top5NodesApi = apiWrapper({
          fn: {
            [ModelNodeIdentifierNodeTypeEnum.Image]:
              getSearchApiClient().searchContainerImages,
            [ModelNodeIdentifierNodeTypeEnum.Host]: getSearchApiClient().searchHosts,
            [ModelNodeIdentifierNodeTypeEnum.Container]:
              getSearchApiClient().searchContainers,
          }[nodeType],
        });
        const top5Nodes = await top5NodesApi({
          searchSearchNodeReq: {
            node_filter: {
              filters: {
                contains_filter: {
                  filter_in: {
                    pseudo: [false],
                    active: [true],
                    malware_scan_status: ['COMPLETE'],
                  },
                },
                match_filter: {
                  filter_in: {},
                },
                order_filter: {
                  order_fields: [
                    {
                      field_name: 'malwares_count',
                      descending: true,
                    },
                  ],
                },
                compare_filter: [
                  {
                    field_name: 'malwares_count',
                    field_value: 0,
                    greater_than: true,
                  },
                ],
              },
              in_field_filter: [],
              window: {
                offset: 0,
                size: 0,
              },
            },
            window: {
              offset: 0,
              size: 5,
            },
          },
        });
        if (!top5Nodes.ok) {
          throw top5Nodes.error;
        }

        const getTop5NodeScans = apiWrapper({
          fn: getSearchApiClient().searchMalwaresScan,
        });

        const top5NodeScans = await getTop5NodeScans({
          searchSearchScanReq: {
            node_filters: {
              filters: {
                compare_filter: [],
                contains_filter: { filter_in: {} },
                match_filter: { filter_in: {} },
                order_filter: { order_fields: [] },
                not_contains_filter: { filter_in: {} },
              },
              in_field_filter: [],
              window: { offset: 0, size: 0 },
            },
            scan_filters: {
              filters: {
                compare_filter: [],
                contains_filter: {
                  filter_in: {
                    node_id: top5Nodes.value
                      .map((node) => node.malware_latest_scan_id)
                      .filter((scanId) => {
                        return !!scanId?.length;
                      }),
                  },
                },
                match_filter: { filter_in: {} },
                order_filter: { order_fields: [] },
                not_contains_filter: { filter_in: {} },
              },
              in_field_filter: [],
              window: { offset: 0, size: 0 },
            },
            window: {
              offset: 0,
              size: 5,
            },
          },
        });

        if (!top5NodeScans.ok) {
          throw top5NodeScans.error;
        }

        return top5Nodes.value
          .map((node) => {
            const latestScan = top5NodeScans.value.find(
              (scan) => scan.node_id === node.node_id,
            );
            if (!latestScan) {
              return null;
            }
            return {
              name: latestScan.node_name,
              id: latestScan.node_id,
              critical: latestScan.severity_counts?.critical ?? 0,
              high: latestScan.severity_counts?.high ?? 0,
              medium: latestScan.severity_counts?.medium ?? 0,
              low: latestScan.severity_counts?.low ?? 0,
              unknown: latestScan.severity_counts?.unknown ?? 0,
            };
          })
          .reduce<
            Array<{
              name: string;
              critical: number;
              high: number;
              medium: number;
              low: number;
              unknown: number;
            }>
          >((acc, curr) => {
            if (curr) {
              acc.push(curr);
            }
            return acc;
          }, []);
      },
    };
  },
  uniqueMalwaresCount: () => {
    return {
      queryKey: ['uniqueMalwaresCount'],
      queryFn: async () => {
        const defaultResults: MalwaresCountsCardData = {
          total: 0,
          severityBreakdown: {
            critical: 0,
            high: 0,
            medium: 0,
            low: 0,
            unknown: 0,
          },
        };
        const searchMalwaresCountApi = apiWrapper({
          fn: getSearchApiClient().searchMalwaresCount,
        });
        const uniqueMalwareCounts = await searchMalwaresCountApi({
          searchSearchNodeReq: {
            node_filter: {
              filters: {
                contains_filter: { filter_in: {} },
                match_filter: { filter_in: {} },
                order_filter: { order_fields: [] },
                compare_filter: null,
              },
              in_field_filter: [],
              window: {
                offset: 0,
                size: 0,
              },
            },
            window: {
              offset: 0,
              size: 999999999,
            },
          },
        });

        if (!uniqueMalwareCounts.ok) {
          throw new Error('Error getting unique malware counts');
        }

        return {
          total: uniqueMalwareCounts.value.count,
          severityBreakdown: {
            critical: uniqueMalwareCounts.value.categories?.[SeverityEnum.Critical] ?? 0,
            high: uniqueMalwareCounts.value.categories?.[SeverityEnum.High] ?? 0,
            medium: uniqueMalwareCounts.value.categories?.[SeverityEnum.Medium] ?? 0,
            low: uniqueMalwareCounts.value.categories?.[SeverityEnum.Low] ?? 0,
            unknown: uniqueMalwareCounts.value.categories?.[SeverityEnum.Unknown] ?? 0,
          },
        };
      },
    };
  },
  uniqueMalwares: (filters: {
    page?: number;
    order?: {
      sortBy: string;
      descending: boolean;
    };
    pageSize: number;
    severity: string[];
    hostIds: string[];
    containerIds: string[];
    containerImageIds: string[];
    clusterIds: string[];
  }) => {
    const {
      page = 1,
      order,
      severity,
      pageSize,
      hostIds,
      containerIds,
      containerImageIds,
      clusterIds,
    } = filters;
    return {
      queryKey: [{ filters }],
      queryFn: async () => {
        const results: {
          malwares: Array<ModelMalware>;
          currentPage: number;
          totalRows: number;
          message?: string;
        } = {
          currentPage: 1,
          totalRows: 0,
          malwares: [],
        };

        const searchMalwaresRequestParams: SearchSearchNodeReq = {
          node_filter: {
            filters: {
              contains_filter: { filter_in: {} },
              order_filter: { order_fields: [] },
              match_filter: { filter_in: {} },
              compare_filter: null,
            },
            in_field_filter: null,
            window: {
              offset: 0,
              size: 0,
            },
          },
          window: { offset: page * pageSize, size: pageSize },
        };
        const nodeIds = [...hostIds, ...containerIds, ...containerImageIds];
        if (nodeIds.length || clusterIds.length) {
          const nodeTypes = [];
          if (hostIds.length) {
            nodeTypes.push('host');
          }
          if (containerIds.length) {
            nodeTypes.push('container');
          }
          if (containerImageIds.length) {
            nodeTypes.push('container_image');
          }

          const containsFilter = {
            filter_in: {},
          };

          if (nodeIds.length) {
            containsFilter.filter_in = {
              node_id: nodeIds,
              node_type: nodeTypes,
            };
          }
          if (clusterIds.length) {
            containsFilter.filter_in = {
              ...containsFilter.filter_in,
              kubernetes_cluster_id: clusterIds,
            };
          }
          searchMalwaresRequestParams.related_node_filter = {
            relation_ship: 'DETECTED',
            node_filter: {
              filters: {
                contains_filter: { filter_in: {} },
                order_filter: { order_fields: [] },
                match_filter: { filter_in: {} },
                compare_filter: null,
              },
              in_field_filter: null,
              window: {
                offset: 0,
                size: 0,
              },
            },
            next_filter: {
              relation_ship: 'SCANNED',
              node_filter: {
                filters: {
                  contains_filter: containsFilter,
                  compare_filter: [],
                  match_filter: { filter_in: {} },
                  order_filter: { order_fields: [] },
                },
                in_field_filter: [],
                window: {
                  offset: 0,
                  size: 0,
                },
              },
            },
          };
        }
        if (severity.length) {
          searchMalwaresRequestParams.node_filter.filters.contains_filter.filter_in![
            'file_severity'
          ] = severity;
        }

        if (order) {
          searchMalwaresRequestParams.node_filter.filters.order_filter.order_fields = [
            {
              field_name: order.sortBy,
              descending: order.descending,
            },
          ];
        } else {
          searchMalwaresRequestParams.node_filter.filters.order_filter.order_fields = [
            {
              field_name: 'file_severity',
              descending: true,
            },
          ];
        }

        const searchMalwaresApi = apiWrapper({
          fn: getSearchApiClient().searchMalwares,
        });
        const searchMalwaresPromise = searchMalwaresApi({
          searchSearchNodeReq: searchMalwaresRequestParams,
        });

        const searchMalwaresCountApi = apiWrapper({
          fn: getSearchApiClient().searchMalwaresCount,
        });
        const searchMalwaresCountPromise = searchMalwaresCountApi({
          searchSearchNodeReq: {
            ...searchMalwaresRequestParams,
            window: {
              ...searchMalwaresRequestParams.window,
              size: 10 * pageSize,
            },
          },
        });
        const [searchMalwaresResponse, searchMalwaresCountResponse] = await Promise.all([
          searchMalwaresPromise,
          searchMalwaresCountPromise,
        ]);
        if (!searchMalwaresResponse.ok) {
          throw searchMalwaresResponse.error;
        }
        if (!searchMalwaresCountResponse.ok) {
          throw searchMalwaresCountResponse.error;
        }

        results.malwares = searchMalwaresResponse.value;
        results.currentPage = page;
        results.totalRows = page * pageSize + searchMalwaresCountResponse.value.count;

        return results;
      },
    };
  },
  scanResultSummaryCounts: (filters: { scanId: string }) => {
    return {
      queryKey: [filters],
      queryFn: async () => {
        const { scanId } = filters;
        const resultMalwareScanApi = apiWrapper({
          fn: getMalwareApiClient().resultMalwareScan,
        });
        const malwareScanResults = await resultMalwareScanApi({
          modelScanResultsReq: {
            scan_id: scanId,
            window: {
              offset: 0,
              size: 1,
            },
            fields_filter: {
              contains_filter: {
                filter_in: {},
              },
              match_filter: {
                filter_in: {},
              },
              order_filter: { order_fields: [] },
              compare_filter: null,
            },
          },
        });

        if (!malwareScanResults.ok) {
          console.error(malwareScanResults);
          throw new Error("Couldn't get malware scan results");
        }
        return {
          scanId,
          timestamp: malwareScanResults.value.created_at,
          counts: malwareScanResults.value.severity_counts ?? {},
        };
      },
    };
  },
  scanDiff: (filters: { baseScanId: string; toScanId: string }) => {
    const { baseScanId, toScanId } = filters;
    return {
      queryKey: [{ filters }],
      queryFn: async () => {
        if (!baseScanId || !toScanId) {
          throw new Error('Scan ids are required for comparision');
        }

        const results: {
          added: ModelMalware[];
          deleted: ModelMalware[];
          message?: string;
        } = {
          added: [],
          deleted: [],
        };

        const compareScansApi = apiWrapper({
          fn: getScanCompareApiClient().diffAddMalware,
        });

        const addedCompareReq: ModelScanCompareReq = {
          fields_filter: {
            contains_filter: {
              filter_in: {},
            },
            match_filter: { filter_in: {} },
            order_filter: { order_fields: [] },
            compare_filter: null,
          },
          base_scan_id: toScanId,
          to_scan_id: baseScanId,
          window: {
            offset: 0,
            size: 99999,
          },
        };

        const addScanPromise = compareScansApi({
          modelScanCompareReq: addedCompareReq,
        });

        // deleted
        const deletedCompareReq: ModelScanCompareReq = {
          fields_filter: {
            contains_filter: {
              filter_in: {},
            },
            match_filter: { filter_in: {} },
            order_filter: { order_fields: [] },
            compare_filter: null,
          },
          base_scan_id: baseScanId,
          to_scan_id: toScanId,
          window: {
            offset: 0,
            size: 99999,
          },
        };
        const deletedScanPromise = compareScansApi({
          modelScanCompareReq: deletedCompareReq,
        });

        const [addScanResponse, deletedScanResponse] = await Promise.all([
          addScanPromise,
          deletedScanPromise,
        ]);

        if (!addScanResponse.ok) {
          const { message } = await getResponseErrors(addScanResponse.error);
          return {
            error: 'Error getting scan diff',
            message,
            ...results,
          };
        }

        if (!addScanResponse.value) {
          return results;
        }

        const addedScans = addScanResponse.value._new;
        if (!deletedScanResponse.ok) {
          const { message } = await getResponseErrors(deletedScanResponse.error);
          return {
            error: 'Error getting scan diff',
            message,
            ...results,
          };
        }

        if (!deletedScanResponse.value) {
          return results;
        }
        const deletedScans = deletedScanResponse.value._new;

        results.added = addedScans ?? [];
        results.deleted = deletedScans ?? [];

        return results;
      },
    };
  },
});
