import { WorkSchedule } from '../../users/entities/user.entity';

// Jours de base par mois selon le planning
const BASE_DAYS_PER_MONTH: Record<WorkSchedule, number> = {
  [WorkSchedule.FIVE_DAYS]: 2.5,   // 30j/an
  [WorkSchedule.SIX_DAYS]:  2.5,   // 30j/an (même base)
  [WorkSchedule.FOUR_DAYS]: 2,   // 24j/an (proportionnel)
};

// Plafond annuel selon le planning
const MAX_DAYS_PER_YEAR: Record<WorkSchedule, number> = {
  [WorkSchedule.FIVE_DAYS]: 30,
  [WorkSchedule.SIX_DAYS]:  30,
  [WorkSchedule.FOUR_DAYS]: 24,
};

export interface SeniorityResult {
  years: number;
  months: number;
  totalMonths: number;
  bonusDays: number;         // jours supplémentaires ancienneté
  baseDays: number;          // jours acquis base
  totalAcquired: number;     // total = base + bonus
}

export function computeSeniority(hiredAt: Date, referenceDate: Date): SeniorityResult {
  const years  = referenceDate.getFullYear() - hiredAt.getFullYear();
  const months = referenceDate.getMonth() - hiredAt.getMonth();

  let totalMonths = years * 12 + months;
  if (referenceDate.getDate() < hiredAt.getDate()) totalMonths--;
  if (totalMonths < 0) totalMonths = 0;

  const fullYears = Math.floor(totalMonths / 12);

  // Bonus ancienneté (jours supplémentaires par an)
  let bonusDays = 0;
  if (fullYears >= 15)     bonusDays = 3;
  else if (fullYears >= 10) bonusDays = 2;
  else if (fullYears >= 5)  bonusDays = 1;

  return {
    years: fullYears,
    months: totalMonths % 12,
    totalMonths,
    bonusDays,
    baseDays: 0,       // calculé dans computeAcquiredDays
    totalAcquired: 0,  // calculé dans computeAcquiredDays
  };
}

export function computeAcquiredDays(
  hiredAt: Date,
  year: number,
  schedule: WorkSchedule,
): number {
  const startOfYear = new Date(year, 0, 1);
  const endOfYear   = new Date(year, 11, 31);

  // Date de début de calcul : la plus récente entre le 1er jan et la date d'embauche
  const from = hiredAt > startOfYear ? hiredAt : startOfYear;
  const to   = endOfYear;

  if (from > to) return 0;

  // Nombre de mois travaillés dans l'année
  let workedMonths = (to.getFullYear() - from.getFullYear()) * 12
    + (to.getMonth() - from.getMonth()) + 1;
  workedMonths = Math.min(workedMonths, 12);

  // Jours de base
  const basePerMonth = BASE_DAYS_PER_MONTH[schedule];
  const maxDays      = MAX_DAYS_PER_YEAR[schedule];
  const baseDays     = Math.min(workedMonths * basePerMonth, maxDays);

  // Bonus ancienneté (calculé sur l'ancienneté au 1er janvier de l'année)
  const { bonusDays } = computeSeniority(hiredAt, startOfYear);

  // Arrondi au 0.5 inférieur
  const total = baseDays + bonusDays;
  return Math.floor(total * 2) / 2;
}