import * as cdk from "aws-cdk-lib";
import * as acm from "aws-cdk-lib/aws-certificatemanager";
import * as cognito from "aws-cdk-lib/aws-cognito";
import * as route53 from "aws-cdk-lib/aws-route53";
import * as route53targets from "aws-cdk-lib/aws-route53-targets";
import { Construct } from "constructs";

interface UserPoolCustomDomainProps {
  userPool: cognito.IUserPool;
  hostedZone: route53.IHostedZone;
  domainPrefix: string;
  certificate: acm.ICertificate;
}

export class UserPoolCustomDomain extends Construct {
  readonly userPoolOAuthTokenEndpointUrl: string;

  constructor(scope: Construct, id: string, props: UserPoolCustomDomainProps) {
    super(scope, id);
    const { userPool, hostedZone, domainPrefix, certificate } = props;

    const userPoolCustomDomain = new cognito.UserPoolDomain(this, "UserPoolCustomDomain", {
      userPool,
      customDomain: {
        domainName: `${domainPrefix}.${hostedZone.zoneName}`,
        certificate: certificate,
      },
    });

    new route53.ARecord(this, "UserPoolCustomDomainAliasRecord", {
      zone: hostedZone,
      recordName: domainPrefix,
      target: route53.RecordTarget.fromAlias(new route53targets.UserPoolDomainTarget(userPoolCustomDomain)),
    });
    this.userPoolOAuthTokenEndpointUrl = `https://${userPoolCustomDomain.domainName}/oauth2/token`;
  }
}

interface UserPoolCognitoDomainProps {
  userPool: cognito.IUserPool;
  domainPrefix: string;
}

export class UserPoolCognitoDomain extends Construct {
  readonly userPoolOAuthTokenEndpointUrl: string;

  constructor(scope: Construct, id: string, props: UserPoolCognitoDomainProps) {
    super(scope, id);
    const { region } = new cdk.ScopedAws(this);
    const { domainPrefix, userPool } = props;
    new cognito.UserPoolDomain(this, "UserPoolDomain", {
      userPool,
      cognitoDomain: {
        domainPrefix,
      },
    });
    this.userPoolOAuthTokenEndpointUrl = `https://${domainPrefix}.auth.${region}.amazoncognito.com/oauth2/token`;
  }
}
