export interface CacheRange {
  contribuyenteId: string;
  startDate: string; // YYYY-MM-01 (día 1 del mes inicial)
  endDate: string;   // YYYY-MM-01 (día 1 del mes final, para BETWEEN contra make_date)
}

/**
 * Decide si un rango de fechas es elegible para leer de `metricas_mensuales`
 * (read-through cache de Tanda B). Requisitos:
 *   - `contribuyenteId` presente (la tabla solo tiene datos por contribuyente)
 *   - `conciliacion` desactivada (la tabla guarda flujo normal, no id_conciliacion)
 *   - `fechaFin` antes del primer día del año actual (años cerrados)
 *   - `fechaInicio` es día 1 del mes; `fechaFin` es último día del mes
 *
 * Retorna `null` si no califica — el caller debe caer al path on-the-fly.
 */
export function planCache(
  fechaInicio: string,
  fechaFin: string,
  conciliacion: boolean | undefined,
  contribuyenteId: string | null | undefined,
): CacheRange | null {
  // Escape hatch para validación: forzar el path on-the-fly aunque el rango
  // califique. Útil en `validate-metricas.ts` para comparar cache vs raw.
  if (process.env.METRICAS_BYPASS_CACHE === '1') return null;
  if (!contribuyenteId || conciliacion) return null;
  const fi = new Date(fechaInicio + 'T00:00:00Z');
  const ff = new Date(fechaFin + 'T00:00:00Z');
  if (isNaN(fi.getTime()) || isNaN(ff.getTime())) return null;
  const currentYearStart = new Date(Date.UTC(new Date().getUTCFullYear(), 0, 1));
  if (ff >= currentYearStart) return null;
  if (fi.getUTCDate() !== 1) return null;
  const lastDay = new Date(Date.UTC(ff.getUTCFullYear(), ff.getUTCMonth() + 1, 0)).getUTCDate();
  if (ff.getUTCDate() !== lastDay) return null;
  const safe = contribuyenteId.replace(/[^a-f0-9-]/gi, '');
  if (!safe) return null;
  const startDate = `${fi.getUTCFullYear()}-${String(fi.getUTCMonth() + 1).padStart(2, '0')}-01`;
  const endDate = `${ff.getUTCFullYear()}-${String(ff.getUTCMonth() + 1).padStart(2, '0')}-01`;
  return { contribuyenteId: safe, startDate, endDate };
}
