"""Utilities to extract the useful customer message from email/chat text.

This cleaner is intentionally conservative: it removes quoted history,
transport headers and common signatures before either deterministic guardrails
or the LLM see the text.  The goal is not to classify by rules; it is to avoid
feeding the assistant with footers, legal disclaimers and old messages.
"""
from __future__ import annotations

import re
from typing import Any, Dict


def get_nested(data: Dict[str, Any], *keys: str) -> Any:
    current: Any = data

    for key in keys:
        if not isinstance(current, dict):
            return None
        current = current.get(key)

    return current


def _cut_quoted_history(text: str) -> str:
    cut_markers = [
        "\nDe:",
        "\nDe ",
        "\nEnviada:",
        "\nEnviado:",
        "\nAssunto:",
        "\nPara:",
        "\nCc:",
        "\nÀs ",
        "\nA ",
        "\nOn ",
        "\nFrom:",
        "\nSent:",
        "\nSubject:",
        "\nTo:",
        "\nCc:",
        "\n-----Original Message-----",
        "\n------ Mensagem original ------",
        "\n-----Mensagem original-----",
        "\n________________________________",
        "\n---------------------------------------------------------------",
        "\n[Quoted text hidden]",
    ]
    cut_at = len(text)
    for marker in cut_markers:
        idx = text.find(marker)
        if idx != -1:
            cut_at = min(cut_at, idx)
    return text[:cut_at]


def _looks_like_signature_start(line: str) -> bool:
    normalized = re.sub(r"\s+", " ", line.strip().lower())
    if not normalized:
        return False
    starts = (
        "cumprimentos",
        "com os melhores cumprimentos",
        "melhores cumprimentos",
        "best regards",
        "regards",
        "atenciosamente",
        "cordiais cumprimentos",
        "cmpt",
        "cps",
        "enviado do meu",
        "sent from",
    )
    return any(normalized.startswith(item) for item in starts)


def _drop_signature_and_disclaimers(text: str) -> str:
    lines = text.split("\n")
    kept: list[str] = []
    non_empty = 0
    for line in lines:
        stripped = line.strip()
        low = stripped.lower()
        if stripped.startswith(">"):
            continue
        # Keep greetings at the top, but stop when the actual signature starts
        # after at least one meaningful line.
        if non_empty >= 1 and _looks_like_signature_start(stripped):
            break
        if any(marker in low for marker in [
            "aviso de confidencialidade",
            "esta mensagem pode conter informação confidencial",
            "this message may contain confidential",
            "se recebeu esta mensagem por engano",
            "before you print",
            "por favor tenha em atenção a sua responsabilidade ambiental",
            "por favor considere o impacto",
            "chamada para rede fixa nacional",
            "chamada para a rede móvel nacional",
        ]):
            break
        kept.append(line)
        if stripped:
            non_empty += 1
    return "\n".join(kept).strip()


def clean_email_reply_text(content: str) -> str:
    text = str(content or "").replace("\r\n", "\n").replace("\r", "\n").strip()
    text = _cut_quoted_history(text).strip()
    text = _drop_signature_and_disclaimers(text).strip()
    # Collapse excessive blank lines but preserve paragraph breaks.
    text = re.sub(r"\n{3,}", "\n\n", text)
    return text.strip()


def extract_customer_reply_text(task_or_payload: Dict[str, Any]) -> str:
    """Return the best available customer-authored text for reply generation."""
    data = task_or_payload or {}
    metadata = data.get("metadata") if isinstance(data.get("metadata"), dict) else {}
    message_metadata = data.get("message_metadata") if isinstance(data.get("message_metadata"), dict) else {}
    candidates = [
        data.get("request_text"),
        data.get("clean_body"),
        data.get("raw_body"),
        metadata.get("request_text"),
        metadata.get("customer_message"),
        message_metadata.get("clean_body"),
        message_metadata.get("raw_body"),
        data.get("message_subject"),
        data.get("note"),
    ]
    for candidate in candidates:
        cleaned = clean_email_reply_text(str(candidate or ""))
        if cleaned:
            return cleaned
    return ""


def extract_chatwoot_content(payload: Dict[str, Any], message: Dict[str, Any]) -> str:
    content = (
        get_nested(message, "content_attributes", "email", "html_content", "reply")
        or get_nested(message, "content_attributes", "email", "text_content", "reply")
        or get_nested(payload, "content_attributes", "email", "html_content", "reply")
        or get_nested(payload, "content_attributes", "email", "text_content", "reply")
        or message.get("processed_message_content")
        or message.get("content")
        or payload.get("content")
        or ""
    )

    return clean_email_reply_text(str(content or ""))
