import json from collections.abc import Mapping from typing import Any from app.services.integrations.events import ( ORDER_CANCELLED_EVENT, ORDER_CREATED_EVENT, RENTAL_OPENED_EVENT, RENTAL_PAYMENT_REGISTERED_EVENT, RENTAL_RETURN_REGISTERED_EVENT, REVIEW_SCHEDULED_EVENT, ) DEFAULT_EMAIL_TEMPLATES = { ORDER_CREATED_EVENT: { "subject": "[Orquestrador] Pedido criado {numero_pedido}", "body": """Um pedido de veiculo foi criado com sucesso. Numero: {numero_pedido} Veiculo: {modelo_veiculo} Valor: R$ {valor_veiculo} CPF: {cpf} Status: {status} Status do veiculo: {status_veiculo}""", }, ORDER_CANCELLED_EVENT: { "subject": "[Orquestrador] Pedido cancelado {numero_pedido}", "body": """Um pedido foi cancelado. Numero: {numero_pedido} Status: {status} Motivo: {motivo} Data cancelamento: {data_cancelamento}""", }, REVIEW_SCHEDULED_EVENT: { "subject": "[Orquestrador] Revisao agendada {protocolo}", "body": """Uma revisao foi agendada. Protocolo: {protocolo} Placa: {placa} Data e hora: {data_hora} Modelo: {modelo} Ano: {ano} KM: {km} Valor estimado: R$ {valor_revisao}""", }, RENTAL_OPENED_EVENT: { "subject": "[Orquestrador] Locacao aberta {contrato_numero}", "body": """Uma locacao foi aberta. Contrato: {contrato_numero} Veiculo: {modelo_veiculo} Placa: {placa} Inicio: {data_inicio} Devolucao prevista: {data_fim_prevista} Diaria: R$ {valor_diaria} Valor previsto: R$ {valor_previsto} Status: {status}""", }, RENTAL_PAYMENT_REGISTERED_EVENT: { "subject": "[Orquestrador] Pagamento de aluguel {protocolo}", "body": """Um pagamento de aluguel foi registrado. Protocolo: {protocolo} Contrato: {contrato_numero} Placa: {placa} Valor: R$ {valor} Data pagamento: {data_pagamento} Favorecido: {favorecido}""", }, RENTAL_RETURN_REGISTERED_EVENT: { "subject": "[Orquestrador] Devolucao registrada {contrato_numero}", "body": """Uma devolucao de locacao foi registrada. Contrato: {contrato_numero} Veiculo: {modelo_veiculo} Placa: {placa} Data devolucao: {data_devolucao} Valor previsto: R$ {valor_previsto} Valor final: R$ {valor_final} Status: {status}""", }, } class _SafeTemplateData(dict): def __missing__(self, key: str) -> str: return "" def _normalize_template_value(value: Any) -> str: if value is None: return "" if isinstance(value, bool): return "sim" if value else "nao" if isinstance(value, (list, tuple, dict)): return json.dumps(value, ensure_ascii=True, default=str, sort_keys=True) return str(value) def build_template_context(payload: Mapping[str, Any] | None) -> dict[str, str]: context = _SafeTemplateData() for key, value in dict(payload or {}).items(): context[str(key)] = _normalize_template_value(value) return context def render_email_content( *, event_type: str, payload: Mapping[str, Any] | None, subject_template: str | None = None, body_template: str | None = None, ) -> tuple[str, str]: defaults = DEFAULT_EMAIL_TEMPLATES.get( event_type, { "subject": "[Orquestrador] Evento {event_type}", "body": "Payload do evento {event_type}:\n{payload_json}", }, ) context = build_template_context(payload) context.setdefault("event_type", event_type) context.setdefault("payload_json", _normalize_template_value(payload)) subject = str(subject_template or defaults["subject"]).format_map(context).strip() body = str(body_template or defaults["body"]).format_map(context).strip() return subject, body