import { SecretClient } from '@azure/keyvault-secrets';
import { DefaultAzureCredential, ClientSecretCredential } from '@azure/identity';
import { config } from './config.js';
import { getAzureConfig as getStoredAzureConfig } from '../modules/azure-config/repository.js';

let keyVaultClient: SecretClient | null = null;

export async function getKeyVaultClient(): Promise<SecretClient | null> {
  if (keyVaultClient) {
    return keyVaultClient;
  }

  try {
    let credential;
    let keyVaultUrl = config.AZURE_KEY_VAULT_URL;

    // Try to get configuration from database first
    const storedConfig = await getStoredAzureConfig();
    if (storedConfig && storedConfig.isActive) {
      keyVaultUrl = storedConfig.keyVaultUrl;
      if (storedConfig.tenantId && storedConfig.clientId && storedConfig.clientSecret) {
        credential = new ClientSecretCredential(
          storedConfig.tenantId,
          storedConfig.clientId,
          storedConfig.clientSecret
        );
      }
    }

    // Fall back to environment variables if no stored config
    if (!credential && config.AZURE_TENANT_ID && config.AZURE_CLIENT_ID && config.AZURE_CLIENT_SECRET) {
      credential = new ClientSecretCredential(
        config.AZURE_TENANT_ID,
        config.AZURE_CLIENT_ID,
        config.AZURE_CLIENT_SECRET
      );
    }

    // Use DefaultAzureCredential as last resort
    if (!credential) {
      credential = new DefaultAzureCredential();
    }

    if (!keyVaultUrl) {
      return null;
    }

    keyVaultClient = new SecretClient(keyVaultUrl, credential);
    return keyVaultClient;
  } catch (error) {
    console.error('Failed to initialize Azure Key Vault client:', error);
    return null;
  }
}

export async function getAzureSecret(secretName: string): Promise<string | null> {
  const client = await getKeyVaultClient();
  if (!client) {
    return null;
  }

  try {
    const secret = await client.getSecret(secretName);
    return secret.value || null;
  } catch (error) {
    console.error(`Failed to get secret ${secretName} from Azure Key Vault:`, error);
    return null;
  }
}

export async function setAzureSecret(secretName: string, secretValue: string): Promise<boolean> {
  const client = await getKeyVaultClient();
  if (!client) {
    return false;
  }

  try {
    await client.setSecret(secretName, secretValue);
    return true;
  } catch (error) {
    console.error(`Failed to set secret ${secretName} in Azure Key Vault:`, error);
    return false;
  }
}

export async function deleteAzureSecret(secretName: string): Promise<boolean> {
  const client = await getKeyVaultClient();
  if (!client) {
    return false;
  }

  try {
    await client.beginDeleteSecret(secretName);
    return true;
  } catch (error) {
    console.error(`Failed to delete secret ${secretName} from Azure Key Vault:`, error);
    return false;
  }
}

export async function listAzureSecrets(): Promise<string[]> {
  const client = await getKeyVaultClient();
  if (!client) {
    return [];
  }

  try {
    const secrets: string[] = [];
    for await (const secretProperties of client.listPropertiesOfSecrets()) {
      if (secretProperties.name) {
        secrets.push(secretProperties.name);
      }
    }
    return secrets;
  } catch (error) {
    console.error('Failed to list secrets from Azure Key Vault:', error);
    return [];
  }
}
