// Express.js API Gateway Application

import express, { Express } from 'express';
import cors from 'cors';
import helmet from 'helmet';
import swaggerUi from 'swagger-ui-express';
import swaggerJsdoc from 'swagger-jsdoc';
import { zeroTrustAuthMiddleware, optionalAuthMiddleware } from './middleware/auth.middleware';
import { dynamicRateLimitMiddleware } from './middleware/rate-limit.middleware';
import { errorHandler } from './middleware/error.middleware';
import { auditLogMiddleware } from './middleware/audit.middleware';
import { validateEnvironment } from '@/shared/config/env-validator';
import { logger } from '@/infrastructure/monitoring/logger';
import { tracingMiddleware } from '@/infrastructure/monitoring/tracing.middleware';

// Validate environment variables at startup (fail fast)
try {
  validateEnvironment();
  logger.info('Environment validation passed');
} catch (error) {
  logger.error('Environment validation failed', {
    error: error instanceof Error ? error.message : 'Unknown error',
  });
  process.exit(1);
}

// Import route handlers (will be created)
// import paymentRoutes from '@/core/payments/payment.routes';
// import fxRoutes from '@/core/fx/fx.routes';
// import cbdcRoutes from '@/core/cbdc/cbdc.routes';
// import ledgerRoutes from '@/core/ledger/ledger.routes';
// import accountRoutes from '@/core/accounts/account.routes';

// Volume II routes
import constitutionRoutes from '@/core/governance/constitution/constitution.routes';
import sriRoutes from '@/core/risk/sri/sri.routes';
import isnRoutes from '@/core/settlement/isn/isn.routes';
import regtechRoutes from '@/core/compliance/regtech/regtech.routes';
import operationsRoutes from '@/core/operations/operations.routes';

// Volume III routes
import gssRoutes from '@/core/settlement/gss/gss.routes';
import cimRoutes from '@/core/cbdc/interoperability/cim.routes';
import ssuRoutes from '@/core/settlement/ssu/ssu.routes';
import cbdsRoutes from '@/core/commodities/cbds/cbds.routes';
import glpRoutes from '@/core/treasury/glp/glp.routes';
import crossChainRoutes from '@/core/settlement/cross-chain/cross-chain.routes';
import tezosUsdtzRoutes from '@/core/defi/tezos-usdtz/tezos-usdtz.routes';
import sireRoutes from '@/core/settlement/sire/sire.routes';

// Volume V routes
import gbigRoutes from '@/core/identity/gbig/gbig.routes';
import sareRoutes from '@/core/risk/sare/sare.routes';
import gctfRoutes from '@/core/cbdc/tokenomics/gctf.routes';
import diasRoutes from '@/core/governance/arbitration/dias.routes';

// Volume VII routes
import gpnRoutes from '@/core/payments/gpn/gpn.routes';
import mrtgsRoutes from '@/core/settlement/m-rtgs/mrtgs.routes';
import sciRoutes from '@/infrastructure/sovereign-cloud/sci.routes';
import zkCbdcRoutes from '@/core/cbdc/zk-validation/zk-cbdc.routes';
import ariRoutes from '@/core/compliance/ari/ari.routes';
import casoRoutes from '@/core/settlement/caso/caso.routes';
import dscnRoutes from '@/core/compliance/dscn/dscn.routes';
import mlsRoutes from '@/core/ledger/meta-ledger/mls.routes';

// Volume VI routes
import udfoRoutes from '@/core/ontology/udfo/udfo.routes';
import sdipRoutes from '@/core/identity/sdip/sdip.routes';
import grhsRoutes from '@/core/compliance/grhs/grhs.routes';
import gaseRoutes from '@/core/compliance/gase/gase.routes';
import waplRoutes from '@/core/compliance/wapl/wapl.routes';
import alpsRoutes from '@/core/treasury/alps/alps.routes';

// Volume VIII routes
import dcdcRoutes from '@/core/security/dcdc/dcdc.routes';
import psgRoutes from '@/core/settlement/psg/psg.routes';
import dscmRoutes from '@/infrastructure/compute/dscm-x/dscm.routes';
import cbdcGovernanceRoutes from '@/core/cbdc/governance/cbdc-governance.routes';
import gqlRoutes from '@/core/ledger/gql/gql.routes';
import simulationRoutes from '@/core/simulation/afcss/simulation.routes';
import sstmRoutes from '@/core/security/sstm/sstm.routes';

