import { getContainer } from '../../lib/cosmos-init.js';
import { productId } from '../../lib/config.js';
import { randomBytes, createCipheriv, createDecipheriv } from 'crypto';
import type { AzureConfig, CreateAzureConfig, UpdateAzureConfig } from './types.js';

const AZURE_CONFIG_CONTAINER = 'azure-config';
const ENCRYPTION_KEY = process.env.ENCRYPTION_KEY || 'default-encryption-key-change-in-production';
const ALGORITHM = 'aes-256-cbc';

function encrypt(text: string): string {
  const iv = randomBytes(16);
  const key = Buffer.from(ENCRYPTION_KEY.padEnd(32, '0').substring(0, 32));
  const cipher = createCipheriv(ALGORITHM, key, iv);
  let encrypted = cipher.update(text, 'utf8');
  encrypted = Buffer.concat([encrypted, cipher.final()]);
  return Buffer.concat([iv, encrypted]).toString('base64');
}

function decrypt(encryptedText: string): string {
  const buffer = Buffer.from(encryptedText, 'base64');
  const iv = buffer.subarray(0, 16);
  const encrypted = buffer.subarray(16);
  const key = Buffer.from(ENCRYPTION_KEY.padEnd(32, '0').substring(0, 32));
  const decipher = createDecipheriv(ALGORITHM, key, iv);
  let decrypted = decipher.update(encrypted);
  decrypted = Buffer.concat([decrypted, decipher.final()]);
  return decrypted.toString('utf8');
}

export async function createAzureConfig(data: CreateAzureConfig): Promise<AzureConfig> {
  const now = new Date().toISOString();
  const encryptedClientSecret = encrypt(data.clientSecret);

  const config: AzureConfig = {
    id: `azure-config-${Date.now()}`,
    tenantId: data.tenantId,
    clientId: data.clientId,
    clientSecret: encryptedClientSecret,
    keyVaultUrl: data.keyVaultUrl,
    isActive: data.isActive !== undefined ? data.isActive : true,
    updatedAt: now,
    productId,
  };

  await getContainer(AZURE_CONFIG_CONTAINER as any).items.create(config);
  return config;
}

export async function getAzureConfig(): Promise<AzureConfig | null> {
  const query = 'SELECT * FROM c WHERE c.productId = @productId AND c.isActive = true';
  const parameters = [{ name: '@productId', value: productId }];

  try {
    const { resources } = await getContainer(AZURE_CONFIG_CONTAINER as any)
      .items.query({ query, parameters })
      .fetchAll();

    if (resources.length > 0) {
      const config = resources[0] as any;
      return {
        ...config,
        clientSecret: decrypt(config.clientSecret),
      };
    }
    return null;
  } catch {
    return null;
  }
}

export async function updateAzureConfig(id: string, updates: UpdateAzureConfig): Promise<AzureConfig | null> {
  const existing = await getAzureConfig();
  if (!existing || existing.id !== id) {
    return null;
  }

  const now = new Date().toISOString();
  let clientSecret = existing.clientSecret;

  if (updates.clientSecret !== undefined) {
    clientSecret = encrypt(updates.clientSecret);
  }

  const updated: AzureConfig = {
    ...existing,
    ...updates,
    clientSecret,
    updatedAt: now,
  };

  await getContainer(AZURE_CONFIG_CONTAINER as any).item(id).replace(updated);
  return updated;
}

export async function deleteAzureConfig(id: string): Promise<boolean> {
  try {
    await getContainer(AZURE_CONFIG_CONTAINER as any).item(id).delete();
    return true;
  } catch {
    return false;
  }
}

export async function testAzureConnection(): Promise<{ success: boolean; error?: string }> {
  const config = await getAzureConfig();
  if (!config) {
    return { success: false, error: 'No Azure configuration found' };
  }

  try {
    const { getKeyVaultClient } = await import('../../lib/azure-keyvault.js');
    const client = getKeyVaultClient();
    if (!client) {
      return { success: false, error: 'Failed to initialize Azure Key Vault client' };
    }

    // Try to list secrets to test connection
    const { listAzureSecrets } = await import('../../lib/azure-keyvault.js');
    await listAzureSecrets();

    return { success: true };
  } catch (error) {
    return { success: false, error: String(error) };
  }
}
