import os
import logging
from typing import Dict, Any, Optional

import boto3
from botocore.exceptions import ClientError

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

class SES:
    def __init__(self, region_name: Optional[str] = None):
        """
        Create SES helper. Most methods accept per-call credentials to mimic your TS shape.
        If you want a client bound to permanent credentials, you can create one and pass
        those credentials into the methods or extend this class to store them.
        """
        self.region = region_name or os.getenv("AWS_DEFAULT_REGION", "us-east-1")

    def _make_sesv2_client(self, credentials: Optional[Dict[str, str]] = None):
        """
        Create a boto3 sesv2 client. If credentials dict is provided it should contain
        'accessKeyId' and 'secretAccessKey' keys (matching the TS code shape).
        """
        if credentials:
            return boto3.client(
                "sesv2",
                region_name=self.region,
                aws_access_key_id=credentials.get("accessKeyId"),
                aws_secret_access_key=credentials.get("secretAccessKey"),
            )
        return boto3.client("sesv2", region_name=self.region)

    def is_email_verified(
        self,
        credentials: Optional[Dict[str, str]],
        params: Dict[str, Any],
    ) -> Optional[Dict[str, Any]]:
        """
        Check email/domain identity status.
        :param credentials: {'accessKeyId': '...', 'secretAccessKey': '...'} OR None
        :param params: dict for get_email_identity, must include 'EmailIdentity'
        :return: response dict from get_email_identity() or None if error
        """
        try:
            client = self._make_sesv2_client(credentials)
            response = client.get_email_identity(**params)
            return response
        except ClientError as e:
            logger.error("AWS SESv2 ClientError in is_email_verified: %s", e)
            return None
        except Exception as e:
            logger.exception("Unexpected error in is_email_verified: %s", e)
            return None

    def verify_email_identity(
        self,
        credentials: Optional[Dict[str, str]],
        params: Dict[str, Any],
    ) -> bool:
        """
        Create (verify) an email identity or domain identity.
        :param credentials: {'accessKeyId': '...', 'secretAccessKey': '...'} OR None
        :param params: dict for create_email_identity, must include 'EmailIdentity'
        :return: True on success; raises on failure (mirrors TS behaviour)
        """
        try:
            client = self._make_sesv2_client(credentials)
            client.create_email_identity(**params)
            return True
        except ClientError as e:
            logger.error("AWS SESv2 ClientError in verify_email_identity: %s", e)
            raise
        except Exception as e:
            logger.exception("Unexpected error in verify_email_identity: %s", e)
            raise

    def add_domain_identity(
        self,
        credentials: Optional[Dict[str, str]],
        params: Dict[str, Any],
    ) -> Dict[str, Any]:
        """
        Add a domain identity (wraps create_email_identity and returns the response).
        :param credentials: {'accessKeyId': '...', 'secretAccessKey': '...'} OR None
        :param params: dict for create_email_identity, must include 'EmailIdentity' (domain)
        :return: response dict from create_email_identity
        """
        try:
            client = self._make_sesv2_client(credentials)
            response = client.create_email_identity(**params)
            return response
        except ClientError as e:
            logger.error("AWS SESv2 ClientError in add_domain_identity: %s", e)
            raise
        except Exception as e:
            logger.exception("Unexpected error in add_domain_identity: %s", e)
            raise
