import { NotificationAudience } from '@edr/types';

import { MaintenanceService } from './maintenance.service';

/**
 * The daily due-alert: a SCHEDULED item that crossed its km or date threshold
 * gets one BACKOFFICE notification, then is stamped so it isn't repeated.
 */
function makeService(due: Array<Record<string, unknown>>) {
  const update = jest.fn();
  const notify = jest.fn();
  const service = Object.create(MaintenanceService.prototype) as Record<string, unknown>;
  service.maintenanceRepository = { getUnnotifiedDue: jest.fn().mockResolvedValue(due) };
  service.scheduleRepository = { update };
  service.inbox = { notify };
  service.logger = { error: jest.fn() };
  return { service: service as unknown as MaintenanceService, update, notify };
}

describe('MaintenanceService.sendDueAlerts', () => {
  it('reports the km reason when the km threshold was crossed', async () => {
    const { service, notify, update } = makeService([
      {
        id: 'sched-1',
        vehicleId: 'v-1',
        plateNumber: 'ET-9875',
        maintenanceType: 'PREVENTIVE',
        description: 'Oil change',
        nextDueKm: 50000,
        nextDueDate: null,
        currentKm: 50200,
      },
    ]);

    await service.sendDueAlerts();

    expect(notify).toHaveBeenCalledWith(
      expect.objectContaining({
        audience: NotificationAudience.BACKOFFICE,
        title: 'Maintenance due — ET-9875',
        body: expect.stringContaining('driven 50200 km (due at 50000 km)'),
      }),
    );
    expect(update).toHaveBeenCalledWith('sched-1', { dueNotifiedAt: expect.any(Date) });
  });

  it('reports the date reason when only the due date has passed', async () => {
    const { service, notify } = makeService([
      {
        id: 'sched-2',
        vehicleId: 'v-2',
        plateNumber: 'AA-8642',
        maintenanceType: 'INSPECTION',
        description: 'Annual inspection',
        nextDueKm: null,
        nextDueDate: new Date('2026-01-01'),
        currentKm: 1000,
      },
    ]);

    await service.sendDueAlerts();

    expect(notify).toHaveBeenCalledWith(
      expect.objectContaining({ body: expect.stringContaining('due 1/1/2026') }),
    );
  });

  it('does nothing when nothing is due', async () => {
    const { service, notify, update } = makeService([]);

    await service.sendDueAlerts();

    expect(notify).not.toHaveBeenCalled();
    expect(update).not.toHaveBeenCalled();
  });
});