// Volume IX routes
import gsdsRoutes from '@/core/derivatives/gsds/gsds.routes';
import ispRoutes from '@/core/settlement/isp/isp.routes';
import beieRoutes from '@/core/behavioral/beie/beie.routes';
import snfnRoutes from '@/core/treasury/snfn/snfn.routes';
import mrliRoutes from '@/core/ledger/mrli/mrli.routes';
import asssRoutes from '@/core/simulation/asss/asss.routes';

// Volume XI routes
import scdcRoutes from '@/core/governance/scdc/scdc.routes';
import gmmtRoutes from '@/core/monetary/gmmt/gmmt.routes';
import tlpRoutes from '@/core/treasury/tlp/tlp.routes';
import uhemRoutes from '@/core/economics/uhem/uhem.routes';
import ossmRoutes from '@/core/settlement/ossm/ossm.routes';
import multiverseStabilityRoutes from '@/core/fx/multiverse-stability/multiverse-stability.routes';
import qtaeRoutes from '@/core/governance/qtae/qtae.routes';

// Volume XIII routes
import hsmnRoutes from '@/core/governance/hsmn/hsmn.routes';
import udaeRoutes from '@/core/fx/udae/udae.routes';
import tmfplRoutes from '@/core/fx/tmfpl/tmfpl.routes';
import climRoutes from '@/core/ledger/clim/clim.routes';
import sgleRoutes from '@/core/treasury/sgle/sgle.routes';
import mrecpRoutes from '@/core/economics/mrecp/mrecp.routes';
import proeRoutes from '@/core/governance/proe/proe.routes';

// Volume XIV routes
import tcmpRoutes from '@/core/monetary/tcmp/tcmp.routes';
import ilieRoutes from '@/core/identity/ilie/ilie.routes';
import shasRoutes from '@/core/settlement/shas/shas.routes';
import rssckRoutes from '@/core/contracts/rssck/rssck.routes';
import sbavRoutes from '@/core/valuation/sbav/sbav.routes';
import eeiRoutes from '@/core/economics/eei/eei.routes';
import uprmfRoutes from '@/core/monetary/uprmf/uprmf.routes';
import gatewayRoutes from '@/core/gateway/routes/gateway.routes';

// Special Sub-Volumes routes
import gasRoutes from '@/core/settlement/gas/gas.routes';
import gruRoutes from '@/core/monetary/gru/gru.routes';
import metaverseRoutes from '@/core/metaverse/metaverse.routes';
import gpuEdgeRoutes from '@/infrastructure/compute/gpu-edge/gpu-edge.routes';
import quantumProxyRoutes from '@/infrastructure/quantum/proxy/quantum-proxy.routes';
import gapAuditRoutes from '@/core/audit/gap-engine/gap-audit.routes';

// Admin Console routes
import dbisAdminRoutes from '@/core/admin/dbis-admin/dbis-admin.routes';
import scbAdminRoutes from '@/core/admin/scb-admin/scb-admin.routes';

// IRU Marketplace routes
import iruMarketplaceRoutes from '@/integration/api-gateway/routes/iru-marketplace.routes';
import iruPortalRoutes from '@/integration/api-gateway/routes/iru-portal.routes';

// Exchange integrations
import cryptoComOtcRoutes from '@/core/exchange/crypto-com-otc/crypto-com-otc.routes';
import exchangeRoutes from '@/core/exchange/exchange.routes';

// Volume X routes
import msgfRoutes from '@/core/governance/msgf/msgf.routes';
import umapRoutes from '@/core/monetary/umap/umap.routes';
import nceRoutes from '@/core/consensus/nce/nce.routes';
import faceRoutes from '@/core/cbdc/face/face.routes';
import csseRoutes from '@/core/settlement/csse/csse.routes';
import ilcRoutes from '@/core/ledger/ilc/ilc.routes';

const app: Express = express();

// Behind NPM / load balancer: set TRUST_PROXY=1 so rate limits and req.ip use the client address
if (process.env.TRUST_PROXY === '1' || process.env.TRUST_PROXY === 'true') {
  app.set('trust proxy', 1);
}

// Security middleware
app.use(helmet());

// Distributed tracing middleware (before other middleware)
app.use(tracingMiddleware);

// CORS configuration
const allowedOrigins = process.env.ALLOWED_ORIGINS?.split(',').map((o) => o.trim()) || [];
if (process.env.NODE_ENV === 'production' && (allowedOrigins.length === 0 || allowedOrigins.includes('*'))) {
  throw new Error(
    'ALLOWED_ORIGINS must be set in production and cannot contain wildcard (*)'
  );
}

app.use(
  cors({
    origin:
      allowedOrigins.length > 0 && !allowedOrigins.includes('*')
        ? allowedOrigins
        : process.env.NODE_ENV === 'development'
        ? '*'
        : false,
    credentials: true,
  })
);

