import boto3
import json
import smtplib
import requests
from email.mime.text import MIMEText

class AlertingHandler:
    def __init__(self, alerting_config: dict):
        self.alerting_config = alerting_config or {}
        self.smtp_credentials = {}

        if "smtp_secret_name" in self.alerting_config:
            # Production secure method: Fetch SMTP creds from AWS Secrets Manager
            self.smtp_credentials = self.get_smtp_credentials_from_secrets(self.alerting_config["smtp_secret_name"])
        elif "smtp_server" in self.alerting_config:
            # Local testing: Credentials directly from config
            self.smtp_credentials = {
                "smtp_server": self.alerting_config.get("smtp_server"),
                "smtp_port": self.alerting_config.get("smtp_port"),
                "smtp_username": self.alerting_config.get("smtp_username"),
                "smtp_password": self.alerting_config.get("smtp_password"),
                "from_email": self.alerting_config.get("from_email")
            }

    def get_smtp_credentials_from_secrets(self, secret_name):
        try:
            client = boto3.client('secretsmanager')
            response = client.get_secret_value(SecretId=secret_name)
            secret = json.loads(response['SecretString'])
            return {
                "smtp_server": secret["smtp_server"],
                "smtp_port": int(secret["smtp_port"]),
                "smtp_username": secret["smtp_username"],
                "smtp_password": secret["smtp_password"],
                "from_email": secret["from_email"]
            }
        except Exception as e:
            print(f"[ERROR] Failed to fetch SMTP credentials from SecretsManager: {str(e)}")
            return {}

    def send_alert(self, subject, message_body):
        """Send both Slack and Email alerts if configured."""
        if "slack_webhook_url" in self.alerting_config:
            try:
                self.send_slack_alert(subject, message_body)
            except Exception as e:
                print(f"[WARNING] Failed to send Slack alert: {str(e)}")

        if "email_list" in self.alerting_config:
            try:
                self.send_email_alert(subject, message_body)
            except Exception as e:
                print(f"[WARNING] Failed to send Email alert: {str(e)}")

    def send_slack_alert(self, subject, message_body):
        slack_webhook_url = self.alerting_config.get("slack_webhook_url")
        slack_message = {
            "text": f"*{subject}*\n{message_body}"
        }
        headers = {'Content-Type': 'application/json'}

        response = requests.post(slack_webhook_url, headers=headers, data=json.dumps(slack_message))
        if response.status_code != 200:
            raise Exception(f"Slack webhook failed with status {response.status_code}: {response.text}")

        print(f"[SUCCESS] Slack alert sent.")

    def send_email_alert(self, subject, message_body):
        if not self.smtp_credentials:
            print("[INFO] SMTP credentials not configured; skipping email alert.")
            return

        smtp_server = self.smtp_credentials["smtp_server"]
        smtp_port = self.smtp_credentials["smtp_port"]
        smtp_username = self.smtp_credentials["smtp_username"]
        smtp_password = self.smtp_credentials["smtp_password"]
        from_email = self.smtp_credentials["from_email"]
        to_emails = self.alerting_config.get("email_list", [])

        msg = MIMEText(message_body)
        msg['Subject'] = subject
        msg['From'] = from_email
        msg['To'] = ", ".join(to_emails)

        with smtplib.SMTP(smtp_server, smtp_port) as server:
            server.starttls()
            server.login(smtp_username, smtp_password)
            server.sendmail(from_email, to_emails, msg.as_string())

        print(f"[SUCCESS] Email alert sent to: {', '.join(to_emails)}")
