import { CosmosClient } from '@azure/cosmos';
import { config } from './config.js';

// Local Cosmos client singleton (replaces @bytelyst/cosmos)
let cosmosClient: CosmosClient | null = null;
const containers = new Map<string, any>();
let isInitialized = false;
let initializationError: Error | null = null;

const containerDefinitions = [
  {
    id: 'services',
    partitionKey: '/id',
  },
  {
    id: 'deployments',
    partitionKey: '/id',
  },
  {
    id: 'audit-logs',
    partitionKey: '/id',
  },
  {
    id: 'migrations',
    partitionKey: '/id',
  },
  {
    id: 'backups',
    partitionKey: '/id',
  },
  {
    id: 'env-vars',
    partitionKey: '/id',
  },
  {
    id: 'azure-config',
    partitionKey: '/id',
  },
] as const;

function getCosmosClient(endpoint?: string, key?: string): CosmosClient {
  if (!cosmosClient) {
    cosmosClient = new CosmosClient({
      endpoint: endpoint || config.COSMOS_ENDPOINT,
      key: key || config.COSMOS_KEY,
    });
  }
  return cosmosClient;
}

async function getDatabase(databaseName: string, endpoint?: string, key?: string) {
  const client = getCosmosClient(endpoint, key);
  const databaseResponse = await client.databases.createIfNotExists({
    id: databaseName,
  });
  return databaseResponse.database;
}

async function getOrCreateContainer(database: any, containerDef: { id: string; partitionKey: string }) {
  const containerResponse = await database.containers.createIfNotExists({
    id: containerDef.id,
    partitionKey: { paths: [containerDef.partitionKey] },
  });
  return containerResponse.container;
}

export async function initializeContainers(endpoint?: string, key?: string) {
  try {
    const database = await getDatabase(config.COSMOS_DATABASE, endpoint, key);

    for (const containerDef of containerDefinitions) {
      const container = await getOrCreateContainer(database, containerDef);
      containers.set(containerDef.id, container);
    }

    isInitialized = true;
    initializationError = null;
  } catch (error) {
    isInitialized = false;
    initializationError = error as Error;
    console.error('Failed to initialize Cosmos containers:', error);
    throw error;
  }
}

export async function reinitializeContainers(endpoint: string, key: string) {
  // Reset the client and containers
  cosmosClient = null;
  containers.clear();

  // Reinitialize with new credentials
  await initializeContainers(endpoint, key);
}

export function getContainer(name: 'services' | 'deployments' | 'audit-logs' | 'migrations' | 'backups' | 'env-vars' | 'azure-config') {
  const container = containers.get(name);
  if (!container) {
    throw new Error(`Container ${name} not found. Make sure initializeContainers() has been called.`);
  }
  return container;
}

export function getCosmosStatus() {
  return {
    isInitialized,
    error: initializationError?.message || null,
  };
}
