"""
Module: alert_manager.py
Description: This module provides functionality for monitoring anomalies and sending alerts.
"""

import logging
import smtplib
from email.mime.text import MIMEText
from typing import List, Optional, Dict

# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')


class AlertManager:
    """
    A class for managing alerts and sending notifications based on detected anomalies.
    """

    def __init__(self, smtp_server: str, smtp_port: int, sender_email: str, sender_password: str, recipients: List[str]):
        """
        Initializes the AlertManager with SMTP server details and recipient information.

        Args:
            smtp_server: The SMTP server address (e.g., 'smtp.gmail.com').
            smtp_port: The SMTP server port (e.g., 587).
            sender_email: The email address from which alerts will be sent.
            sender_password: The password for the sender's email account.
            recipients: A list of email addresses to which alerts will be sent.
        """
        self.smtp_server = smtp_server
        self.smtp_port = smtp_port
        self.sender_email = sender_email
        self.sender_password = sender_password
        self.recipients = recipients

    def send_email_alert(self, subject: str, body: str) -> bool:
        """
        Sends an email alert to the configured recipients.

        Args:
            subject: The subject of the email.
            body: The body of the email.

        Returns:
            True if the email was sent successfully, False otherwise.
        """
        try:
            msg = MIMEText(body)
            msg['Subject'] = subject
            msg['From'] = self.sender_email
            msg['To'] = ', '.join(self.recipients)

            with smtplib.SMTP(self.smtp_server, self.smtp_port) as server:
                server.starttls()  # Upgrade connection to secure
                server.login(self.sender_email, self.sender_password)
                server.sendmail(self.sender_email, self.recipients, msg.as_string())

            logging.info(f"Alert email sent successfully to: {self.recipients}")
            return True
        except Exception as e:
            logging.error(f"Failed to send alert email: {e}")
            return False

    def handle_anomaly(self, anomaly_data: Dict, alert_threshold: float = 0.9) -> None:
        """
        Handles a detected anomaly by evaluating its severity and sending an alert if necessary.

        Args:
            anomaly_data: A dictionary containing information about the anomaly.  Expected keys include 'metric', 'value', and 'severity'.
            alert_threshold: The threshold for anomaly severity above which an alert will be triggered. Defaults to 0.9.
        """
        try:
            metric = anomaly_data.get('metric')
            value = anomaly_data.get('value')
            severity = anomaly_data.get('severity')

            if metric is None or value is None or severity is None:
                logging.warning(f"Incomplete anomaly data received: {anomaly_data}")
                return

            if severity >= alert_threshold:
                subject = f"Anomaly Detected: {metric}"
                body = f"A significant anomaly has been detected for {metric}.\n" \
                       f"Value: {value}\n" \
                       f"Severity: {severity}"

                self.send_email_alert(subject, body)
            else:
                logging.info(f"Anomaly detected for {metric} with severity {severity}, below threshold of {alert_threshold}. No alert sent.")

        except Exception as e:
            logging.error(f"Error handling anomaly: {e}")


if __name__ == '__main__':
    # Example Usage (replace with your actual configuration)
    smtp_server = 'smtp.gmail.com'  # Replace with your SMTP server
    smtp_port = 587  # Replace with your SMTP port
    sender_email = 'your_email@gmail.com'  # Replace with your sender email
    sender_password = 'your_password'  # Replace with your sender password or use an App Password for Gmail
    recipients = ['recipient1@example.com', 'recipient2@example.com']  # Replace with your recipient emails

    alert_manager = AlertManager(smtp_server, smtp_port, sender_email, sender_password, recipients)

    # Example anomaly data
    anomaly_data = {
        'metric': 'CPU Usage',
        'value': 95.5,
        'severity': 0.95
    }

    alert_manager.handle_anomaly(anomaly_data)

    # Example anomaly data below the threshold
    low_severity_anomaly = {
        'metric': 'Memory Usage',
        'value': 70.2,
        'severity': 0.6
    }

    alert_manager.handle_anomaly(low_severity_anomaly)

    # Example of an incomplete data
    incomplete_data = {
        'metric': 'Disk I/O'
    }

    alert_manager.handle_anomaly(incomplete_data)