import { ForbiddenException } from "@nestjs/common";
import { ProductosService } from "./productos.service";
import { ProductoLocal } from "./entities/producto-local.entity";

function createService(overrides: Record<string, any> = {}) {
  const localRepo = {
    findOne: jest.fn(async () => null),
    create: jest.fn((d: any) => d),
    save: jest.fn(async (d: any) => ({ ...d, plu: d.plu ?? "TLLP-00000001" })),
    createQueryBuilder: jest.fn(() => ({
      where: jest.fn().mockReturnThis(),
      andWhere: jest.fn().mockReturnThis(),
      orderBy: jest.fn().mockReturnThis(),
      take: jest.fn().mockReturnThis(),
      getMany: jest.fn(async () => []),
      getOne: jest.fn(async () => null),
    })),
    ...overrides.localRepo,
  };

  const erpRepo = {
    findOne: jest.fn(async () => null),
    ...overrides.erpRepo,
  };

  const tenantAccessor = {
    repositoryFor: jest.fn((entity: any) =>
      entity === ProductoLocal ? localRepo : erpRepo,
    ),
    ...overrides.tenantAccessor,
  };

  const maepluMirrorService = {
    insertIfMissing: jest.fn(async () => undefined),
    ...overrides.maepluMirrorService,
  };

  const tallerParametros = {
    getBooleanConFallback: jest.fn(async () => true),
    ...overrides.tallerParametros,
  };

  const service = new ProductosService(
    tenantAccessor as any,
    maepluMirrorService as any,
    tallerParametros as any,
  );

  return {
    service,
    localRepo,
    erpRepo,
    tenantAccessor,
    maepluMirrorService,
    tallerParametros,
  };
}

describe("ProductosService — gate de productos.permite_crear", () => {
  it("create() rechaza con ForbiddenException si el toggle está apagado", async () => {
    const tallerParametros = {
      getBooleanConFallback: jest.fn(async () => false),
    };
    const { service } = createService({ tallerParametros });

    await expect(
      service.create({ desclarga: "Aceite 5W30" } as any),
    ).rejects.toThrow(ForbiddenException);
    expect(tallerParametros.getBooleanConFallback).toHaveBeenCalledWith(
      "productos.permite_crear",
    );
  });

  it("update() rechaza con ForbiddenException si el toggle está apagado", async () => {
    const tallerParametros = {
      getBooleanConFallback: jest.fn(async () => false),
    };
    const { service } = createService({ tallerParametros });

    await expect(
      service.update("TLLP-1", { desclarga: "x" } as any),
    ).rejects.toThrow(ForbiddenException);
  });

  it("create() procede normalmente cuando el toggle está en true", async () => {
    const { service, localRepo } = createService();

    await service.create({ desclarga: "Aceite 5W30" } as any);

    expect(localRepo.save).toHaveBeenCalled();
  });
});
