from __future__ import annotations

from app.domain.contas.workflow_actions import build_contas_workflow_actions


class Client:
    def __init__(self):
        self.sms_args=None; self.status_payload=None; self.tracking_payload=None; self.protocol_payload=None
        self.fail_protocol=False; self.fail_status=False
    def sms(self, msisdn, message, **ctx):
        self.sms_args=(msisdn,message,ctx)
        return {"resource_url":"http://sms/mock","_transport":{"attempts":[{"api_url":"http://mock/sms","status_code":200,"latency_ms":1}]}}
    def status_sr(self,payload):
        self.status_payload=payload
        if self.fail_status: raise RuntimeError("status fail")
        return {"ok":True,"_transport":{"attempts":[{"api_url":"http://mock/status","status_code":200,"latency_ms":1}]}}
    def tracking(self,payload): self.tracking_payload=payload; return {"ok":True}
    def abrir_protocolo(self,payload):
        self.protocol_payload=payload
        if self.fail_protocol: raise RuntimeError("gateway indisponivel")
        return {"interactionProtocol":"CCM-1"}

class Service:
    def __init__(self): self.client=Client()


def test_sms_usa_barcode_titular_e_payload_padrao():
    s=Service(); a=build_contas_workflow_actions(s).get("enviar_sms")
    out=a({"msisdn":"15981110643"},{"input":{"msisdn":"11964200059"},"vars":{"abrir_contestacao_cliente":{"barcode":"3419179001"}}})
    assert out["success"] is True
    msisdn,message,ctx=s.client.sms_args
    assert msisdn == "15981110643"
    assert message == "Codigo do boleto: 3419179001"
    assert ctx["sender_name"] == "TIM Brasil"
    assert ctx["long_url"] == "https://meutim.com.br"
    assert out["sms_not_send_error"] is False


def test_sms_falha_nao_interrompe_fluxo_e_marca_flag():
    s=Service()
    def fail(*args,**kwargs): raise RuntimeError("sms fail")
    s.client.sms=fail
    a=build_contas_workflow_actions(s).get("enviar_sms")
    out=a({"msisdn":"119"},{"input":{}})
    assert out["success"] is True
    assert out["sms_sent"] is False
    assert out["sms_not_send_error"] is True


def test_conta_certa_manual_falha_api_e_best_effort():
    s=Service(); s.client.fail_protocol=True
    a=build_contas_workflow_actions(s).get("abrir_sr_conta_certa_manual")
    out=a({"msisdn":"119","social_sec_no":"123","dia_vencimento":"20"},{"input":{}})
    assert out["success"] is True
    assert out["status"] == "Encaminhado"
    assert out["sr_conta_certa_id"] == ""
    assert out["conta_certa_manual_error"] is True
    assert s.client.protocol_payload["reason3"].endswith("20")


def test_status_sr_sms_path_e_tracking_completo():
    s=Service(); a=build_contas_workflow_actions(s).get("atualizar_status_sr")
    state={"input":{},"vars":{
        "registrar_protocolo":{"protocolo_id":"PRT-10"},
        "enviar_sms":{"sms_sent":True,"sms_not_send_error":False},
        "check_invoice_status":{"open_invoices":[{"invoiceId":"300","invoiceStatus":"A Vencer","issueDate":"2026-06-01","dueDate":"2026-06-20","openAmount":"349.29","amount":"349.29"}]},
    }}
    out=a({"msisdn":"119","scenario":"contestacao","current_invoice_number":"300","social_sec_no":"123.456.789-01","invoice_amount_open":"349.29","invoice_amount":"349.29"},state)
    assert out["success"] is True and out["protocol_closed"] is True
    assert out["format_text"] == "sms" and out["resolution_type"] == "new_boleto"
    assert s.client.status_payload["reason1"] == "Reclamação"
    assert s.client.status_payload["reason2"] == "Conta"
    assert s.client.status_payload["reason3"] == "Valor"
    assert s.client.tracking_payload["protocolNumber"] == "PRT-10"
    assert s.client.tracking_payload["invoiceEmissionDate"] == "2026-06-01T00:00:00.00Z"
    assert s.client.tracking_payload["invoiceExpirationDate"] == "2026-06-20T00:00:00.00Z"
    assert s.client.tracking_payload["invoiceStatus"] == "Aberto"


def test_status_sr_nao_faz_tracking_de_fatura_errada():
    s=Service(); a=build_contas_workflow_actions(s).get("atualizar_status_sr")
    state={"vars":{"registrar_protocolo":{"protocolo_id":"P"},"check_invoice_status":{"open_invoices":[{"invoiceId":"OTHER"}]}}}
    out=a({"msisdn":"119","scenario":"contestacao","current_invoice_number":"TARGET"},state)
    assert out["success"] is True
    assert s.client.tracking_payload is None
