"""
EmailMessagingGraph.py
----------------------
Private Microsoft Graph mail sender
Application permissions, shared mailbox
"""

import msal
import requests
from functools import lru_cache
from typing import Union, List


# =========================
# PRIVATE CONFIG (ONLY YOU)
# =========================
TENANT_ID = "7d269944-37a4-43a1-8140-c7517dc426e9"
CLIENT_ID = "4b222bfd-78c9-4239-a53f-43006b3ed07f"
CLIENT_SECRET = "Txg8Q~MjhocuopxsJyJBhPmDfMxZ2r5WpTFj1dfk"
SENDER = "reports@buzalka.cz"


AUTHORITY = f"https://login.microsoftonline.com/{TENANT_ID}"
SCOPE = ["https://graph.microsoft.com/.default"]


@lru_cache(maxsize=1)
def _get_token() -> str:
    app = msal.ConfidentialClientApplication(
        CLIENT_ID,
        authority=AUTHORITY,
        client_credential=CLIENT_SECRET,
    )

    token = app.acquire_token_for_client(scopes=SCOPE)

    if "access_token" not in token:
        raise RuntimeError(f"Graph auth failed: {token}")

    return token["access_token"]


def send_mail(
    to: Union[str, List[str]],
    subject: str,
    body: str,
    *,
    html: bool = False,
):
    """
    Send email via Microsoft Graph.

    :param to: email or list of emails
    :param subject: subject
    :param body: email body
    :param html: True = HTML, False = plain text
    """

    if isinstance(to, str):
        to = [to]

    payload = {
        "message": {
            "subject": subject,
            "body": {
                "contentType": "HTML" if html else "Text",
                "content": body,
            },
            "toRecipients": [
                {"emailAddress": {"address": addr}} for addr in to
            ],
        },
        "saveToSentItems": "true",
    }

    headers = {
        "Authorization": f"Bearer {_get_token()}",
        "Content-Type": "application/json",
    }

    r = requests.post(
        f"https://graph.microsoft.com/v1.0/users/{SENDER}/sendMail",
        headers=headers,
        json=payload,
        timeout=30,
    )

    if r.status_code != 202:
        raise RuntimeError(
            f"sendMail failed [{r.status_code}]: {r.text}"
        )
