import { createCipheriv, randomBytes } from 'crypto';

const CLAVE = '0123456789abcdef0123456789abcdef'; // 32 chars
jest.mock('src/config', () => ({ envs: { aiEncryptionKey: '0123456789abcdef0123456789abcdef' } }));

import { AiConfigService } from './ai-config.service';

/** Cifra igual que el servicio, para simular una key guardada. */
function cifrar(texto: string): string {
  const iv = randomBytes(16);
  const cipher = createCipheriv('aes-256-cbc', Buffer.from(CLAVE, 'utf8'), iv);
  const enc = Buffer.concat([cipher.update(texto, 'utf8'), cipher.final()]);
  return `${iv.toString('hex')}:${enc.toString('hex')}`;
}

/** Prisma en memoria: configs IA por empresa y el árbol empresa → holding. */
function prismaFalso(configs: Record<string, any>, padres: Record<string, string | null>) {
  return {
    ai_empresa_config: {
      findUnique: async ({ where }: any) => configs[where.empresa_id] ?? null,
    },
    empresas: {
      findUnique: async ({ where }: any) => ({ parent_id: padres[where.id] ?? null }),
    },
  } as any;
}

describe('AiConfigService.getConfig · tiene_api_key', () => {
  const HOLDING = 'holding', EMPRESA = 'sucursal';

  it('con "Tokens de la plataforma" y key en el holding, la empresa tiene credencial usable', async () => {
    const svc = new AiConfigService(
      prismaFalso(
        {
          [HOLDING]: { empresa_id: HOLDING, proveedor: 'anthropic', modelo: 'claude-x', api_key_encrypted: cifrar('sk-holding') },
          [EMPRESA]: { empresa_id: EMPRESA, credencial_modo: 'PLATAFORMA', api_key_encrypted: null },
        },
        { [EMPRESA]: HOLDING, [HOLDING]: null },
      ),
    );
    const cfg = await svc.getConfig(EMPRESA);
    expect(cfg.tiene_api_key).toBe(true);
    expect(cfg.modelo_efectivo).toBe('claude-x');
    expect(cfg.api_key_encrypted).toBeUndefined(); // nunca sale la key
  });

  it('con "Tokens de la plataforma" pero el holding sin key, no hay credencial', async () => {
    const svc = new AiConfigService(
      prismaFalso(
        {
          [HOLDING]: { empresa_id: HOLDING, api_key_encrypted: null },
          [EMPRESA]: { empresa_id: EMPRESA, credencial_modo: 'PLATAFORMA', api_key_encrypted: null },
        },
        { [EMPRESA]: HOLDING, [HOLDING]: null },
      ),
    );
    expect((await svc.getConfig(EMPRESA)).tiene_api_key).toBe(false);
  });

  it('con key propia sigue mirando la de la empresa', async () => {
    const svc = new AiConfigService(
      prismaFalso(
        { [EMPRESA]: { empresa_id: EMPRESA, credencial_modo: 'PROPIA', api_key_encrypted: cifrar('sk-propia') } },
        { [EMPRESA]: null },
      ),
    );
    expect((await svc.getConfig(EMPRESA)).tiene_api_key).toBe(true);
  });
});
