import * as cdk from 'aws-cdk-lib';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import { Construct } from 'constructs';
import { config } from '../../config';

export interface MultiRegionVpcStackProps extends cdk.StackProps {
  accountStage: string;
  region: string;
}

interface CidrMap {
  [key: string]: {
    [region: string]: string;
  };
}

export class MultiRegionVpcStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props: MultiRegionVpcStackProps) {
    super(scope, id, props);

    const cidrMap: CidrMap = {
      staging: {
        'us-east-2': '10.2.0.0/16',
      },
      prod: {
        'us-east-2': '10.4.0.0/16',
        'eu-central-1': '10.5.0.0/16',
        'ap-southeast-1': '10.6.0.0/16',
      },
    };
    new cdk.CfnOutput(this, 'VpcCidr', {
      value: cidrMap[props.accountStage][props.region],
    });

    const sunoMainVpc = ec2.Vpc.fromLookup(this, 'SunoMainVpc', {
      vpcName: 'suno-main-vpc',
      region: 'us-east-2',
    });

    // VPC Configuration
    const multiRegionSunoMainVpc = new ec2.Vpc(this, 'MultiRegionVpc', {
      vpcName: 'multi-region-suno-main-vpc',
      cidr: cidrMap[props.accountStage][props.region],
      maxAzs: 3, // 3 Availability Zones
      subnetConfiguration: [
        {
          cidrMask: 24, // /24 subnets for public
          name: 'suno-main-vpc-public-',
          subnetType: ec2.SubnetType.PUBLIC,
        },
        {
          cidrMask: 24, // /24 subnets for private
          name: 'suno-main-vpc-app-',
          subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
        },
        {
          cidrMask: 24, // /24 subnets for private
          name: 'suno-main-vpc-app-lambda-',
          subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
        },
        {
          cidrMask: 24, // /24 subnets for private
          name: 'suno-main-vpc-database-',
          subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
        },
      ],
      natGateways: 3,
    });
    // Create VPC Peering Connection
    let vpcPeeringConnection: ec2.CfnVPCPeeringConnection;
    if (props.region !== 'us-east-2') {
      vpcPeeringConnection = new ec2.CfnVPCPeeringConnection(this, 'VpcPeeringConnection', {
        vpcId: multiRegionSunoMainVpc.vpcId,
        peerRegion: 'us-east-2',
        peerVpcId: sunoMainVpc.vpcId,
      });
    } else {
      // Different naming for staging vs prod in us-east-2
      if (props.accountStage === 'staging') {
        vpcPeeringConnection = new ec2.CfnVPCPeeringConnection(this, 'VpcPeeringConnection', {
          vpcId: sunoMainVpc.vpcId,
          peerVpcId: multiRegionSunoMainVpc.vpcId,
        });
      } else {
        vpcPeeringConnection = new ec2.CfnVPCPeeringConnection(this, 'VpcPeeringConnection-us-east-2', {
          vpcId: sunoMainVpc.vpcId,
          peerRegion: 'us-east-2',
          peerVpcId: multiRegionSunoMainVpc.vpcId,
        });
      }
    }