// Body parsing
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true, limit: '10mb' }));

// Request logging
app.use(auditLogMiddleware);

// Swagger/OpenAPI documentation
const swaggerOptions = {
  definition: {
    openapi: '3.0.0',
    info: {
      title: 'DBIS Core Banking System API',
      version: '1.0.0',
      description: 'Sovereign-grade financial infrastructure API',
      contact: {
        name: 'DBIS',
      },
    },
    servers: [
      {
        url: `http://localhost:${process.env.PORT || 3000}`,
        description: 'Development server',
      },
    ],
    components: {
      securitySchemes: {
        SovereignToken: {
          type: 'http',
          scheme: 'bearer',
          bearerFormat: 'SOV-TOKEN',
          description: 'Sovereign Identity Token (SIT)',
        },
      },
    },
    security: [
      {
        SovereignToken: [],
      },
    ],
  },
  apis: ['./src/**/*.routes.ts', './src/**/*.ts'],
};

const swaggerSpec = swaggerJsdoc(swaggerOptions);
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));

// Top-level service metadata so API hostnames return a clean 200 at "/".
app.get('/', (req, res) => {
  res.status(200).json({
    service: 'dbis-core-banking-system',
    status: 'healthy',
    version: '1.0.0',
    docs: '/api-docs',
    health: '/health',
  });
});

// Health check endpoints (no auth required)
app.get(['/health', '/v1/health'], async (req, res) => {
  const healthStatus: {
    status: string;
    timestamp: string;
    version: string;
    database?: string;
    hsm?: string;
  } = {
    status: 'healthy',
    timestamp: new Date().toISOString(),
    version: '1.0.0',
  };

  // Check database connectivity
  try {
    const prisma = (await import('@/shared/database/prisma')).default;
    await prisma.$queryRaw`SELECT 1`;
    healthStatus.database = 'connected';
  } catch (error) {
    healthStatus.status = 'degraded';
    healthStatus.database = 'disconnected';
  }

  // Check HSM availability (if enabled)
  if (process.env.HSM_ENABLED === 'true') {
    try {
      const { hsmService } = await import('@/integration/hsm/hsm.service');
      // Simple check - in production, this would verify HSM connectivity
      healthStatus.hsm = 'available';
    } catch (error) {
      healthStatus.status = 'degraded';
      healthStatus.hsm = 'unavailable';
    }
  }

  const statusCode = healthStatus.status === 'healthy' ? 200 : 503;
  res.status(statusCode).json(healthStatus);
});

// IRU Marketplace routes (public endpoints, auth handled per-route)
app.use('/api/v1/iru/marketplace', iruMarketplaceRoutes);

// IRU Portal routes (authenticated)
app.use('/api/v1/iru/portal', iruPortalRoutes);

// IRU Deployment routes (authenticated)
import iruDeploymentRoutes from '@/integration/api-gateway/routes/iru-deployment.routes';
app.use('/api/v1/iru/deployment', iruDeploymentRoutes);

// IRU Qualification routes (admin only)
import iruQualificationRoutes from '@/integration/api-gateway/routes/iru-qualification.routes';
app.use('/api/v1/iru/qualification', iruQualificationRoutes);

// IRU Agreement routes (authenticated)
import iruAgreementRoutes from '@/integration/api-gateway/routes/iru-agreement.routes';
app.use('/api/v1/iru/agreement', iruAgreementRoutes);

// IRU Payment routes (authenticated)
import iruPaymentRoutes from '@/integration/api-gateway/routes/iru-payment.routes';
app.use('/api/v1/iru/payment', iruPaymentRoutes);

// IRU Notification routes (authenticated)
import iruNotificationRoutes from '@/integration/api-gateway/routes/iru-notification.routes';
app.use('/api/v1/iru/notifications', iruNotificationRoutes);

// IRU Metrics routes (public for Prometheus)
import iruMetricsRoutes from '@/integration/api-gateway/routes/iru-metrics.routes';
app.use('/api/v1/iru/metrics', iruMetricsRoutes);

// Admin Central API (service-to-service: audit append, permission check, audit query)
// Auth: X-Admin-Central-Key. Must be registered before /api auth so it uses its own middleware.
import adminCentralRoutes from '@/integration/api-gateway/routes/admin-central.routes';
app.use('/api/admin/central', adminCentralRoutes);

// API routes (protected)
// All API routes require authentication
app.use('/api', zeroTrustAuthMiddleware);
app.use('/api', dynamicRateLimitMiddleware);

