import { LOCALE_MAP } from 'src/constants/locale';

import {
  formatLongPaymentDateMX,
  formatPaymentDateMX,
  getOfferExpirationInfo,
} from './formatters';

describe('formatPaymentDateMX', () => {
  const date = new Date(Date.UTC(2026, 4, 15, 12, 0, 0));

  it('formats short month in user locale', () => {
    const es = formatPaymentDateMX(date, LOCALE_MAP.es);
    const en = formatPaymentDateMX(date, LOCALE_MAP.en);

    expect(es).not.toBe(en);
    expect(es.toLowerCase()).toContain('may');
    expect(en).toContain('May');
  });

  it('falls back to es-MX when locale.code is undefined', () => {
    const fallback = formatPaymentDateMX(date, {} as Locale);
    const esMX = formatPaymentDateMX(date, { code: 'es-MX' } as Locale);

    expect(fallback).toBe(esMX);
  });
});

describe('formatLongPaymentDateMX', () => {
  const date = new Date(Date.UTC(2026, 4, 15, 12, 0, 0));

  it('formats long month in user locale', () => {
    const es = formatLongPaymentDateMX(date, LOCALE_MAP.es);
    const en = formatLongPaymentDateMX(date, LOCALE_MAP.en);

    expect(es).not.toBe(en);
    expect(es.toLowerCase()).toContain('mayo');
    expect(en).toContain('May');
  });

  it('falls back to es-MX when locale.code is undefined', () => {
    const fallback = formatLongPaymentDateMX(date, {} as Locale);
    const esMX = formatLongPaymentDateMX(date, { code: 'es-MX' } as Locale);

    expect(fallback).toBe(esMX);
  });
});

describe('getOfferExpirationInfo', () => {
  const now = new Date('2026-05-19T12:00:00Z');

  it('returns null when expiresAt is undefined', () => {
    expect(getOfferExpirationInfo(undefined, now)).toBeNull();
  });

  it('returns null when the offer is already expired', () => {
    expect(getOfferExpirationInfo('2026-05-19T11:00:00Z', now)).toBeNull();
  });

  it('returns "today" when less than 24h remain', () => {
    expect(getOfferExpirationInfo('2026-05-20T11:59:59Z', now)).toEqual({
      kind: 'today',
    });
  });

  it('returns "tomorrow" when between 24h and 48h remain', () => {
    expect(getOfferExpirationInfo('2026-05-20T12:00:00Z', now)).toEqual({
      kind: 'tomorrow',
    });
    expect(getOfferExpirationInfo('2026-05-21T11:59:59Z', now)).toEqual({
      kind: 'tomorrow',
    });
  });

  it('returns "days" with ceil-day count when 48h or more remain', () => {
    expect(getOfferExpirationInfo('2026-05-21T12:00:00Z', now)).toEqual({
      kind: 'days',
      count: 2,
    });
    expect(getOfferExpirationInfo('2026-05-29T12:00:00Z', now)).toEqual({
      kind: 'days',
      count: 10,
    });
  });

  it('ceils fractional-hour remainders up to the next day', () => {
    expect(getOfferExpirationInfo('2026-05-21T13:00:00Z', now)).toEqual({
      kind: 'days',
      count: 3,
    });
  });
});