    if (props.region === 'us-east-2') {
      // Update Route Tables for sunoMainVpc
      sunoMainVpc.privateSubnets.forEach((subnet, index) => {
        const routeTable = subnet.routeTable;
        let routeTableId = routeTable.routeTableId;
        if (props.accountStage === 'staging') {
          if (subnet.ipv4CidrBlock === '10.0.3.0/24') {
            routeTableId = 'rtb-00579482b814eabe8';
          }
          if (subnet.ipv4CidrBlock === '10.0.67.0/24') {
            routeTableId = 'rtb-0728219d846bd5947';
          }
          if (subnet.ipv4CidrBlock === '10.0.131.0/24') {
            routeTableId = 'rtb-004b142eac611149c';
          }
        }
        new ec2.CfnRoute(this, `SunoMainVpcRoute${index}`, {
          routeTableId: routeTableId,
          destinationCidrBlock: multiRegionSunoMainVpc.vpcCidrBlock,
          vpcPeeringConnectionId: vpcPeeringConnection.ref,
        });
        
        // Only create multi-region routes in prod environment
        if (props.accountStage === 'prod') {
          new ec2.CfnRoute(this, `SunoMainVpcRoute${index}-eu-central-1`, {
            routeTableId: routeTableId,
            destinationCidrBlock: '10.5.0.0/16',
            vpcPeeringConnectionId: 'pcx-0efcd0b352c2a6eff',
          });
          new ec2.CfnRoute(this, `SunoMainVpcRoute${index}-ap-southeast-1`, {
            routeTableId: routeTableId,
            destinationCidrBlock: '10.6.0.0/16',
            vpcPeeringConnectionId: 'pcx-0e3c8dcea4959237a',
          });
        }
      });
      const lambdaRouteTableIds = ['rtb-0ef3bec0d99fca28a', 'rtb-00b94a54b9d9ca5e3', 'rtb-021a00fa38b3a3d76'];
      lambdaRouteTableIds.forEach((routeTableId, index) => {
        // Lambda routes only exist in prod environment
        if (props.accountStage === 'prod') {
          new ec2.CfnRoute(this, `SunoMainVpcRoute${index}-us-east-2-lambda`, {
            routeTableId: routeTableId,
            destinationCidrBlock: multiRegionSunoMainVpc.vpcCidrBlock,
            vpcPeeringConnectionId: vpcPeeringConnection.ref,
          });
          
          new ec2.CfnRoute(this, `SunoMainVpcRoute${index}-eu-central-1-lambda`, {
            routeTableId: routeTableId,
            destinationCidrBlock: '10.5.0.0/16',
            vpcPeeringConnectionId: 'pcx-0efcd0b352c2a6eff',
          });
          new ec2.CfnRoute(this, `SunoMainVpcRoute${index}-ap-southeast-1-lambda`, {
            routeTableId: routeTableId,
            destinationCidrBlock: '10.6.0.0/16',
            vpcPeeringConnectionId: 'pcx-0e3c8dcea4959237a',
          });
        }
      });
      const appRouteTableIds = ['rtb-013284304664b9102', 'rtb-0c3ea6c33961ac5aa', 'rtb-0174af4176ce2c575'];
      appRouteTableIds.forEach((routeTableId, index) => {
        // App routes only exist in prod environment
        if (props.accountStage === 'prod') {
          new ec2.CfnRoute(this, `SunoMainVpcRoute${index}-us-east-2-app`, {
            routeTableId: routeTableId,
            destinationCidrBlock: multiRegionSunoMainVpc.vpcCidrBlock,
            vpcPeeringConnectionId: vpcPeeringConnection.ref,
          });
          
          new ec2.CfnRoute(this, `SunoMainVpcRoute${index}-eu-central-1-app`, {
            routeTableId: routeTableId,
            destinationCidrBlock: '10.5.0.0/16',
            vpcPeeringConnectionId: vpcPeeringConnection.ref,
          });
          new ec2.CfnRoute(this, `SunoMainVpcRoute${index}-ap-southeast-1-app`, {
            routeTableId: routeTableId,
            destinationCidrBlock: '10.6.0.0/16',
            vpcPeeringConnectionId: vpcPeeringConnection.ref,
          });
        }
      });
    }

    // Update Route Tables for multiRegionSunoMainVpc
    multiRegionSunoMainVpc.privateSubnets.forEach((subnet, index) => {
      const routeTable = subnet.routeTable;
      console.log('routeTable', routeTable);
      new ec2.CfnRoute(this, `MultiRegionSunoMainVpcRoute${index}`, {
        routeTableId: routeTable.routeTableId,
        destinationCidrBlock: sunoMainVpc.vpcCidrBlock,
        vpcPeeringConnectionId: vpcPeeringConnection.ref,
      });
    });

    // Update Security Groups for sunoMainVpc
    // Security group only exists in staging environment
    if (props.region === 'us-east-2' && props.accountStage === 'staging') {
      const sunoMainVpcSecurityGroup = new ec2.SecurityGroup(this, 'SunoMainVpcSecurityGroup', {
        vpc: sunoMainVpc,
        allowAllOutbound: true,
      });
      sunoMainVpcSecurityGroup.addIngressRule(ec2.Peer.ipv4(multiRegionSunoMainVpc.vpcCidrBlock), ec2.Port.allTraffic());
    }

    // Update Security Groups for multiRegionSunoMainVpc
    const multiRegionSunoMainVpcSecurityGroup = new ec2.SecurityGroup(this, 'MultiRegionSunoMainVpcSecurityGroup', {
      vpc: multiRegionSunoMainVpc,
      allowAllOutbound: true,
      description: 'MultiRegionVpcStack/MultiRegionSunoMainVpcSecurityGroup',
    });
    multiRegionSunoMainVpcSecurityGroup.addIngressRule(ec2.Peer.ipv4(sunoMainVpc.vpcCidrBlock), ec2.Port.allTraffic());
  }
}