// Register route handlers
import ledgerRoutes from '@/core/ledger/ledger.routes';
import accountRoutes from '@/core/accounts/account.routes';
import paymentRoutes from '@/core/payments/payment.routes';
import fxRoutes from '@/core/fx/fx.routes';
import nostroVostroRoutes from '@/core/nostro-vostro/nostro-vostro.routes';
// import chartOfAccountsRoutes from '@/core/accounting/chart-of-accounts.routes';

app.use('/api/ledger', ledgerRoutes);
app.use('/api/accounts', accountRoutes);
app.use('/api/payments', paymentRoutes);
app.use('/api/fx', fxRoutes);
app.use('/api/v1/crypto-com-otc', cryptoComOtcRoutes);
app.use('/api/v1/exchange', exchangeRoutes);
app.use('/api/v1/nostro-vostro', nostroVostroRoutes);
// app.use('/api/accounting/chart-of-accounts', chartOfAccountsRoutes);

// Gateway Microservices routes
app.use('/api/v1/gateway', gatewayRoutes);

// Volume II routes
app.use('/api/constitution', constitutionRoutes);
app.use('/api/sri', sriRoutes);
app.use('/api/isn', isnRoutes);
app.use('/api/regtech', regtechRoutes);
app.use('/api/operations', operationsRoutes);

// Volume III routes
app.use('/api/v1/gss', gssRoutes);
app.use('/api/v1/cim', cimRoutes);
app.use('/api/v1/ssu', ssuRoutes);
app.use('/api/v1/cbds', cbdsRoutes);
app.use('/api/v1/glp', glpRoutes);
app.use('/api/v1/cross-chain', crossChainRoutes);
app.use('/api/v1/routes', tezosUsdtzRoutes);

// AS4 Settlement routes
import as4GatewayRoutes from '@/core/settlement/as4/as4.routes';
import as4MemberDirectoryRoutes from '@/core/settlement/as4-settlement/member-directory/member-directory.routes';
import as4SettlementRoutes from '@/core/settlement/as4-settlement/as4-settlement.routes';
import as4MetricsRoutes from '@/core/settlement/as4/as4-metrics.routes';
app.use('/api/v1/as4/gateway', as4GatewayRoutes);
app.use('/api/v1/as4/directory', as4MemberDirectoryRoutes);
app.use('/api/v1/as4/settlement', as4SettlementRoutes);
app.use('/api/v1/as4', as4MetricsRoutes); // Metrics endpoint (public for Prometheus)

// Volume V routes
app.use('/api/v1/gbig', gbigRoutes);
app.use('/api/v1/sare', sareRoutes);
app.use('/api/v1/gctf', gctfRoutes);
app.use('/api/v1/dias', diasRoutes);
app.use('/api/v1/mls', mlsRoutes);

// Volume IX routes
app.use('/api/v1/gsds', gsdsRoutes);
app.use('/api/v1/isp', ispRoutes);
app.use('/api/v1/beie', beieRoutes);
app.use('/api/v1/snfn', snfnRoutes);
app.use('/api/v1/mrli', mrliRoutes);
app.use('/api/v1/asss', asssRoutes);

// Volume VI routes
app.use('/api/v1/udfo', udfoRoutes);
app.use('/api/v1/sdip', sdipRoutes);
app.use('/api/v1/grhs', grhsRoutes);
app.use('/api/v1/gase', gaseRoutes);
app.use('/api/v1/wapl', waplRoutes);
app.use('/api/v1/alps', alpsRoutes);

// Volume VII routes
app.use('/api/v1/gpn', gpnRoutes);
app.use('/api/v1/m-rtgs', mrtgsRoutes);
app.use('/api/v1/sci', sciRoutes);
app.use('/api/v1/zk-cbdc', zkCbdcRoutes);
app.use('/api/v1/ari', ariRoutes);
app.use('/api/v1/caso', casoRoutes);
app.use('/api/v1/dscn', dscnRoutes);

// Volume VIII routes
app.use('/api/v1/dcdc', dcdcRoutes);
app.use('/api/v1/psg', psgRoutes);
app.use('/api/v1/dscm', dscmRoutes);
app.use('/api/v1/cbdc-governance', cbdcGovernanceRoutes);
app.use('/api/v1/gql', gqlRoutes);
app.use('/api/v1/simulation', simulationRoutes);
app.use('/api/v1/sstm', sstmRoutes);

// Volume X routes
app.use('/api/v1/msgf', msgfRoutes);
app.use('/api/v1/umap', umapRoutes);
app.use('/api/v1/nce', nceRoutes);
app.use('/api/v1/face', faceRoutes);
app.use('/api/v1/csse', csseRoutes);
app.use('/api/v1/ilc', ilcRoutes);

