import { Test } from '@nestjs/testing';
import { NotFoundException } from '@nestjs/common';
import { PositionsService } from './positions.service';
import { PrismaService } from '../prisma/prisma.service';

describe('PositionsService', () => {
  let service: PositionsService;
  let prisma: PrismaService;
  let countryId: bigint;
  let categoryId: bigint;
  const createdIds: bigint[] = [];

  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({
      providers: [PositionsService, PrismaService],
    }).compile();
    service = moduleRef.get(PositionsService);
    prisma = moduleRef.get(PrismaService);
    await prisma.onModuleInit();

    const stamp = Date.now();
    const c = await prisma.country.create({
      data: { countryName: `Pos Country ${stamp}` },
    });
    countryId = c.id;
    const cat = await prisma.category.create({
      data: { categoryName: `Pos Cat ${stamp}` },
    });
    categoryId = cat.id;
  });

  afterAll(async () => {
    if (createdIds.length) {
      await prisma.position.deleteMany({ where: { id: { in: createdIds } } });
    }
    await prisma.country.delete({ where: { id: countryId } });
    await prisma.category.delete({ where: { id: categoryId } });
    await prisma.onModuleDestroy();
  });

  it('should be defined', () => {
    expect(service).toBeDefined();
  });

  it('creates a position linked to country + category and returns joined names', async () => {
    const created = await service.create({
      indexVal: 1,
      countryId: Number(countryId),
      categoryId: Number(categoryId),
    });
    createdIds.push(created.id);

    expect(created.country?.countryName).toBeTruthy();
    expect(created.category?.categoryName).toBeTruthy();

    const fetched = await service.findOne(created.id);
    expect(fetched.country?.id).toBe(countryId);
    expect(fetched.category?.id).toBe(categoryId);
  });

  it('filters by countryId and categoryId', async () => {
    const list = await service.findAll({
      countryId,
      categoryId,
    });
    expect(list.length).toBeGreaterThan(0);
    expect(list.every((p) => p.countryId === countryId)).toBe(true);
    expect(list.every((p) => p.categoryId === categoryId)).toBe(true);
  });

  it('updates indexVal and disconnects country', async () => {
    const created = await service.create({
      indexVal: 5,
      countryId: Number(countryId),
    });
    createdIds.push(created.id);
    const updated = await service.update(created.id, {
      indexVal: 9,
      countryId: null,
    });
    expect(updated.indexVal).toBe(9);
    expect(updated.countryId).toBeNull();
  });

  it('throws NotFoundException for unknown country during create', async () => {
    await expect(
      service.create({ indexVal: 1, countryId: 99999999 }),
    ).rejects.toBeInstanceOf(NotFoundException);
  });

  it('deletes a position', async () => {
    const created = await service.create({ indexVal: 7 });
    await service.remove(created.id);
    const list = await service.findAll();
    expect(list.find((p) => p.id === created.id)).toBeUndefined();
  });
});
