/**
 * Qué hacer con una suscripción cuya `fecha_fin` ya pasó.
 *
 * El cron trataba a todas igual: vencida es vencida. Pero una cuenta gratuita
 * (PLAN SOCIO, un plan bonificado a cero) no tiene nada que cobrar, así que
 * expirarla le corta el servicio por una deuda que no existe. Esas se renuevan
 * solas.
 *
 * La prueba gratuita es la excepción: también cuesta 0, pero su razón de ser es
 * terminarse. Se distingue por `periodo_prueba > 0` en el plan.
 */

export type AccionVencimiento = 'renovar' | 'gracia' | 'expirar';

export interface DecisionVencimiento {
  accion: AccionVencimiento;
  /** Solo en 'renovar': hasta cuándo queda vigente el nuevo ciclo. */
  nuevaFechaFin?: Date;
}

const num = (v: unknown): number => {
  const n = Number(v);
  return Number.isFinite(n) ? n : 0;
};

const sumarDias = (fecha: Date, dias: number): Date => {
  const d = new Date(fecha);
  d.setDate(d.getDate() + dias);
  return d;
};

export function decidirVencimiento(params: {
  /** Lo que se le cobra por mes. 0, null o negativo = no se le cobra nada. */
  costoMensual: unknown;
  /** Días de prueba del plan. > 0 significa que el plan ES una prueba. */
  periodoPrueba: unknown;
  diasGracia: unknown;
  estado: string;
  fechaFin: Date;
  ahora: Date;
}): DecisionVencimiento {
  const esPrueba = num(params.periodoPrueba) > 0;
  const esGratuita = num(params.costoMensual) <= 0;

  // Gratuita y no es una prueba: no hay cobro que esperar, se renueva el ciclo.
  if (esGratuita && !esPrueba) {
    return { accion: 'renovar', nuevaFechaFin: sumarDias(params.ahora, 30) };
  }

  const diasGracia = num(params.diasGracia);
  const limiteGracia = sumarDias(params.fechaFin, diasGracia);
  if (params.estado === 'Activo' && diasGracia > 0 && params.ahora <= limiteGracia) {
    return { accion: 'gracia' };
  }

  return { accion: 'expirar' };
}