// Volume XI routes
app.use('/api/v1/scdc', scdcRoutes);
app.use('/api/v1/gmmt', gmmtRoutes);
app.use('/api/v1/tlp', tlpRoutes);
app.use('/api/v1/uhem', uhemRoutes);
app.use('/api/v1/ossm', ossmRoutes);
app.use('/api/v1/multiverse-stability', multiverseStabilityRoutes);
app.use('/api/v1/qtae', qtaeRoutes);

// Volume XIII routes
app.use('/api/v1/hsmn', hsmnRoutes);
app.use('/api/v1/udae', udaeRoutes);
app.use('/api/v1/tmfpl', tmfplRoutes);
app.use('/api/v1/clim', climRoutes);
app.use('/api/v1/sgle', sgleRoutes);
app.use('/api/v1/mrecp', mrecpRoutes);
app.use('/api/v1/proe', proeRoutes);

// Volume XIV routes
app.use('/api/v1/tcmp', tcmpRoutes);
app.use('/api/v1/ilie', ilieRoutes);
app.use('/api/v1/shas', shasRoutes);
app.use('/api/v1/rssck', rssckRoutes);
app.use('/api/v1/sbav', sbavRoutes);
app.use('/api/v1/eei', eeiRoutes);
app.use('/api/v1/uprmf', uprmfRoutes);

// Special Sub-Volumes routes
app.use('/api/gas', gasRoutes);
app.use('/api/gru', gruRoutes);
app.use('/api/metaverse', metaverseRoutes);
app.use('/api/gpu-edge', gpuEdgeRoutes);
app.use('/api/quantum-proxy', quantumProxyRoutes);
app.use('/api/gap-audit', gapAuditRoutes);

// Admin Console routes
app.use('/api/admin/dbis', dbisAdminRoutes);
app.use('/api/admin/scb', scbAdminRoutes);

// SolaceNet Capability Platform routes
import solacenetCapabilityRoutes from '@/core/solacenet/registry/capability-registry.routes';
import solacenetEntitlementRoutes from '@/core/solacenet/entitlements/entitlements.routes';
import solacenetPolicyRoutes from '@/core/solacenet/policy/policy-engine.routes';
import solacenetAuditRoutes from '@/core/solacenet/audit/audit-log.routes';
import solacenetLimitsRoutes from '@/core/solacenet/capabilities/limits/limits.routes';
import solacenetFeesRoutes from '@/core/solacenet/capabilities/fees/fees.routes';

app.use('/api/v1/solacenet/capabilities', solacenetCapabilityRoutes);
app.use('/api/v1/solacenet', solacenetEntitlementRoutes);
app.use('/api/v1/solacenet/policy', solacenetPolicyRoutes);
app.use('/api/v1/solacenet/audit', solacenetAuditRoutes);
app.use('/api/v1/solacenet/limits', solacenetLimitsRoutes);
app.use('/api/v1/solacenet/fees', solacenetFeesRoutes);

// SolaceNet Capability Packs
import solacenetPaymentRoutes from '@/core/solacenet/capabilities/payments/payment-gateway.routes';
import solacenetWalletRoutes from '@/core/solacenet/capabilities/wallets/wallet-accounts.routes';
import solacenetCardRoutes from '@/core/solacenet/capabilities/cards/card-issuing.routes';
import solacenetMobileMoneyRoutes from '@/core/solacenet/capabilities/mobile-money/mobile-money.routes';
import solacenetTokenizationRoutes from '@/core/solacenet/capabilities/tokenization/tokenization.routes';

app.use('/api/v1/solacenet/payments', solacenetPaymentRoutes);
app.use('/api/v1/solacenet/wallets', solacenetWalletRoutes);
app.use('/api/v1/solacenet/cards', solacenetCardRoutes);
app.use('/api/v1/solacenet/mobile-money', solacenetMobileMoneyRoutes);
app.use('/api/v1/solacenet/tokenization', solacenetTokenizationRoutes);

// Risk Rules Engine
import riskRulesRoutes from '@/core/risk/rules-engine.routes';
app.use('/api/v1/risk', riskRulesRoutes);

// Health check routes (public, no auth)
import healthRoutes from './routes/health.routes';
app.use('/health', healthRoutes);

// Metrics endpoint (public, for Prometheus)
import metricsRoutes from './routes/metrics.routes';
app.use('/', metricsRoutes);

// Error handling middleware (must be last)
app.use(errorHandler);

export default app;
