"""
Notification service for sending risk warnings and alerts
"""

import json
import logging
from typing import Dict, Any, Optional
from datetime import datetime
import requests

from ..models.decision import ReviewRequest
from .controller import RiskAssessment

logger = logging.getLogger(__name__)


class NotificationService:
    """
    Notification service for sending alerts via multiple channels

    Supports:
    - Feishu (Lark) webhook notifications
    - Email notifications (future)
    - SMS notifications (future)
    """

    def __init__(
        self,
        feishu_webhook: Optional[str] = None,
        email_config: Optional[Dict[str, str]] = None,
    ):
        """
        Initialize notification service

        Args:
            feishu_webhook: Feishu webhook URL for notifications
            email_config: Email configuration dictionary
        """
        self.feishu_webhook = feishu_webhook
        self.email_config = email_config or {}
        self.notification_history: list = []

    def send_risk_warning(self, risk_assessment: RiskAssessment, context: Dict[str, Any]) -> bool:
        """
        Send risk warning notification

        Args:
            risk_assessment: Risk assessment result
            context: Additional context information

        Returns:
            True if notification sent successfully, False otherwise
        """
        try:
            # Build warning message
            message = self._build_risk_warning_message(risk_assessment, context)

            # Send via available channels
            success = False

            if self.feishu_webhook:
                success = self._send_feishu_message(message, "Risk Warning")

            # Log the notification
            self._log_notification("risk_warning", message, success)

            return success

        except Exception as e:
            logger.error(f"Failed to send risk warning: {str(e)}")
            return False

    def send_review_request(self, review_request: ReviewRequest) -> bool:
        """
        Send human review request notification

        Args:
            review_request: Review request details

        Returns:
            True if notification sent successfully, False otherwise
        """
        try:
            # Build review request message
            message = self._build_review_request_message(review_request)

            # Send via available channels
            success = False

            if self.feishu_webhook:
                success = self._send_feishu_message(message, "Review Request")

            # Log the notification
            self._log_notification("review_request", message, success)

            return success

        except Exception as e:
            logger.error(f"Failed to send review request: {str(e)}")
            return False

    def send_rollback_notification(self, reason: str, from_version: str, to_version: str) -> bool:
        """
        Send rollback notification

        Args:
            reason: Reason for rollback
            from_version: Version being rolled back from
            to_version: Version being rolled back to

        Returns:
            True if notification sent successfully, False otherwise
        """
        try:
            # Build rollback message
            message = self._build_rollback_message(reason, from_version, to_version)

            # Send via available channels
            success = False

            if self.feishu_webhook:
                success = self._send_feishu_message(message, "Rollback Notification")

            # Log the notification
            self._log_notification("rollback", message, success)

            return success

        except Exception as e:
            logger.error(f"Failed to send rollback notification: {str(e)}")
            return False

    def send_iteration_complete(self, iteration_summary: Dict[str, Any]) -> bool:
        """
        Send iteration complete notification

        Args:
            iteration_summary: Summary of completed iteration

        Returns:
            True if notification sent successfully, False otherwise
        """
        try:
            # Build iteration complete message
            message = self._build_iteration_complete_message(iteration_summary)

            # Send via available channels
            success = False

            if self.feishu_webhook:
                success = self._send_feishu_message(message, "Iteration Complete")

            # Log the notification
            self._log_notification("iteration_complete", message, success)

            return success

        except Exception as e:
            logger.error(f"Failed to send iteration complete notification: {str(e)}")
            return False

    def _send_feishu_message(self, message: str, title: str) -> bool:
        """
        Send message via Feishu webhook

        Args:
            message: Message content
            title: Message title

        Returns:
            True if sent successfully, False otherwise
        """
        if not self.feishu_webhook:
            logger.warning("Feishu webhook not configured")
            return False

        try:
            # Build Feishu message card
            payload = {
                "msg_type": "interactive",
                "card": {
                    "header": {
                        "title": {"tag": "plain_text", "content": title},
                        "template": self._get_feishu_color_for_title(title),
                    },
                    "elements": [
                        {
                            "tag": "div",
                            "text": {"tag": "lark_md", "content": message},
                        },
                        {
                            "tag": "hr",
                        },
                        {
                            "tag": "note",
                            "elements": [
                                {
                                    "tag": "plain_text",
                                    "content": f"Timestamp: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}",
                                }
                            ],
                        },
                    ],
                },
            }

            # Send POST request
            response = requests.post(
                self.feishu_webhook,
                json=payload,
                headers={"Content-Type": "application/json"},
                timeout=10,
            )

            if response.status_code == 200:
                result = response.json()
                if result.get("code") == 0:
                    logger.info(f"Feishu notification sent successfully: {title}")
                    return True
                else:
                    logger.error(f"Feishu API error: {result}")
                    return False
            else:
                logger.error(f"Feishu webhook request failed: {response.status_code}")
                return False

        except Exception as e:
            logger.error(f"Failed to send Feishu message: {str(e)}")
            return False

    def _get_feishu_color_for_title(self, title: str) -> str:
        """
        Get Feishu card color based on title

        Args:
            title: Message title

        Returns:
            Color template name
        """
        if "Risk Warning" in title or "Rollback" in title:
            return "red"
        elif "Review Request" in title:
            return "orange"
        elif "Complete" in title:
            return "green"
        else:
            return "blue"

    def _build_risk_warning_message(
        self, risk_assessment: RiskAssessment, context: Dict[str, Any]
    ) -> str:
        """
        Build risk warning message

        Args:
            risk_assessment: Risk assessment result
            context: Additional context

        Returns:
            Formatted message string
        """
        message_parts = [
            f"**Risk Level:** {risk_assessment.risk_level.upper()}",
            "",
            "**Risk Factors:**",
        ]

        for factor in risk_assessment.risk_factors:
            message_parts.append(
                f"- **{factor.factor_type}** ({factor.severity}): {factor.description}"
            )

        message_parts.extend(
            [
                "",
                f"**Requires Review:** {'Yes' if risk_assessment.requires_review else 'No'}",
                f"**Can Proceed:** {'Yes' if risk_assessment.can_proceed else 'No'}",
                "",
                "**Recommendations:**",
            ]
        )

        for rec in risk_assessment.recommendations:
            message_parts.append(f"- {rec}")

        if context:
            message_parts.extend(["", "**Context:**"])
            for key, value in context.items():
                message_parts.append(f"- {key}: {value}")

        return "\n".join(message_parts)

    def _build_review_request_message(self, review_request: ReviewRequest) -> str:
        """
        Build review request message

        Args:
            review_request: Review request details

        Returns:
            Formatted message string
        """
        plan = review_request.plan

        message_parts = [
            f"**Request ID:** {review_request.request_id}",
            f"**Urgency:** {review_request.urgency.upper()}",
            f"**Reason:** {review_request.reason}",
            "",
            "**Improvement Plan:**",
            f"- Plan ID: {plan.plan_id}",
            f"- Risk Level: {plan.risk_level}",
            f"- Issues Addressed: {len(plan.issues_addressed)}",
            f"- Modifications: {len(plan.modifications)}",
            "",
            "**Rationale:**",
            plan.rationale,
            "",
            "**Expected Impact:**",
        ]

        for metric, value in plan.expected_impact.items():
            message_parts.append(f"- {metric}: {value:+.2%}")

        message_parts.extend(
            [
                "",
                "**Action Required:**",
                "Please review and approve/reject this modification plan.",
            ]
        )

        return "\n".join(message_parts)

    def _build_rollback_message(self, reason: str, from_version: str, to_version: str) -> str:
        """
        Build rollback notification message

        Args:
            reason: Rollback reason
            from_version: Source version
            to_version: Target version

        Returns:
            Formatted message string
        """
        message_parts = [
            "**System Rollback Initiated**",
            "",
            f"**Reason:** {reason}",
            f"**From Version:** {from_version}",
            f"**To Version:** {to_version}",
            "",
            "**Action Taken:**",
            "The system has automatically rolled back to the previous stable version.",
            "",
            "**Next Steps:**",
            "- Review the rollback reason",
            "- Investigate the issue that caused the rollback",
            "- Address the root cause before attempting another modification",
        ]

        return "\n".join(message_parts)

    def _build_iteration_complete_message(self, iteration_summary: Dict[str, Any]) -> str:
        """
        Build iteration complete message

        Args:
            iteration_summary: Iteration summary data

        Returns:
            Formatted message string
        """
        message_parts = [
            "**Iteration Complete**",
            "",
            f"**Iteration Number:** {iteration_summary.get('iteration_num', 'N/A')}",
            f"**Status:** {iteration_summary.get('status', 'N/A')}",
            "",
        ]

        if "metrics" in iteration_summary and iteration_summary["metrics"]:
            metrics = iteration_summary["metrics"]
            message_parts.extend(
                [
                    "**Performance Metrics:**",
                    f"- Sharpe Ratio: {metrics.sharpe_ratio:.2f}",
                    f"- Win Rate: {metrics.win_rate:.2%}",
                    f"- Profit Factor: {metrics.profit_factor:.2f}",
                    f"- Max Drawdown: {metrics.max_drawdown:.2%}",
                    "",
                ]
            )

        if "improvement_plan" in iteration_summary and iteration_summary["improvement_plan"]:
            plan = iteration_summary["improvement_plan"]
            message_parts.extend(
                [
                    "**Improvements Applied:**",
                    f"- Plan ID: {plan.plan_id}",
                    f"- Modifications: {len(plan.modifications)}",
                    f"- Risk Level: {plan.risk_level}",
                    "",
                ]
            )

        message_parts.append("The system will continue with the next iteration.")

        return "\n".join(message_parts)

    def _log_notification(self, notification_type: str, message: str, success: bool) -> None:
        """
        Log notification to history

        Args:
            notification_type: Type of notification
            message: Message content
            success: Whether notification was successful
        """
        self.notification_history.append(
            {
                "type": notification_type,
                "message": message,
                "success": success,
                "timestamp": datetime.now().isoformat(),
            }
        )

        # Keep only last 100 notifications
        if len(self.notification_history) > 100:
            self.notification_history = self.notification_history[-100:]

    def get_notification_history(self, limit: Optional[int] = None) -> list:
        """
        Get notification history

        Args:
            limit: Optional limit on number of notifications to return

        Returns:
            List of notification records
        """
        if limit:
            return self.notification_history[-limit:]
        return self.notification_history
