"""
VWP BEC Incident - Send phishing notification to all affected recipients.
Sends from JR's account via Microsoft Graph API sendMail endpoint.
"""

import json
import subprocess
import sys
import tempfile
import os

# === Configuration ===
TENANT_ID = "5c53ae9f-7071-4248-b834-8685b646450f"
APP_ID = "fabb3421-8b34-484b-bc17-e46de9703418"
APP_SECRET = "~QJ8Q~NyQSs4OcGqHZyPrA2CVnq9KBfKiimntbMO"
JR_USER_ID = "0af923d0-48c5-4cc1-8553-c60625802815"
JR_EMAIL = "j-r@valleywideplastering.com"

RECIPIENTS_FILE = r"D:\ClaudeTools\temp\vwp_exchange_recipients.json"

# Addresses to exclude (lowercase for comparison)
EXCLUDE_EXACT = {
    "j-r@valleywideplastering.com",
    "jr@valleywideplastering.com",
    "jr@casarica.net",
    "jrsuperwall@gmail.com",
    "kathya@azappliancehome.com.com",  # malformed double .com
}

EXCLUDE_DOMAINS = ["bidmail.com", "onmicrosoft.com"]


def get_access_token():
    """Acquire OAuth2 token via client credentials flow."""
    token_url = f"https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token"
    result = subprocess.run(
        [
            "curl", "-s", "-X", "POST", token_url,
            "-H", "Content-Type: application/x-www-form-urlencoded",
            "-d", f"client_id={APP_ID}&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret={APP_SECRET}&grant_type=client_credentials",
        ],
        capture_output=True, text=True
    )
    resp = json.loads(result.stdout)
    if "access_token" not in resp:
        print("[ERROR] Failed to get access token:")
        print(json.dumps(resp, indent=2))
        sys.exit(1)
    print("[OK] Access token acquired")
    return resp["access_token"]


def load_recipients():
    """Load and filter recipients from the JSON file."""
    with open(RECIPIENTS_FILE, encoding="utf-8") as f:
        data = json.load(f)

    raw = data["all_unique_recipients"]
    print(f"[INFO] Raw recipient count: {len(raw)}")

    # Strip surrounding single quotes and whitespace
    cleaned = [addr.strip().strip("'").strip() for addr in raw]

    # Filter and deduplicate (case-insensitive)
    seen = set()
    filtered = []
    for addr in cleaned:
        lower = addr.lower()

        # Skip excluded exact addresses
        if lower in EXCLUDE_EXACT:
            continue

        # Skip excluded domain patterns
        if any(domain in lower for domain in EXCLUDE_DOMAINS):
            continue

        # Deduplicate
        if lower not in seen:
            seen.add(lower)
            filtered.append(addr)

    print(f"[INFO] After filtering and dedup: {len(filtered)} BCC recipients")
    return filtered


def send_notification(token, bcc_recipients):
    """Send the notification email via Graph API sendMail endpoint."""
    subject = 'Security Notice - Do Not Open Box.com File "Valley Wide Plastering, INC......pdf"'

    body_html = (
        '<p>You recently received a file sharing invitation from my Box.com account '
        'for a file named "Valley Wide Plastering, INC......pdf".</p>'
        '\n\n'
        '<p>This file was <strong>NOT</strong> sent by me. My email account was temporarily '
        'compromised, and the attacker used it to distribute this malicious link through '
        'Box.com. The issue has been resolved and my account has been secured.</p>'
        '\n\n'
        '<p><strong>Please take the following steps:</strong></p>'
        '\n'
        '<ol>'
        '<li>Do NOT open or click the Box.com link if you haven\'t already</li>'
        '<li>If you DID click the link or entered any credentials on the page, please '
        'change your password immediately and notify your IT department</li>'
        '<li>Delete the Box.com sharing notification email from your inbox</li>'
        '<li>If you created a Box.com account as a result of this invitation, consider removing it</li>'
        '</ol>'
        '\n\n'
        '<p>We apologize for the inconvenience. If you have any questions or concerns, '
        'please contact our office directly.</p>'
        '\n\n'
        '<p>JR Guerrero<br>Valley Wide Plastering, Inc.</p>'
    )

    payload = {
        "message": {
            "subject": subject,
            "body": {
                "contentType": "HTML",
                "content": body_html
            },
            "toRecipients": [
                {"emailAddress": {"address": JR_EMAIL}}
            ],
            "bccRecipients": [
                {"emailAddress": {"address": addr}} for addr in bcc_recipients
            ]
        },
        "saveToSentItems": True
    }

    # Write payload to temp file to avoid command-line length limits
    tmp = tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False, encoding="utf-8")
    json.dump(payload, tmp, ensure_ascii=False)
    tmp.close()

    send_url = f"https://graph.microsoft.com/v1.0/users/{JR_USER_ID}/sendMail"

    try:
        result = subprocess.run(
            [
                "curl", "-s", "-o", "/dev/null", "-w", "%{http_code}",
                "-X", "POST", send_url,
                "-H", f"Authorization: Bearer {token}",
                "-H", "Content-Type: application/json",
                "-d", f"@{tmp.name}",
            ],
            capture_output=True, text=True
        )
        status_code = result.stdout.strip()
        print(f"[INFO] HTTP status code: {status_code}")

        if status_code == "202":
            print("[SUCCESS] Notification email sent successfully!")
        else:
            print(f"[ERROR] Unexpected status code: {status_code}")
            # Re-run to capture response body for debugging
            result2 = subprocess.run(
                [
                    "curl", "-s",
                    "-X", "POST", send_url,
                    "-H", f"Authorization: Bearer {token}",
                    "-H", "Content-Type: application/json",
                    "-d", f"@{tmp.name}",
                ],
                capture_output=True, text=True
            )
            print(result2.stdout[:2000])
    finally:
        os.unlink(tmp.name)


def main():
    print("=" * 60)
    print("VWP BEC Incident - Phishing Notification Sender")
    print("=" * 60)

    # Step 1: Load and filter recipients
    bcc_recipients = load_recipients()

    # Print all recipients for verification
    print("\n[INFO] BCC recipient list:")
    for i, addr in enumerate(bcc_recipients, 1):
        print(f"  {i:3d}. {addr}")
    print(f"\n[INFO] Total BCC recipients: {len(bcc_recipients)}")
    print(f"[INFO] To recipient: {JR_EMAIL}")

    # Step 2: Get access token
    token = get_access_token()

    # Step 3: Send the email
    print(f"\n[INFO] Sending notification email...")
    send_notification(token, bcc_recipients)

    print("\n[OK] Done.")


if __name__ == "__main__":
    main()
