import { Test, TestingModule } from '@nestjs/testing';
import { SeatsService } from './seats.service';
import { PrismaService } from '../../common/prisma.service';
import { ConflictException } from '@nestjs/common';

describe('SeatsService - Auto Assign', () => {
  let service: SeatsService;
  let prisma: PrismaService;

  const mockPrisma = {
    seat: {
      findMany: jest.fn(),
      updateMany: jest.fn(),
    },
  };

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [
        SeatsService,
        { provide: PrismaService, useValue: mockPrisma },
      ],
    }).compile();

    service = module.get<SeatsService>(SeatsService);
    prisma = module.get<PrismaService>(PrismaService);
    jest.clearAllMocks();
  });

  describe('autoAssignSeats', () => {
    it('should assign contiguous seats in same row', async () => {
      const mockSeats = [
        { id: 'seat-1', coachId: 'coach-1', row: 1, col: 'A' },
        { id: 'seat-2', coachId: 'coach-1', row: 1, col: 'B' },
        { id: 'seat-3', coachId: 'coach-1', row: 1, col: 'C' },
        { id: 'seat-4', coachId: 'coach-1', row: 2, col: 'A' },
      ];

      mockPrisma.seat.findMany.mockResolvedValue(mockSeats);

      const result = await service.autoAssignSeats('trip-1', 2, 'ECONOMY_REGULAR');

      expect(result).toHaveLength(2);
      expect(result).toEqual(['seat-1', 'seat-2']);
    });

    it('should throw error if not enough seats available', async () => {
      mockPrisma.seat.findMany.mockResolvedValue([
        { id: 'seat-1', coachId: 'coach-1', row: 1, col: 'A' },
      ]);

      await expect(
        service.autoAssignSeats('trip-1', 3, 'ECONOMY_REGULAR'),
      ).rejects.toThrow(ConflictException);
    });

    it('should respect eligibility filter', async () => {
      const mockSeats = [
        { id: 'seat-1', coachId: 'coach-1', row: 1, col: 'A', eligibility: 'ACCESSIBLE' },
        { id: 'seat-2', coachId: 'coach-1', row: 1, col: 'B', eligibility: 'ACCESSIBLE' },
      ];

      mockPrisma.seat.findMany.mockResolvedValue(mockSeats);

      const result = await service.autoAssignSeats('trip-1', 2, 'ECONOMY_REGULAR');

      expect(result).toHaveLength(2);
    });

    it('should assign single seat', async () => {
      const mockSeats = [
        { id: 'seat-1', coachId: 'coach-1', row: 1, col: 'A' },
      ];

      mockPrisma.seat.findMany.mockResolvedValue(mockSeats);

      const result = await service.autoAssignSeats('trip-1', 1, 'ECONOMY_REGULAR');

      expect(result).toEqual(['seat-1']);
    });
  });
});
