/// <reference path="./.sst/platform/config.d.ts" />

const APP_CONFIG = {
  name: 'serverlessclaw',
  region: 'ap-southeast-2',
  architecture: 'arm64' as const,
  runtime: 'nodejs24.x',
  retention: '1 month' as const,
} as const;

function getAppRegion(): string {
  return process.env.AWS_REGION?.trim() || APP_CONFIG.region;
}

/**
 * SST v4 Platform Configuration for ServerlessClaw.
 * Defines the main application entry point, infrastructure providers, and modular resource setup.
 */
export default $config({
  app(input) {
    const region = getAppRegion();

    return {
      name: APP_CONFIG.name,
      removal: input?.stage === 'prod' ? 'retain' : 'remove', // Non-prod/local stages remove resources by default
      protect: ['prod'].includes(input?.stage),
      home: 'aws',
      providers: {
        aws: {
          region,
          version: '7.23.0',
        },
        ...(input?.stage !== 'local' ? { cloudflare: '6.13.0' } : {}),
      },
      defaults: {
        function: {
          architecture: APP_CONFIG.architecture,
          runtime: APP_CONFIG.runtime,
          environment: {
            AWS_PROFILE: '', // Clear profile to avoid conflict warning as SST injects static credentials
          },
          nodejs: {
            loader: {
              '.md': 'text',
            },
            esbuild: {
              // AWS SDK v3 is included in Lambda's managed Node.js 24.x runtime.
              // Externalizing it reduces bundle size by ~2-3MB per function.
              external: [
                '@aws-sdk/*',
                // Dashboard-only packages — safety net against accidental bundling
                'sonner',
                'react-markdown',
                'remark-gfm',
                'raw-loader',
                '@tailwindcss/postcss',
                'tailwindcss',
                'mqtt',
                'vitest',
                'playwright',
              ],
            },
          },
        },
      },
    };
  },
  async run() {
    // SST v4 Modular Infrastructure via Dynamic Imports
    const { createStorage } = await import('./packages/infra/storage.js');
    const { createBus } = await import('./packages/infra/bus.js');
    const { createDeployer } = await import('./packages/infra/deployer.js');
    const { createApi, configureApiRoutes } = await import('./packages/infra/api.js');
    const { createMCPServers } = await import('./packages/infra/mcp-servers.js');
    const { createAgents } = await import('./packages/infra/agents.js');
    const { createDashboard } = await import('./packages/infra/dashboard.js');

    // 1. Storage & Secrets
    const {
      memoryTable,
      traceTable,
      configTable,
      stagingBucket,
      knowledgeBucket,
      dataLakeBucket,
      secrets,
    } = createStorage();

    // 2. Multi-Agent Orchestration (EventBridge)
    const { bus, realtime, dlq } = createBus();

    // 3. The Deployer (CodeBuild)
    const { deployer, linkable: deployerLink } = createDeployer({
      stagingBucket,
      githubToken: secrets.GitHubToken,
    });

    // 4. API Instance (Created early for linking, routes added later)
    const { api } = createApi({
      memoryTable,
      traceTable,
      configTable,
      stagingBucket,
      knowledgeBucket,
      secrets,
      bus,
      deployer,
      deployerLink,
    });

    // 5. MCP Servers
    const mcpServers = createMCPServers({
      memoryTable,
      traceTable,
      configTable,
      stagingBucket,
      knowledgeBucket,
      secrets,
      bus,
      deployer,
      deployerLink,
      api, // Now available for linking if needed
    });
    const multiplexer = mcpServers.multiplexer;

    // 6. Sub-Agents (Handlers & Logic)
    const agentResources = createAgents(
      {
        memoryTable,
        traceTable,
        configTable,
        stagingBucket,
        knowledgeBucket,
        dataLakeBucket,
        secrets,
        bus,
        deployer,
        deployerLink,
        realtime,
        dlq,
        api, // Linkable API instance
        multiplexer,
      },
      mcpServers
    );

    // 7. API Routes (Configured after agents exist)
    configureApiRoutes(api, {
      memoryTable,
      traceTable,
      configTable,
      stagingBucket,
      knowledgeBucket,
      secrets,
      bus,
      deployer,
      deployerLink,
      agents: agentResources,
    });

    // 8. ClawCenter (Next.js 16)
    const { dashboard } = createDashboard({
      memoryTable,
      traceTable,
      configTable,
      stagingBucket,
      knowledgeBucket,
      secrets,
      bus,
      deployer,
      deployerLink,
      api,
      realtime,
      multiplexer,
      heartbeatHandler: agentResources.heartbeatHandler,
      schedulerRole: agentResources.schedulerRole,
    });

    // 9. Integration Stacks (GitHub, etc.)
    const { createGitHubStack } = await import('./packages/integration-github/stack.js');
    const githubResources = createGitHubStack({ bus, dlq });

    // 10. Billing & Cost Alerts ($5/day Daily Budget)
    const { createBilling } = await import('./packages/infra/billing.js');
    const { billingTopic } = createBilling();

    // 11. Multi-Region Operator Scaling (VX-4.2)
    const { createMultiRegionScaling } = await import('./packages/infra/multi-region.js');
    const multiRegion = createMultiRegionScaling({
      memoryTable,
      traceTable,
      configTable,
      stagingBucket,
      knowledgeBucket,
      secrets,
      bus,
      deployer,
      deployerLink,
      api,
    });

    return {
      apiUrl: api.url,
      dashboardUrl: dashboard.url,
      billingTopicArn: billingTopic?.arn,
      githubBucket: githubResources.githubBucket.name,
      regionSyncQueueUrl: multiRegion.regionSyncQueue.url,
    };
  },
});
