"""
Email Service Integration - Handles email communication via Microsoft Graph API.
Sends test execution reports and notifications.
"""

import msal
import requests
import json
import os
import re
from typing import Optional, List, Dict, Any
from datetime import datetime
from dotenv import load_dotenv
import pandas as pd

from backend.core.logger import get_logger

load_dotenv()


class EmailService:
    """
    Integration service for email communication.
    Sends test execution reports via Microsoft Graph API.
    """

    def __init__(self, logger=None):
        """Initialize email service with credentials from environment."""
        self.logger = logger or get_logger(__name__)
        self.client_id = os.getenv("CLIENT_ID")
        self.client_secret = os.getenv("CLIENT_SECRET")
        self.tenant_id = os.getenv("TENANT_ID")
        self.graph_user = os.getenv("GRAPH_USER")

    def _get_access_token(self) -> str:
        """Acquire access token for Microsoft Graph API."""
        authority = f'https://login.microsoftonline.com/{self.tenant_id}'
        scope = ["https://graph.microsoft.com/.default"]

        app = msal.ConfidentialClientApplication(
            self.client_id,
            authority=authority,
            client_credential=self.client_secret
        )
        token_response = app.acquire_token_for_client(scopes=scope)
        if 'access_token' not in token_response:
            raise ValueError("Failed to acquire access token for Graph API")
        return token_response['access_token']

    def _extract_build_version_from_url(self, url: str) -> str:
        """Try extracting build version from a webpage."""
        try:
            if not url:
                return ""
            resp = requests.get(url, timeout=10, headers={"User-Agent": "Mozilla/5.0"})
            if resp.status_code != 200 or not resp.text:
                return ""
            html = resp.text
            # Common patterns to detect version strings
            patterns = [
                r"meta\\s+name=\\\"build-version\\\"\\s+content=\\\"([^\\\"]+)\\\"",
                r"build[-_ ]?version['\"]?\s*[:=]\s*['\"]?([A-Za-z0-9_.-]+)",
                r"version['\"]?\s*[:=]\s*['\"]?([A-Za-z0-9_.-]+)",
                r"Build\\s*Version\\s*[:=\\-]\\s*([A-Za-z0-9_.-]+)",
                r"APP_VERSION\s*[:=]\s*['\"]?([A-Za-z0-9_.-]+)",
            ]
            for pattern in patterns:
                m = re.search(pattern, html, flags=re.IGNORECASE)
                if m:
                    return m.group(1).strip()
            return ""
        except Exception:
            return ""

    def _clean_test_case_title(self, title: str) -> str:
        """Remove only the first leading bracketed segment from a title."""
        try:
            text = str(title)
        except Exception:
            return ""
        # Strip a single leading [ ... ] block
        m = re.match(r"^\s*\[[^\]]*\]\s*", text)
        if m:
            text = text[m.end():]
        return text

    def _build_email_html(
        self,
        report_url: str,
        login_url: str,
        summary_data: Dict[str, Any],
        test_summary: Dict[str, Any],
        detailed_report: Dict[str, Any]
    ) -> str:
        """Build HTML content for test execution report email."""
        try:
            passed_count = int(summary_data.get('Total Steps Passed', 0) or 0)
        except Exception:
            passed_count = 0
        try:
            failed_count = int(summary_data.get('Total Steps Failed', 0) or 0)
        except Exception:
            failed_count = 0
        
        total_count = passed_count + failed_count
        pass_percent_str = f"{int((passed_count / total_count) * 100)}%" if total_count else "0%"

        # Build version displayed under header
        scraped_version = self._extract_build_version_from_url(login_url)
        build_version = (
            scraped_version
            or (
                str(summary_data.get('Build Version')).strip()
                if isinstance(summary_data.get('Build Version'), (str, int, float)) and str(summary_data.get('Build Version')).strip()
                else os.getenv('BUILD_VERSION', '').strip()
            )
        )

        # HTML content
        html_content = f"""
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <title>HCLTech - Execution Report</title>
  <style>
    body {{
      background: #f8f9ff;
      margin: 0;
      padding: 20px;
      color: #1C1C1C;
      font-family: Arial, sans-serif;
    }}
    .container {{
      max-width: 1000px;
      margin: 0 auto;
      background: white;
      border-radius: 12px;
      padding: 24px;
      box-shadow: 0 6px 20px rgba(18,32,64,0.06);
    }}
    h2 {{
      color: #000000;
    }}
    table {{
      width: 100%;
      border-collapse: collapse;
      margin-top: 18px;
      font-size: 14px;
    }}
    th {{
      background-color: #0949F6 !important;
      color: #ffffff !important;
      padding: 10px;
      text-align: left;
    }}
    td {{
      background-color: #ffffff !important;
      padding: 10px;
      border-bottom: 1px solid #f1f3ff;
      color: #000000;
    }}
    .status-passed {{ color: #00994C; font-weight: bold; }}
    .status-failed {{ color: #FF4D4F; font-weight: bold; }}
    .btn {{
      display:inline-block;
      background-color: #0949F6 !important;
      color: #ffffff !important;
      padding: 10px 16px;
      text-decoration: none;
      border-radius: 8px;
      font-weight: bold;
      margin-top: 16px;
    }}
    .header {{
      display: flex;
      align-items: center;
      justify-content: space-between;
      margin-bottom: 24px;
    }}
    .logo {{
      font-size: 20px;
      font-weight: bold;
      color: #000000;
    }}
    .accent-bar {{
      height: 6px;
      border-radius: 6px;
      background: linear-gradient(90deg,#6F31FF,#0949F6);
      margin-top: 12px;
    }}
  </style>
</head>
<body>
  <div class="container">
    <div class="header">
      <div>
        <div class="logo">IDC_Family_Safety Web Regression AI Agent Report</div>
      </div>
    </div>

   <h2>Test Summary</h2>
<table>
  <thead>
    <tr>
      <th>Total</th>
      <th>Passed</th>
      <th>Failed</th>
      <th>Pass %</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>{total_count}</td>
      <td>{passed_count}</td>
      <td>{failed_count}</td>
      <td>{pass_percent_str}</td>
    </tr>
  </tbody>
</table>

   <h2>Execution Summary</h2>
<table>
  <thead>
    <tr>
      <th>Run Start Time</th>
      <th>Run End Time</th>
      <th>Total Duration</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>{summary_data.get('Run Start Time', '')}</td>
      <td>{summary_data.get('Run End Time', '')}</td>
      <td>{(
          str(pd.to_datetime(summary_data['Run End Time']) - pd.to_datetime(summary_data['Run Start Time']))
          .replace('0 days ', '')
      ) if summary_data.get('Run Start Time') and summary_data.get('Run End Time') else ''}</td>
    </tr>
  </tbody>
</table>

    <h2>Detailed Execution Report</h2>
    <table>
      <thead>
        <tr>{"".join(f"<th>{col}</th>" for col in detailed_report['columns'])}</tr>
      </thead>
      <tbody>
        {"".join(
            "<tr>" + "".join(
                (
                    f"<td class='status-{(row.get('Status','').lower())}'>{row.get(col,'')}</td>"
                    if col == 'Status'
                    else (
                        f"<td>{self._clean_test_case_title(row.get(col,''))}</td>"
                        if col.strip().lower() == 'test case title'
                        else f"<td>{row.get(col,'')}</td>"
                    )
                )
                for col in detailed_report['columns']
            ) + "</tr>"
            for row in detailed_report['rows']
        )}
      </tbody>
    </table>

    <a href="{report_url}" class="btn">Download Full Report</a>

    <div class="accent-bar"></div>

    <p style="color:#7D7D7D;font-size:12px;margin-top:24px;">
      Note: This is an automated email generated by the HCLTech Exploratory Agent. Do not reply to this email.
    </p>
  </div>
</body>
</html>
"""
        return html_content

    def send_email(
        self,
        recipients: str,
        report_url: str,
        login_url: str,
        summary_data: Dict[str, Any],
        test_cases: List[Dict[str, Any]],
        test_summary: Dict[str, Any],
        execution_summary: Dict[str, Any],
        detailed_report: Dict[str, Any]
    ) -> bool:
        """Send test execution report via email."""
        try:
            access_token = self._get_access_token()
        except Exception as e:
            self.logger.error(f"Failed to get access token: {e}")
            return False

        html_content = self._build_email_html(report_url, login_url, summary_data, test_summary, detailed_report)

        if not recipients:
            recipients = os.getenv("MAIL_RECIPIENTS", "")

        cc_normalized_list = []
        try:
            if isinstance(recipients, (list, tuple, set)):
                cc_normalized_list = [str(x).strip() for x in recipients if str(x).strip()]
            elif isinstance(recipients, str):
                cc_normalized_list = [x.strip() for x in recipients.split(",") if x.strip()]
        except Exception:
            cc_normalized_list = []

        cc_addresses = cc_normalized_list
        
        primary_recipients_env = os.getenv("PRIMARY_RECIPIENT", "")
        to_addresses = []
        try:
            if primary_recipients_env:
                to_addresses = [x.strip() for x in primary_recipients_env.split(",") if x.strip()]
        except Exception:
            to_addresses = []

        bcc_recipients_env = os.getenv("BCC_RECIPIENTS", "")
        bcc_addresses = []
        try:
            if bcc_recipients_env:
                bcc_addresses = [x.strip() for x in bcc_recipients_env.split(",") if x.strip()]
        except Exception:
            bcc_addresses = []

        to_recipients = [{"emailAddress": {"address": addr}} for addr in to_addresses]
        cc_recipients = [{"emailAddress": {"address": addr}} for addr in cc_addresses]
        bcc_recipients = [{"emailAddress": {"address": addr}} for addr in bcc_addresses]

        email_message = {
            "message": {
                "subject": "IDC_Family_Safety Web Regression AI Agent Report",
                "body": {
                    "contentType": "HTML",
                    "content": html_content
                },
                "toRecipients": to_recipients,
                "ccRecipients": cc_recipients,
                "bccRecipients": bcc_recipients
            },
            "saveToSentItems": "false"
        }

        headers = {
            'Authorization': f'Bearer {access_token}',
            'Content-Type': 'application/json'
        }

        graph_api_endpoint = f'https://graph.microsoft.com/v1.0/users/{self.graph_user}/sendMail'
        response = requests.post(graph_api_endpoint, headers=headers, data=json.dumps(email_message))

        if response.status_code == 202:
            return True
        else:
            self.logger.error(f"Failed to send email: {response.status_code} - {response.text}")
            return False

    def send_client_email(
        self,
        report_url: str,
        login_url: str,
        summary_data: Dict[str, Any],
        test_cases: List[Dict[str, Any]],
        test_summary: Dict[str, Any],
        execution_summary: Dict[str, Any],
        detailed_report: Dict[str, Any],
        should_send: bool = True,
        client_report_url: str = None
    ) -> bool:
        """Send email to client recipients."""
        if not should_send:
            return False
        
        client_primary_recipient = os.getenv("CLIENT_PRIMARY_RECIPIENT", "")
        client_mail_recipients = os.getenv("CLIENT_MAIL_RECIPIENTS", "")
        client_bcc_recipients = os.getenv("CLIENT_BCC_RECIPIENTS", "")
        
        if not client_primary_recipient and not client_mail_recipients:
            return False
        
        try:
            original_primary = os.getenv("PRIMARY_RECIPIENT")
            original_mail = os.getenv("MAIL_RECIPIENTS")
            original_bcc = os.getenv("BCC_RECIPIENTS")
            
            os.environ["PRIMARY_RECIPIENT"] = client_primary_recipient
            os.environ["MAIL_RECIPIENTS"] = client_mail_recipients
            os.environ["BCC_RECIPIENTS"] = client_bcc_recipients
            
            effective_report_url = client_report_url if client_report_url else report_url
            
            self.logger.info(f"  TO: {client_primary_recipient}")
            self.logger.info(f"  CC: {client_mail_recipients}")
            self.logger.info(f"  BCC: {client_bcc_recipients}")
            
            email_sent = self.send_email(
                client_mail_recipients, effective_report_url, login_url, summary_data, test_cases,
                test_summary, execution_summary, detailed_report
            )
            
            if original_primary:
                os.environ["PRIMARY_RECIPIENT"] = original_primary
            else:
                os.environ.pop("PRIMARY_RECIPIENT", None)
            if original_mail:
                os.environ["MAIL_RECIPIENTS"] = original_mail
            else:
                os.environ.pop("MAIL_RECIPIENTS", None)
            if original_bcc:
                os.environ["BCC_RECIPIENTS"] = original_bcc
            else:
                os.environ.pop("BCC_RECIPIENTS", None)
            
            return True
            
        except Exception as e:
            self.logger.error(f"Error sending client email: {e}")
            return False

    def send_internal_email(
        self,
        report_url: str,
        login_url: str,
        summary_data: Dict[str, Any],
        test_cases: List[Dict[str, Any]],
        test_summary: Dict[str, Any],
        execution_summary: Dict[str, Any],
        detailed_report: Dict[str, Any],
        internal_report_url: str = None
    ) -> bool:
        """Send email to internal recipients."""
        internal_primary_recipient = os.getenv("INTERNAL_PRIMARY_RECIPIENT", "")
        internal_mail_recipients = os.getenv("INTERNAL_MAIL_RECIPIENTS", "")
        internal_bcc_recipients = os.getenv("INTERNAL_BCC_RECIPIENTS", "")
        
        if not internal_primary_recipient and not internal_mail_recipients:
            return False
        
        try:
            original_primary = os.getenv("PRIMARY_RECIPIENT")
            original_mail = os.getenv("MAIL_RECIPIENTS")
            original_bcc = os.getenv("BCC_RECIPIENTS")
            
            os.environ["PRIMARY_RECIPIENT"] = internal_primary_recipient
            os.environ["MAIL_RECIPIENTS"] = internal_mail_recipients
            os.environ["BCC_RECIPIENTS"] = internal_bcc_recipients
            
            effective_report_url = internal_report_url if internal_report_url else report_url
            
            self.logger.info(f"  TO: {internal_primary_recipient}")
            self.logger.info(f"  CC: {internal_mail_recipients}")
            self.logger.info(f"  BCC: {internal_bcc_recipients}")
            
            email_sent = self.send_email(
                internal_mail_recipients, effective_report_url, login_url, summary_data, test_cases,
                test_summary, execution_summary, detailed_report
            )
            
            if original_primary:
                os.environ["PRIMARY_RECIPIENT"] = original_primary
            else:
                os.environ.pop("PRIMARY_RECIPIENT", None)
            if original_mail:
                os.environ["MAIL_RECIPIENTS"] = original_mail
            else:
                os.environ.pop("MAIL_RECIPIENTS", None)
            if original_bcc:
                os.environ["BCC_RECIPIENTS"] = original_bcc
            else:
                os.environ.pop("BCC_RECIPIENTS", None)
            
            return True
            
        except Exception as e:
            self.logger.error(f"Error sending internal email: {e}")
            return False


# Backward compatibility functions
_email_service_instance = EmailService()


def send_client_email(
    report_url: str,
    login_url: str,
    summary_data: Dict[str, Any],
    test_cases: List[Dict[str, Any]],
    test_summary: Dict[str, Any],
    execution_summary: Dict[str, Any],
    detailed_report: Dict[str, Any],
    should_send: bool = True,
    client_report_url: str = None
) -> bool:
    """Backward compatibility function."""
    return _email_service_instance.send_client_email(
        report_url, login_url, summary_data, test_cases, test_summary,
        execution_summary, detailed_report, should_send, client_report_url
    )


def send_internal_email(
    report_url: str,
    login_url: str,
    summary_data: Dict[str, Any],
    test_cases: List[Dict[str, Any]],
    test_summary: Dict[str, Any],
    execution_summary: Dict[str, Any],
    detailed_report: Dict[str, Any],
    internal_report_url: str = None
) -> bool:
    """Backward compatibility function."""
    return _email_service_instance.send_internal_email(
        report_url, login_url, summary_data, test_cases, test_summary,
        execution_summary, detailed_report, internal_report_url
    )


__all__ = [
    "EmailService",
    "send_client_email",
    "send_internal_email",
]
