import { ClientesService } from "./clientes.service";

function createService(overrides: {
  localFindOne?: any;
  erpFindOne?: any;
} = {}) {
  const erpRepo = {
    findOne: jest.fn(async () => overrides.erpFindOne ?? null),
    save: jest.fn(async (data: any) => data),
    update: jest.fn(async () => ({ affected: 1 })),
    create: jest.fn((data: any) => data),
    delete: jest.fn(async () => ({ affected: 1 })),
  };

  const localRepo = {
    findOne: jest.fn(async () => overrides.localFindOne ?? null),
    create: jest.fn((data: any) => ({ ...data })),
    save: jest.fn(async (data: any) => ({ ...data })),
  };

  const getRepository = jest.fn((entity: any) =>
    entity?.name === "Cliente" ? erpRepo : localRepo,
  );

  const tenantAccessor: any = {
    repositoryFor: getRepository,
    runInTransaction: jest.fn(async (fn: any) => fn({ get: getRepository })),
  };

  const service = new ClientesService(tenantAccessor);
  return { service, erpRepo, localRepo };
}

describe("ClientesService.update — proteccion de maecli", () => {
  it("NO escribe en el ERP si la tarjeta es de un cliente real (no TLL-)", async () => {
    const erpCliente = {
      tarjeta: "0000123456",
      nombre: "Cliente Real",
      direccion: "Zona 1",
      telefono: "12345678",
      celular: null,
      nit: "1234567-8",
      email: null,
    };

    const { service, erpRepo } = createService({ erpFindOne: erpCliente });

    await service.update("0000123456", { nombre: "Editado desde taller" } as any);

    expect(erpRepo.save).not.toHaveBeenCalled();
  });

  it("SI escribe en el ERP (create) si la tarjeta es local (TLL-) y no existe aun", async () => {
    const localCliente = {
      tarjeta: "TLL-00000001",
      nombre: "Cliente Taller",
      direccion: "Zona 2",
      nit: "CF",
    };

    const { service, erpRepo } = createService({ localFindOne: localCliente });

    await service.update("TLL-00000001", { nombre: "Editado" } as any);

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

  it("usa update() parcial (no save() de la entidad completa) si la fila TLL- ya existe en el ERP", async () => {
    const localCliente = {
      tarjeta: "TLL-00000002",
      nombre: "Cliente Taller 2",
      direccion: "Zona 3",
      nit: "CF",
    };
    const erpExisting = {
      tarjeta: "TLL-00000002",
      nombre: "Cliente Taller 2 viejo",
      direccion: "Zona 3",
      nit: "CF",
    };

    const { service, erpRepo } = createService({
      localFindOne: localCliente,
      erpFindOne: erpExisting,
    });

    await service.update("TLL-00000002", { nombre: "Editado otra vez" } as any);

    expect(erpRepo.update).toHaveBeenCalledWith(
      { tarjeta: "TLL-00000002" },
      expect.not.objectContaining({ tarjeta: expect.anything() }),
    );
    expect(erpRepo.save).not.toHaveBeenCalled();
  });
});
