import { BadRequestException } from '@nestjs/common';
import { BookingTransitionService } from './booking-transition.service';

/**
 * Focused tests for the clearance 100%-approved gate in finalizeClearance.
 * Uses minimal stubs for the service's collaborators.
 */
describe('BookingTransitionService — finalizeClearance gate', () => {
  const booking = {
    id: 'b-1',
    status: 'DOCUMENTS_UNDER_REVIEW',
    tradeDirection: 'IMPORT',
    freightType: 'CONTAINER',
    serviceType: { includesCustoms: false }, // no output set → only the input gate
  };

  // Input set has two required docs.
  const inputSetting = {
    code: 'clearance_import_container_without_customs',
    fields: [
      { fileKey: 'commercial_invoice', isRequired: true },
      { fileKey: 'packing_list', isRequired: true },
    ],
  };

  function makeService(reviews: Array<{ settingCode: string; fileKey: string; status: string }>) {
    const bookingsRepository = {
      findDocumentReviews: jest.fn().mockResolvedValue(reviews),
      update: jest.fn().mockResolvedValue({ id: 'b-1' }),
    };
    const bookingsService = {
      findById: jest.fn().mockResolvedValue(booking),
    };
    const fileUploadSettingsService = {
      getByCode: jest.fn().mockResolvedValue(inputSetting),
    };
    const filesService = { findByResource: jest.fn().mockResolvedValue([]) };

    const service = new BookingTransitionService(
      bookingsRepository as never,
      {} as never, // ruleEngineService
      {} as never, // pricingService
      {} as never, // contractService
      filesService as never,
      fileUploadSettingsService as never,
      {} as never, // bookingBatchService
      bookingsService as never,
    );
    return { service, bookingsRepository };
  }

  it('rejects when a required document is not APPROVED', async () => {
    const { service } = makeService([
      {
        settingCode: inputSetting.code,
        fileKey: 'commercial_invoice',
        status: 'APPROVED',
      },
      // packing_list is still PENDING (missing approval)
    ]);
    await expect(service.finalizeClearance('b-1')).rejects.toBeInstanceOf(
      BadRequestException,
    );
  });

  it('moves to CLEARANCE_READY when all required documents are APPROVED', async () => {
    const { service, bookingsRepository } = makeService([
      { settingCode: inputSetting.code, fileKey: 'commercial_invoice', status: 'APPROVED' },
      { settingCode: inputSetting.code, fileKey: 'packing_list', status: 'APPROVED' },
    ]);
    await service.finalizeClearance('b-1');
    expect(bookingsRepository.update).toHaveBeenCalledWith(
      'b-1',
      expect.objectContaining({ status: 'CLEARANCE_READY' }),
    );
  });
});
