import { Sort } from '@msfa-models/sort.model';
const CURRENT_YEAR = new Date().getFullYear();

interface FromToDates {
  from: string | Date;
  to: string | Date;
}

export function sort<T>(data: T[], sort: Sort<keyof T>): T[] {
  const reverse = sort.order === 'desc' ? -1 : 1;
  return [...data].sort((a, b) => {
    const first = a[sort.key];
    const second = b[sort.key];

    return reverse * (+(first > second) - +(second > first));
  });
}

export function sortFromToDates(a: FromToDates, b: FromToDates): number {
  const cleanDateString = (dateString: string): string => {
    return dateString.substring(0, 10).replace(/-/g, '');
  };

  if (!a.from || !b.from) {
    return -1;
  }

  if (a.from instanceof Date) {
    a.from = a.from.toISOString();
  }
  if (a.to instanceof Date) {
    a.to = a.to.toISOString();
  }
  if (b.from instanceof Date) {
    b.from = b.from.toISOString();
  }
  if (b.to instanceof Date) {
    b.to = b.to.toISOString();
  }

  // Remove optional time and '-' characters whenever the ISO date string is given.
  a.from = cleanDateString(a.from);
  b.from = cleanDateString(b.from);
  a.to = cleanDateString(a.to);
  b.to = cleanDateString(b.to);

  // If no complete dates are available we will add as high numbers as possible to make them sort on top.
  // If no tillValue is available it means it is still ongoing and should sort on top
  const aFrom = +a.from.padEnd(8, '9');
  const bFrom = +b.from.padEnd(8, '9');
  const aTo = !a.to ? +`${CURRENT_YEAR + 1}9999` : +a.to.padEnd(8, '9');
  const bTo = !b.to ? +`${CURRENT_YEAR + 1}9999` : +b.to.padEnd(8, '9');

  if (isNaN(aTo)) {
    return 1;
  }
  if (isNaN(bTo)) {
    return -1;
  }

  if (aTo === bTo) {
    if (isNaN(aFrom)) {
      return 1;
    }
    if (isNaN(bFrom)) {
      return -1;
    }
    return aFrom === bFrom ? 0 : bFrom < aFrom ? -1 : 1;
  }

  return bTo < aTo ? -1 : 1;
}
