import { createAsyncThunk } from '@reduxjs/toolkit';

import Api from '@/api';

import { formEncoded } from '@/utils/api';

import { withApiError } from '../../../../utils/api';
import { formatHostkeyToClassRepresentation } from '../../utils/format';
import type { Change, FileIntegrityMonitoring, ListResponse } from './types';

export interface ChangesListArgs {
  hostkey: string;
  onlyWithMessages?: boolean;
  order?: 'asc' | 'desc';
  page?: number;
  perPage?: number;
  sort?: string;
}

export interface CustomTableListArgs {
  hostkey: string;
  order?: 'asc' | 'desc';
  page: number;
  perPage: number;
  sort?: string;
  table: string;
}

const DEFAULT_PAGE = 1;
const DEFAULT_PER_PAGE = 10;

const buildChangesParams = ({
  hostkey,
  page = DEFAULT_PAGE,
  perPage = DEFAULT_PER_PAGE,
  sort,
  order,
  onlyWithMessages
}: ChangesListArgs) => {
  const body = new URLSearchParams();
  body.append('includes[]', formatHostkeyToClassRepresentation(hostkey));
  body.append('page', String(page));
  body.append('count', String(perPage));
  body.append('from', '0');
  body.append('to', String(Math.floor(Date.now() / 1000)));
  if (onlyWithMessages === true) {
    body.append('cleanFilters', 'logmessages=%');
  }

  if (sort && order) {
    body.append('sort', `${order === 'asc' ? '' : '-'}${sort}`);
  }
  return body;
};

const buildCustomTableParams = ({
  hostkey,
  table,
  page = DEFAULT_PAGE,
  perPage = DEFAULT_PER_PAGE,
  sort,
  order
}: CustomTableListArgs) => {
  const body = new URLSearchParams();
  body.append('includes[]', formatHostkeyToClassRepresentation(hostkey));
  body.append('table', table);
  body.append('page', String(page));
  body.append('limit', String(perPage));
  if (sort) {
    body.append('sortColumn', sort);
    body.append('sortDescending', order === 'desc' ? '1' : '0');
  }
  return body;
};

const postChanges = async (args: ChangesListArgs) => {
  const { data } = await Api.post<ListResponse<Change>>(
    '/advancedreports/changes',
    buildChangesParams(args),
    formEncoded
  );
  return { hostkey: args.hostkey, data };
};

const postFileIntegrityMonitoring = async (args: Omit<CustomTableListArgs, 'table'>) => {
  const { data } = await Api.post<ListResponse<FileIntegrityMonitoring>>(
    '/advancedreports/custom_table',
    buildCustomTableParams({ ...args, table: 'filechangeslog' }),
    formEncoded
  );
  return { hostkey: args.hostkey, data };
};

export const fetchChanges = createAsyncThunk('activity/fetchChanges', withApiError(postChanges));

// Only the total is used, to show how many of the changes carry a log message.
export const fetchChangesWithMessages = createAsyncThunk(
  'activity/fetchChangesWithMessages',
  withApiError((args: ChangesListArgs) => postChanges({ ...args, onlyWithMessages: true }))
);

export const fetchFileIntegrityMonitoring = createAsyncThunk(
  'activity/fetchFileIntegrityMonitoring',
  withApiError(postFileIntegrityMonitoring)
);
