"""Commercial reply templates for ClientFlow v4928.1.5.0.

Templates are deterministic and safe by default.  The opportunity/documents are
source of truth; optional LLM wording can adapt these drafts without choosing
prices, stock, fiscal documents or attachments.
"""
from __future__ import annotations

from dataclasses import dataclass, field
from typing import Dict, Iterable, List, Optional


@dataclass(frozen=True)
class MessageTemplate:
    code: str
    name: str
    category: str
    compatible_actions: tuple[str, ...]
    body: str
    expected_document_kinds: tuple[str, ...] = field(default_factory=tuple)
    requires_opportunity: bool = True
    requires_conversation: bool = True
    requires_fiscal_customer: bool = False
    complete_note: str = "Resposta enviada ao cliente via ClientFlow."
    reply_type: str = "send_document"

    def expects_documents(self) -> bool:
        return bool(self.expected_document_kinds)


TEMPLATES: Dict[str, MessageTemplate] = {
    "BUSINESS_KNOWLEDGE_REPLY": MessageTemplate(
        code="BUSINESS_KNOWLEDGE_REPLY",
        name="Resposta com conhecimento BLIF",
        category="conhecimento",
        compatible_actions=("SEND_INFO", "SEND_QUOTE", "SEND_PROFORMA", "SEND_INVOICE", "CONFIRM_PAYMENT", "PREPARE_ORDER", "REVIEW_MANUALLY"),
        body=(
            "Olá {customer_first_name},\n\n"
            "Segue a resposta com base no conhecimento comercial da BLIF.\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        requires_opportunity=False,
        requires_fiscal_customer=False,
        complete_note="Esclarecimento enviado ao cliente.",
        reply_type="answer_without_attachment",
    ),
    "LLM_BUSINESS_REPLY": MessageTemplate(
        code="LLM_BUSINESS_REPLY",
        name="Resposta LLM com conhecimento BLIF",
        category="llm",
        compatible_actions=("SEND_INFO", "SEND_QUOTE", "SEND_PROFORMA", "SEND_INVOICE", "CONFIRM_PAYMENT", "PREPARE_ORDER", "SUPPORT", "REVIEW_MANUALLY", "MARK_NO_INTEREST", "REMOVE_FROM_LIST"),
        body=(
            "Olá {customer_first_name},\n\n"
            "Vou analisar o pedido e responder com base no contexto e conhecimento aprovado da BLIF.\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        requires_opportunity=False,
        requires_conversation=False,
        requires_fiscal_customer=False,
        complete_note="Resposta assistida por LLM preparada para revisão.",
        reply_type="llm_assisted",
    ),
    "CLARIFY_INSTALLATION_SCOPE": MessageTemplate(
        code="CLARIFY_INSTALLATION_SCOPE",
        name="Esclarecer instalação / âmbito do preço",
        category="conhecimento",
        compatible_actions=("SEND_INFO", "SEND_QUOTE", "REVIEW_MANUALLY"),
        body=(
            "Olá {customer_first_name},\n\n"
            "Sim, confirmo que o valor indicado é referente ao equipamento, sem instalação incluída.\n\n"
            "A BLIF não presta serviço direto de instalação, mas o equipamento é de instalação simples e pode ser instalado por qualquer eletricista qualificado. Se necessário, prestamos suporte remoto ao eletricista.\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        requires_opportunity=False,
        requires_fiscal_customer=False,
        complete_note="Esclarecimento sobre instalação enviado ao cliente.",
        reply_type="answer_without_attachment",
    ),
    "CLARIFY_VAT_POLICY": MessageTemplate(
        code="CLARIFY_VAT_POLICY",
        name="Esclarecer IVA",
        category="conhecimento",
        compatible_actions=("SEND_INFO", "SEND_QUOTE", "SEND_PROFORMA", "SEND_INVOICE", "REVIEW_MANUALLY"),
        body=(
            "Olá {customer_first_name},\n\n"
            "Os valores indicados nas nossas comunicações comerciais são apresentados sem IVA. Na fatura final, os valores surgem com IVA incluído.\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        requires_opportunity=False,
        requires_fiscal_customer=False,
        complete_note="Esclarecimento sobre IVA enviado ao cliente.",
        reply_type="answer_without_attachment",
    ),
    "CLARIFY_DELIVERY_PAYMENT": MessageTemplate(
        code="CLARIFY_DELIVERY_PAYMENT",
        name="Esclarecer entrega/pagamento",
        category="conhecimento",
        compatible_actions=("SEND_INFO", "SEND_QUOTE", "SEND_PROFORMA", "CONFIRM_PAYMENT", "PREPARE_ORDER", "REVIEW_MANUALLY"),
        body=(
            "Olá {customer_first_name},\n\n"
            "A condição padrão é pronto pagamento. Após confirmação do pagamento, a entrega estimada é de 2–3 dias úteis.\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        requires_opportunity=False,
        requires_fiscal_customer=False,
        complete_note="Esclarecimento sobre entrega/pagamento enviado ao cliente.",
        reply_type="answer_without_attachment",
    ),
    "CLARIFY_RFID": MessageTemplate(
        code="CLARIFY_RFID",
        name="Esclarecer RFID",
        category="conhecimento",
        compatible_actions=("SEND_INFO", "SEND_QUOTE", "REVIEW_MANUALLY"),
        body=(
            "Olá {customer_first_name},\n\n"
            "Sim, os carregadores BLIF são compatíveis com leitor RFID. O leitor RFID tem o valor de 16 € s/IVA e permite associar cartões ilimitados para controlo de acessos e separação de consumos por utilizador.\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        requires_opportunity=False,
        requires_fiscal_customer=False,
        complete_note="Esclarecimento sobre RFID enviado ao cliente.",
        reply_type="answer_without_attachment",
    ),
    "CLARIFY_LOAD_BALANCER": MessageTemplate(
        code="CLARIFY_LOAD_BALANCER",
        name="Esclarecer balanceador",
        category="conhecimento",
        compatible_actions=("SEND_INFO", "SEND_QUOTE", "REVIEW_MANUALLY"),
        body=(
            "Olá {customer_first_name},\n\n"
            "Os carregadores BLIF podem funcionar com balanceador dinâmico de carga no quadro elétrico. O balanceador ajusta automaticamente a potência disponível e ajuda a evitar sobrecargas ou disparos do disjuntor.\n\n"
            "Em edifícios com vários pisos ou estrutura densa, recomendamos a versão com fios (Modbus).\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        requires_opportunity=False,
        requires_fiscal_customer=False,
        complete_note="Esclarecimento sobre balanceador enviado ao cliente.",
        reply_type="answer_without_attachment",
    ),
    "CLARIFY_LOCAL_HISTORY": MessageTemplate(
        code="CLARIFY_LOCAL_HISTORY",
        name="Esclarecer histórico sem Internet",
        category="conhecimento",
        compatible_actions=("SEND_INFO", "SEND_QUOTE", "REVIEW_MANUALLY"),
        body=(
            "Olá {customer_first_name},\n\n"
            "É possível consultar o histórico de carregamentos localmente, por Wi‑Fi/Bluetooth, mesmo sem Internet. O histórico pode incluir datas, duração e kWh por sessão; com RFID, permite separar por utilizador.\n\n"
            "Nota: o histórico local pode perder-se em caso de reset/factory reset.\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        requires_opportunity=False,
        requires_fiscal_customer=False,
        complete_note="Esclarecimento sobre histórico local enviado ao cliente.",
        reply_type="answer_without_attachment",
    ),
    "CLARIFY_CONDOMINIUM_MOBIE": MessageTemplate(
        code="CLARIFY_CONDOMINIUM_MOBIE",
        name="Esclarecer condomínio / MOBI.E DPC",
        category="conhecimento",
        compatible_actions=("SEND_INFO", "SEND_QUOTE", "REVIEW_MANUALLY"),
        body=(
            "Olá {customer_first_name},\n\n"
            "É viável instalar um carregador BLIF em garagem de condomínio, seja em box ou lugar partilhado, desde que exista ligação elétrica adequada.\n\n"
            "Quando o objetivo é separar consumos da fatura do condomínio, pode ser analisada a integração MOBI.E em modo DPC, que permite registo de sessões e faturação ao utilizador.\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        requires_opportunity=False,
        requires_fiscal_customer=False,
        complete_note="Esclarecimento sobre condomínio/MOBI.E enviado ao cliente.",
        reply_type="answer_without_attachment",
    ),
    "CLARIFY_TECHNICAL_FEATURES": MessageTemplate(
        code="CLARIFY_TECHNICAL_FEATURES",
        name="Esclarecer funcionalidades técnicas",
        category="conhecimento",
        compatible_actions=("SEND_INFO", "SEND_QUOTE", "REVIEW_MANUALLY"),
        body=(
            "Olá {customer_first_name},\n\n"
            "Os carregadores BLIF permitem controlo de potência entre 6 A e 32 A, gestão e monitorização através da app, controlo remoto e agendamento. O ajuste de corrente ajuda a evitar disparos do disjuntor quando a instalação está corretamente dimensionada.\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        requires_opportunity=False,
        requires_fiscal_customer=False,
        complete_note="Esclarecimento técnico enviado ao cliente.",
        reply_type="answer_without_attachment",
    ),

    "INTERNAL_BOUNCE_EMAIL": MessageTemplate(
        code="INTERNAL_BOUNCE_EMAIL",
        name="Bounce / email devolvido — não responder",
        category="triagem",
        compatible_actions=("SEND_INFO", "SEND_QUOTE", "REVIEW_MANUALLY"),
        body=(
            "Não enviar resposta ao cliente.\n\n"
            "Esta mensagem aparenta ser uma devolução automática de email/bounce. "
            "A ação recomendada é atualizar o contacto, validar o email e, se aplicável, remover o contacto de campanhas."
        ),
        requires_opportunity=False,
        requires_conversation=False,
        requires_fiscal_customer=False,
        complete_note="Bounce identificado; contacto deve ser revisto internamente.",
        reply_type="no_customer_reply",
    ),
    "MANUAL_REVIEW_REQUIRED": MessageTemplate(
        code="MANUAL_REVIEW_REQUIRED",
        name="Revisão manual — sem sugestão automática",
        category="triagem",
        compatible_actions=("SEND_INFO", "SEND_QUOTE", "SEND_PROFORMA", "SEND_INVOICE", "CONFIRM_PAYMENT", "PREPARE_ORDER", "REVIEW_MANUALLY"),
        body=(
            "Rever manualmente antes de responder.\n\n"
            "O assistente não encontrou intenção suficientemente segura para gerar uma resposta comercial automática."
        ),
        requires_opportunity=False,
        requires_conversation=False,
        requires_fiscal_customer=False,
        complete_note="Tarefa marcada para revisão manual.",
        reply_type="manual_internal",
    ),
    "INTERNAL_AUTO_REPLY": MessageTemplate(
        code="INTERNAL_AUTO_REPLY",
        name="Resposta automática / ausência — não responder",
        category="triagem",
        compatible_actions=("SEND_INFO", "SEND_QUOTE", "REVIEW_MANUALLY"),
        body=(
            "Não enviar resposta ao cliente.\n\n"
            "Esta mensagem aparenta ser uma resposta automática/ausência. A ação recomendada é aguardar ou rever manualmente, sem enviar conteúdo comercial."
        ),
        requires_opportunity=False,
        requires_conversation=False,
        requires_fiscal_customer=False,
        complete_note="Resposta automática identificada; sem resposta ao cliente.",
        reply_type="no_customer_reply",
    ),
    "ACK_UNSUBSCRIBE": MessageTemplate(
        code="ACK_UNSUBSCRIBE",
        name="Confirmar remoção da lista",
        category="triagem",
        compatible_actions=("SEND_INFO", "SEND_QUOTE", "REVIEW_MANUALLY"),
        body=(
            "Olá {customer_first_name},\n\n"
            "Confirmamos a receção do pedido e vamos remover/atualizar o contacto para não receber novas comunicações comerciais.\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        requires_opportunity=False,
        requires_fiscal_customer=False,
        complete_note="Pedido de remoção/privacidade respondido ao cliente.",
        reply_type="operational_ack",
    ),
    "ACK_ADDRESS_UPDATE": MessageTemplate(
        code="ACK_ADDRESS_UPDATE",
        name="Confirmar atualização de contacto",
        category="triagem",
        compatible_actions=("SEND_INFO", "SEND_QUOTE", "REVIEW_MANUALLY"),
        body=(
            "Olá {customer_first_name},\n\n"
            "Obrigado pela informação. Vamos atualizar o contacto nos nossos registos.\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        requires_opportunity=False,
        requires_fiscal_customer=False,
        complete_note="Atualização de contacto confirmada ao cliente.",
        reply_type="operational_ack",
    ),
    "ACK_NO_INTEREST": MessageTemplate(
        code="ACK_NO_INTEREST",
        name="Responder sem interesse",
        category="triagem",
        compatible_actions=("SEND_INFO", "SEND_QUOTE", "REVIEW_MANUALLY"),
        body=(
            "Olá {customer_first_name},\n\n"
            "Obrigado pelo feedback. Registamos a informação e não insistiremos neste contacto comercial.\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        requires_opportunity=False,
        requires_fiscal_customer=False,
        complete_note="Sem interesse registado e respondido ao cliente.",
        reply_type="operational_ack",
    ),
    "ACK_SUPPORT_RECEIVED": MessageTemplate(
        code="ACK_SUPPORT_RECEIVED",
        name="Acusar receção de suporte/incidente",
        category="suporte",
        compatible_actions=("SEND_INFO", "SEND_QUOTE", "REVIEW_MANUALLY", "PREPARE_ORDER"),
        body=(
            "Olá {customer_first_name},\n\n"
            "Lamentamos a situação. Vamos verificar internamente o estado do processo e dar seguimento com prioridade.\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        requires_opportunity=False,
        requires_fiscal_customer=False,
        complete_note="Incidente/suporte acusado ao cliente.",
        reply_type="support_ack",
    ),
    "ACK_CALLBACK_REQUEST": MessageTemplate(
        code="ACK_CALLBACK_REQUEST",
        name="Confirmar pedido de contacto",
        category="triagem",
        compatible_actions=("SEND_INFO", "SEND_QUOTE", "REVIEW_MANUALLY"),
        body=(
            "Olá {customer_first_name},\n\n"
            "Obrigado pelo contacto. Vamos analisar o pedido e responder/entrar em contacto assim que possível.\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        requires_opportunity=False,
        requires_fiscal_customer=False,
        complete_note="Pedido de contacto acusado ao cliente.",
        reply_type="operational_ack",
    ),
    "SEND_INFO_EQUIPMENT_LIST": MessageTemplate(
        code="SEND_INFO_EQUIPMENT_LIST",
        name="Enviar lista de equipamentos",
        category="informacao",
        compatible_actions=("SEND_INFO", "SEND_QUOTE", "REVIEW_MANUALLY"),
        body=(
            "Olá {customer_first_name},\n\n"
            "Segue abaixo a lista de equipamentos disponíveis:\n\n"
            "- Carregador EV monofásico 7,4 kW\n"
            "- Carregador EV trifásico 11 kW\n"
            "- Carregador EV trifásico 22 kW\n\n"
            "Todos os equipamentos incluem fatura, garantia e apoio técnico.\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        requires_opportunity=False,
        requires_fiscal_customer=False,
        complete_note="Lista de equipamentos enviada ao cliente.",
        reply_type="answer_without_attachment",
    ),
    "SEND_PRICE_LIST": MessageTemplate(
        code="SEND_PRICE_LIST",
        name="Enviar preços indicativos",
        category="informacao",
        compatible_actions=("SEND_INFO", "SEND_QUOTE", "REVIEW_MANUALLY"),
        body=(
            "Olá {customer_first_name},\n\n"
            "Segue a informação de preços disponível para os equipamentos solicitados.\n\n"
            "Os valores finais devem ser confirmados no orçamento/proposta antes de adjudicação.\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        requires_opportunity=False,
        requires_fiscal_customer=False,
        complete_note="Preços indicativos enviados ao cliente.",
        reply_type="answer_without_attachment",
    ),
    "SEND_QUOTE": MessageTemplate(
        code="SEND_QUOTE",
        name="Enviar orçamento/proposta",
        category="proposta",
        compatible_actions=("SEND_QUOTE", "SEND_INFO", "REVIEW_MANUALLY"),
        # SEND_QUOTE pode ser uma proposta textual quando ainda não existe ORC.*.
        # Se o operador selecionar um documento, validamos que é quotation.
        expected_document_kinds=("quotation",),
        requires_fiscal_customer=False,
        body=(
            "Olá {customer_first_name},\n\n"
            "Segue abaixo a proposta/preços indicativos para o pedido.\n\n"
            "Se pretender avançar, confirmamos os dados necessários e preparamos o orçamento formal.\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        complete_note="Orçamento/proposta enviado ao cliente.",
        reply_type="send_document_or_text_quote",
    ),
    "SEND_PROFORMA": MessageTemplate(
        code="SEND_PROFORMA",
        name="Enviar orçamento para pagamento (ORC Jasmin)",
        category="documento",
        compatible_actions=("SEND_PROFORMA", "SEND_INVOICE", "REVIEW_MANUALLY"),
        # Regra BLIF/ClientFlow: a orçamento para pagamento operacional é o orçamento Jasmin ORC.*.
        # Não exigir um tipo documental separado "proforma"; o documento correto é quotation.
        expected_document_kinds=("quotation",),
        requires_fiscal_customer=True,
        body=(
            "Olá {customer_first_name},\n\n"
            "Segue em anexo o orçamento {document_numbers} para pagamento e avanço da encomenda.\n\n"
            "Após o pagamento, envie por favor o comprovativo para confirmação e preparação da encomenda.\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        complete_note="Orçamento para pagamento/ORC Jasmin enviada ao cliente.",
        reply_type="send_document",
    ),
    "SEND_INVOICE": MessageTemplate(
        code="SEND_INVOICE",
        name="Enviar fatura",
        category="documento",
        compatible_actions=("SEND_INVOICE", "SEND_PROFORMA", "REVIEW_MANUALLY"),
        expected_document_kinds=("invoice",),
        requires_fiscal_customer=True,
        body=(
            "Olá {customer_first_name},\n\n"
            "Segue em anexo a fatura {document_numbers}.\n\n"
            "Qualquer questão, estamos ao dispor.\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        complete_note="Fatura enviada ao cliente.",
        reply_type="send_document",
    ),
    "REQUEST_FISCAL_DATA": MessageTemplate(
        code="REQUEST_FISCAL_DATA",
        name="Pedir dados fiscais",
        category="dados",
        compatible_actions=("SEND_PROFORMA", "SEND_INVOICE", "SEND_QUOTE", "REVIEW_MANUALLY"),
        body=(
            "Olá {customer_first_name},\n\n"
            "Para avançarmos corretamente, envie por favor os dados fiscais para faturação:\n\n"
            "- Nome fiscal\n"
            "- NIF\n"
            "- Morada fiscal\n"
            "- Email para envio do documento\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        requires_opportunity=False,
        requires_fiscal_customer=False,
        complete_note="Pedido de dados fiscais enviado ao cliente.",
        reply_type="request_missing_data",
    ),
    "REQUEST_PAYMENT_PROOF": MessageTemplate(
        code="REQUEST_PAYMENT_PROOF",
        name="Pedir comprovativo de pagamento",
        category="pagamento",
        compatible_actions=("CONFIRM_PAYMENT", "SEND_PROFORMA", "REVIEW_MANUALLY"),
        body=(
            "Olá {customer_first_name},\n\n"
            "Para conseguirmos confirmar o processo, envie por favor o comprovativo de pagamento.\n\n"
            "Assim que recebermos a confirmação, damos seguimento à encomenda.\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        requires_opportunity=False,
        requires_fiscal_customer=False,
        complete_note="Pedido de comprovativo de pagamento enviado ao cliente.",
        reply_type="request_missing_data",
    ),
    "CONFIRM_PAYMENT_RECEIVED": MessageTemplate(
        code="CONFIRM_PAYMENT_RECEIVED",
        name="Confirmar pagamento recebido",
        category="pagamento",
        compatible_actions=("CONFIRM_PAYMENT", "PREPARE_ORDER", "REVIEW_MANUALLY"),
        body=(
            "Olá {customer_first_name},\n\n"
            "Confirmamos a receção do pagamento.\n\n"
            "Vamos dar seguimento à preparação da encomenda e manteremos o contacto com a atualização do envio.\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        requires_opportunity=False,
        requires_fiscal_customer=False,
        complete_note="Pagamento confirmado ao cliente.",
        reply_type="answer_without_attachment",
    ),
    "FOLLOW_UP_QUOTE": MessageTemplate(
        code="FOLLOW_UP_QUOTE",
        name="Follow-up de orçamento/proposta",
        category="followup",
        compatible_actions=("FOLLOW_UP_QUOTE", "FOLLOW_UP_GENERIC", "SEND_QUOTE", "REVIEW_MANUALLY"),
        expected_document_kinds=("quotation",),
        body=(
            "Olá {customer_first_name},\n\n"
            "Gostaria apenas de confirmar se recebeu a proposta/orçamento {document_numbers} "
            "e se ficou com alguma dúvida.\n\n"
            "Caso pretenda avançar, posso também enviar os dados para emissão da orçamento para pagamento.\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        requires_opportunity=False,
        requires_conversation=False,
        requires_fiscal_customer=False,
        complete_note="Follow-up de orçamento/proposta enviado ao cliente.",
        reply_type="follow_up",
    ),
    "FOLLOW_UP_PROFORMA": MessageTemplate(
        code="FOLLOW_UP_PROFORMA",
        name="Follow-up de orçamento para pagamento",
        category="followup",
        compatible_actions=("FOLLOW_UP_PROFORMA", "FOLLOW_UP_PAYMENT", "FOLLOW_UP_GENERIC", "SEND_PROFORMA", "REVIEW_MANUALLY"),
        expected_document_kinds=("proforma", "invoice", "quotation"),
        body=(
            "Olá {customer_first_name},\n\n"
            "Gostaria apenas de confirmar se recebeu a orçamento/dados de pagamento {document_numbers} "
            "e se precisa de alguma informação adicional para avançar.\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        requires_opportunity=False,
        requires_conversation=False,
        requires_fiscal_customer=False,
        complete_note="Follow-up de orçamento para pagamento enviado ao cliente.",
        reply_type="follow_up",
    ),
    "FOLLOW_UP_PAYMENT": MessageTemplate(
        code="FOLLOW_UP_PAYMENT",
        name="Follow-up de pagamento",
        category="followup",
        compatible_actions=("FOLLOW_UP_PAYMENT", "FOLLOW_UP_PROFORMA", "CONFIRM_PAYMENT", "REVIEW_MANUALLY"),
        expected_document_kinds=("proforma", "invoice", "quotation"),
        body=(
            "Olá {customer_first_name},\n\n"
            "Gostaria apenas de confirmar se recebeu a orçamento/dados de pagamento {document_numbers} "
            "e se precisa de alguma informação adicional para avançar com o pagamento.\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        requires_opportunity=False,
        requires_conversation=False,
        requires_fiscal_customer=False,
        complete_note="Follow-up de pagamento enviado ao cliente.",
        reply_type="follow_up",
    ),
    "FOLLOW_UP_CUSTOMER_REVIEW": MessageTemplate(
        code="FOLLOW_UP_CUSTOMER_REVIEW",
        name="Follow-up de interesse/revisão",
        category="followup",
        compatible_actions=("FOLLOW_UP_CUSTOMER_REVIEW", "FOLLOW_UP_GENERIC", "SEND_INFO", "REVIEW_MANUALLY"),
        body=(
            "Olá {customer_first_name},\n\n"
            "Gostaria apenas de confirmar se mantém interesse no carregador e se precisa de alguma informação adicional.\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        requires_opportunity=False,
        requires_conversation=False,
        requires_fiscal_customer=False,
        complete_note="Follow-up de interesse enviado ao cliente.",
        reply_type="follow_up",
    ),
    "FOLLOW_UP_GENERIC": MessageTemplate(
        code="FOLLOW_UP_GENERIC",
        name="Follow-up genérico",
        category="followup",
        compatible_actions=("FOLLOW_UP_GENERIC", "FOLLOW_UP_QUOTE", "FOLLOW_UP_PAYMENT", "FOLLOW_UP_CUSTOMER_REVIEW", "REVIEW_MANUALLY"),
        body=(
            "Olá {customer_first_name},\n\n"
            "Gostaria apenas de dar seguimento ao processo e confirmar se precisa de alguma informação adicional.\n\n"
            "Cumprimentos,\nEquipa BLIF"
        ),
        requires_opportunity=False,
        requires_conversation=False,
        requires_fiscal_customer=False,
        complete_note="Follow-up enviado ao cliente.",
        reply_type="follow_up",
    ),
}


# Intent gate fallback anchor: "SEND_INFO": "MANUAL_REVIEW_REQUIRED"
DEFAULT_TEMPLATE_BY_ACTION: Dict[str, str] = {
    "SEND_INFO": "SEND_INFO_EQUIPMENT_LIST",
    "SEND_QUOTE": "SEND_QUOTE",
    "SEND_PROFORMA": "SEND_PROFORMA",
    "SEND_INVOICE": "SEND_INVOICE",
    "CONFIRM_PAYMENT": "REQUEST_PAYMENT_PROOF",
    "PREPARE_ORDER": "CONFIRM_PAYMENT_RECEIVED",
    "FOLLOW_UP_QUOTE": "FOLLOW_UP_QUOTE",
    "FOLLOW_UP_PROFORMA": "FOLLOW_UP_PROFORMA",
    "FOLLOW_UP_PAYMENT": "FOLLOW_UP_PAYMENT",
    "FOLLOW_UP_CUSTOMER_REVIEW": "FOLLOW_UP_CUSTOMER_REVIEW",
    "FOLLOW_UP_GENERIC": "FOLLOW_UP_GENERIC",
    "REVIEW_MANUALLY": "MANUAL_REVIEW_REQUIRED",
}


def get_template(code: Optional[str]) -> Optional[MessageTemplate]:
    return TEMPLATES.get(str(code or "").strip().upper())


def default_template_for_action(action_code: Optional[str]) -> MessageTemplate:
    code = DEFAULT_TEMPLATE_BY_ACTION.get(str(action_code or "").strip().upper(), "MANUAL_REVIEW_REQUIRED")
    return TEMPLATES[code]


def list_templates_for_action(action_code: Optional[str] = None) -> List[MessageTemplate]:
    action = str(action_code or "").strip().upper()
    items: Iterable[MessageTemplate] = TEMPLATES.values()
    if action:
        filtered = [tpl for tpl in items if action in tpl.compatible_actions or "REVIEW_MANUALLY" in tpl.compatible_actions]
        return sorted(filtered, key=lambda tpl: (tpl.category, tpl.name))
    return sorted(items, key=lambda tpl: (tpl.category, tpl.name))
