import { Timestamp } from '@win2win/shared';
import { sumBy } from 'lodash';
import moment from 'moment';

function formatMilliseconds(ms: number): string {
  const days = Math.floor(ms / (3600000 * 24)); // 1 day = 3600000 * 24 ms
  const hours = Math.floor((ms % (3600000 * 24)) / 3600000); // 1 hour = 3600000 ms
  const minutes = Math.floor((ms % 3600000) / 60000); // 1 min = 60000 ms
  const seconds = Math.floor((ms % 60000) / 1000); // 1 sec = 1000 ms

  let result = [] as string[];

  if (days > 0) result.push(`${days}d`);
  if (hours > 0) result.push(`${hours}h`);
  if (minutes > 0) result.push(`${minutes}m`);
  if (seconds > 0) result.push(`${seconds}s`);

  return result.length > 0 ? result.join(' ') : '0s'; // Return at least "0s" if no time is calculated
}

export function sortTimestamps(timestamps: Timestamp[]) {
  return [...timestamps].sort((a, b) => new Date(a.TIMESTAMP).getTime() - new Date(b.TIMESTAMP).getTime());
}

export function calculateTotalDuration(timestamps: Timestamp[]): string {
  const sortedTimestamps = pairTimestamps(timestamps);
  return formatMilliseconds(sumBy(sortedTimestamps, (pair) => calculateDuration(pair.checkin, pair.checkout, true) as number));
}

export function pairTimestamps(timestamps: any) {
  const formatDate = (isoString: string) => {
    const date = new Date(isoString);
    return moment(date).format('DD/MM/YYYY HH:mm:ss');
  };

  const sorted = [...timestamps].sort((a, b) => new Date(a.TIMESTAMP).getTime() - new Date(b.TIMESTAMP).getTime());

  const result: any[] = [];
  let currentCheckin: any = null;
  let lastCheckoutTime: Date | null = null;

  for (const entry of sorted) {
    const entryTime = new Date(entry.TIMESTAMP);

    // Detectar descanso si el tiempo entre checkout y siguiente checkin es menor a 1 hora
    const time = 3600000; 
    if (entry.ACTION === 'checkin' && lastCheckoutTime && entryTime.getTime() > lastCheckoutTime.getTime() && entryTime.getTime() - lastCheckoutTime.getTime() < time) {
      result.push({
        checkin: formatDate(lastCheckoutTime.toISOString()),
        checkinId: null,
        checkinCategory: 'descanso',
        checkout: formatDate(entry.TIMESTAMP),
        checkoutId: null,
        checkoutCategory: 'descanso',
      });
    }

    if (entry.ACTION === 'checkin') {
      if (currentCheckin) {
        result.push({
          checkin: formatDate(currentCheckin.TIMESTAMP),
          checkinId: currentCheckin.ID_TIMESTAMP,
          checkinCategory: currentCheckin.CATEGORY,
        });
      }
      currentCheckin = entry;
    } else if (entry.ACTION === 'checkout') {
      if (currentCheckin) {
        result.push({
          checkin: formatDate(currentCheckin.TIMESTAMP),
          checkinId: currentCheckin.ID_TIMESTAMP,
          checkinCategory: currentCheckin.CATEGORY,
          checkout: formatDate(entry.TIMESTAMP),
          checkoutId: entry.ID_TIMESTAMP,
          checkoutCategory: entry.CATEGORY,
        });
        lastCheckoutTime = new Date(entry.TIMESTAMP);
        currentCheckin = null;
      } else {
        result.push({
          checkout: formatDate(entry.TIMESTAMP),
          checkoutId: entry.ID_TIMESTAMP,
          checkoutCategory: entry.CATEGORY,
        });
        lastCheckoutTime = new Date(entry.TIMESTAMP);
      }
    }
  }

  if (currentCheckin) {
    result.push({
      checkin: formatDate(currentCheckin.TIMESTAMP),
      checkinId: currentCheckin.ID_TIMESTAMP,
      checkinCategory: currentCheckin.CATEGORY,
    });
  }

  return result;
}

export function calculateDuration(checkIn: string | null, checkOut: string | null, raw = false) {
  if (!checkIn) return 0;
  const diff = (checkOut ? moment(checkOut, 'DD/MM/YYYY HH:mm:ss') : moment()).diff(moment(checkIn, 'DD/MM/YYYY HH:mm:ss'));
  if (raw) return diff;
  return formatMilliseconds(diff);
}
