#!/usr/bin/env node

import { config } from 'dotenv';
import { AuthManager } from './auth/oauth.js';
import { MetaApiClient } from './client/meta-client.js';
import { RateLimiter } from './client/rate-limiter.js';
import {
  createMcpServer,
  connectServer,
  ToolRegistry,
  ModuleRegistry,
  createGatewayTool,
} from './server.js';

// Import Tier 1 (core) tool modules
import { registerAccountTools } from './tools/account.js';
import { registerCampaignTools } from './tools/campaigns.js';
import { registerAdSetTools } from './tools/ad-sets.js';
import { registerAdTools } from './tools/ads.js';

/**
 * Main entry point for Meta Ads MCP server
 */
async function main() {
  // Load environment variables
  config();

  const accessToken = process.env.META_ACCESS_TOKEN;
  const appId = process.env.META_APP_ID;
  const appSecret = process.env.META_APP_SECRET;
  const apiVersion = process.env.META_API_VERSION || 'v21.0';

  if (!accessToken) {
    console.error('Error: META_ACCESS_TOKEN environment variable is required');
    process.exit(1);
  }

  console.error('[MCP] Initializing Meta Ads MCP Server...');

  // Initialize auth and client
  const authManager = new AuthManager(accessToken, appId, appSecret);
  const rateLimiter = new RateLimiter(5); // Max 5 concurrent requests
  // Cache available for future use
  // const cache = new SimpleCache(1000, 300); // 1000 entries, 5 minute TTL
  const client = new MetaApiClient(authManager, { apiVersion }, rateLimiter);

  // Validate token on startup
  try {
    console.error('[MCP] Validating access token...');
    const tokenInfo = await authManager.validateToken();
    console.error(`[MCP] Token valid. User ID: ${tokenInfo.userId}, Expires: ${tokenInfo.expiresAt ? new Date(tokenInfo.expiresAt).toISOString() : 'never'}`);
    
    // Warn if token expires soon
    if (authManager.isTokenExpired(60)) {
      console.error('[MCP] WARNING: Access token expires within 1 hour. Consider refreshing.');
    }
  } catch (error) {
    console.error(`[MCP] Token validation failed: ${error instanceof Error ? error.message : String(error)}`);
    console.error('[MCP] Server will start but API calls may fail. Please check your META_ACCESS_TOKEN.');
  }

  // Create tool and module registries
  const toolRegistry = new ToolRegistry(client);
  const moduleRegistry = new ModuleRegistry(toolRegistry);

  // Register Tier 1 (core) modules - loaded immediately
  console.error('[MCP] Registering core modules (Tier 1)...');
  
  moduleRegistry.registerModule({
    category: 'account',
    tier: 'core',
    loaded: false,
    register: registerAccountTools,
  });

  moduleRegistry.registerModule({
    category: 'campaigns',
    tier: 'core',
    loaded: false,
    register: registerCampaignTools,
  });

  moduleRegistry.registerModule({
    category: 'adsets',
    tier: 'core',
    loaded: false,
    register: registerAdSetTools,
  });

  moduleRegistry.registerModule({
    category: 'ads',
    tier: 'core',
    loaded: false,
    register: registerAdTools,
  });

  // Load core modules immediately
  await moduleRegistry.loadModule('account');
  await moduleRegistry.loadModule('campaigns');
  await moduleRegistry.loadModule('adsets');
  await moduleRegistry.loadModule('ads');

  // Register Tier 2 (advanced) modules - lazy loaded via gateway tools
  console.error('[MCP] Registering advanced modules (Tier 2) as gateway tools...');

  // Analytics module (gateway)
  moduleRegistry.registerModule({
    category: 'analytics',
    tier: 'advanced',
    loaded: false,
    register: async (registry) => {
      // This would be implemented in src/tools/analytics.ts
      // For now, just a placeholder
      console.error('[MCP] Analytics module loaded (placeholder)');
      registry.registerTool({
        name: 'get_insights_placeholder',
        description: 'Placeholder for insights tool',
        inputSchema: require('zod').z.object({}),
        handler: async () => ({
          content: [{ type: 'text', text: 'Analytics module loaded but not yet implemented' }],
        }),
      });
    },
  });

  toolRegistry.registerTool(
    createGatewayTool(
      'analytics',
      moduleRegistry,
      'Load analytics and insights tools for campaign performance analysis'
    )
  );

  // Audiences module (gateway)
  moduleRegistry.registerModule({
    category: 'audiences',
    tier: 'advanced',
    loaded: false,
    register: async (registry) => {
      console.error('[MCP] Audiences module loaded (placeholder)');
      registry.registerTool({
        name: 'list_audiences_placeholder',
        description: 'Placeholder for audience tools',
        inputSchema: require('zod').z.object({}),
        handler: async () => ({
          content: [{ type: 'text', text: 'Audiences module loaded but not yet implemented' }],
        }),
      });
    },
  });

  toolRegistry.registerTool(
    createGatewayTool(
      'audiences',
      moduleRegistry,
      'Load audience management tools for custom audiences, lookalikes, and saved audiences'
    )
  );

  // Budget optimization module (gateway)
  moduleRegistry.registerModule({
    category: 'budget',
    tier: 'advanced',
    loaded: false,
    register: async (registry) => {
      console.error('[MCP] Budget module loaded (placeholder)');
      registry.registerTool({
        name: 'optimize_budget_placeholder',
        description: 'Placeholder for budget tools',
        inputSchema: require('zod').z.object({}),
        handler: async () => ({
          content: [{ type: 'text', text: 'Budget module loaded but not yet implemented' }],
        }),
      });
    },
  });

  toolRegistry.registerTool(
    createGatewayTool(
      'budget',
      moduleRegistry,
      'Load budget optimization tools for CBO management and budget recommendations'
    )
  );

  // Create and connect MCP server
  const server = createMcpServer(toolRegistry);
  
  // Graceful shutdown handling
  const shutdown = async () => {
    console.error('[MCP] Shutting down...');
    process.exit(0);
  };

  process.on('SIGINT', shutdown);
  process.on('SIGTERM', shutdown);

  // Connect to stdio transport
  await connectServer(server);

  // Log module status
  const moduleStatus = moduleRegistry.getModuleStatus();
  console.error('[MCP] Module status:', JSON.stringify(moduleStatus, null, 2));
  console.error(`[MCP] Registered ${toolRegistry.getTools().length} tools`);
  console.error('[MCP] Server ready!');
}

// Run the server
main().catch((error) => {
  console.error('[MCP] Fatal error:', error);
  process.exit(1);
});
