import {
  rand,
  randCompanyName,
  randIp,
  randNumber,
  randPastDate,
  randPhrase,
  randUrl,
  randUser
} from '@ngneat/falso';
import type { DataGridProps } from '../types';
import { companySizeMap, companySizes, osTypes } from './constants';
import type { CompanySize, OSType } from './constants';

const getMonthDiff = (d1: Date, d2: Date) =>
  Math.max(0, (d2.getFullYear() - d1.getFullYear()) * 12 - d1.getMonth() + d2.getMonth());

const simulateRowData =
  (isChild?: boolean) => (rowData: DataGridProps['tableData']['data'][number], i: number) => {
    if (typeof rowData.activityType !== 'undefined' || isChild) {
      rowData.activityType = 'Expansion';
      if (i % 2 === 0)
        rowData.activity = `${randNumber({
          min: 5,
          max: 50,
          precision: 5
        })} TM licenses have been purchased`;
    }

    if (typeof rowData.sourceIp !== 'undefined' || isChild) {
      rowData.destinationIp = randIp();
      rowData.sourceIp = randIp();
      rowData.url = randUrl();
    }

    if (rowData.cancellationReason || rowData.comments || isChild) {
      rowData.cancellationReason = randPhrase();
      if (i % 2 === 0) rowData.comments = randPhrase();
      rowData.points = randNumber({ min: 75, max: 120 });
      rowData.osType = rand(osTypes) as OSType;
    }

    if (rowData.companyName || rowData.companySize) {
      rowData.companyName = randCompanyName();
      rowData.companySize = rand(companySizes);
      if (i % 3 > 0) rowData.disabled = false;
    }

    if (typeof rowData.country !== 'undefined') {
      if (i % 3 > 0) rowData.country = rand(['CA', 'GB', 'US']);
    }

    if (rowData.createdDate) {
      rowData.createdDate = randPastDate({ years: 3 }).toISOString();
    }

    if (typeof rowData.sourceIp !== 'undefined' || isChild) {
      rowData.destinationIp = randIp();
      rowData.sourceIp = randIp();
      rowData.url = randUrl();
    }

    if (typeof rowData.arr !== 'undefined' || rowData.mau) {
      if (rowData.firstPaymentDate)
        rowData.ageInMonths = getMonthDiff(new Date(rowData.firstPaymentDate), new Date());
      const companySizeOptions = companySizeMap[rowData.companySize as CompanySize];
      if (companySizeOptions) {
        rowData.appsLicenses = randNumber({
          ...companySizeOptions,
          precision: 10
        });
        rowData.appsUtilized =
          rowData.appsLicenses > 1
            ? randNumber({
                min: 0,
                max: rowData.appsLicenses / 2
              })
            : 0;
      }
      rowData.psLicenses = randNumber({ min: 1, max: 10 });
      rowData.psUtilized =
        rowData.psLicenses > 1 ? randNumber({ min: 0, max: rowData.psLicenses / 2 }) : 0;
      rowData.tmLicenses = randNumber({ min: 10, max: 300, precision: 10 });
      rowData.tmUtilized =
        rowData.tmLicenses > 1 ? randNumber({ min: 0, max: rowData.tmLicenses / 2 }) : 0;
      rowData.mau = randNumber({ min: 0, max: rowData.tmUtilized });
      rowData.arr =
        (rowData.appsLicenses || 0) * 15 + rowData.psLicenses * 25 + rowData.tmLicenses * 100;
    }

    if (rowData.userName) {
      const { email, firstName, lastName } = randUser();
      rowData.iconSrc = '';
      rowData.userName = firstName + ' ' + lastName;
      rowData.userEmail = email;
    }

    if (rowData.networkName) {
      rowData.networkName = randCompanyName();
    }

    if (rowData.accountManager) {
      const { email, firstName, lastName } = randUser();
      rowData.accountManager = firstName + ' ' + lastName;
      rowData.userEmail = email;
    }
  };

/**
 * Returns an extended array of simulated TableData (the divisor is also a start position for simulated data.).
 */
export const getSimulatedTableData = (
  tableData: DataGridProps['tableData'],
  divisor?: number,
  rowsCount?: number
) => {
  const length = tableData.data.length;
  divisor = divisor || length;
  rowsCount = Math.max(rowsCount || 0, length);

  const simulatedData = [];
  for (let i = 0; i < rowsCount; i++) {
    const rowData = {
      ...tableData.data[i % divisor],
      actions: undefined, // hide active button
      _id: 'id' + (100000 + i)
    };

    if (i >= divisor) {
      rowData.childs = undefined;
      simulateRowData(false)(rowData, i);
    } else if (rowData.childs) {
      rowData.childs.forEach(simulateRowData(true));
    }

    simulatedData.push(rowData);
  }
  return {
    ...tableData,
    totalRecords: simulatedData.length,
    data: simulatedData
  } as DataGridProps['tableData'];
};
