from __future__ import annotations

from typing import Any

from app.domain.contas.pro_rata_rules import calculate_refund, payment_message
from app.domain.contas.workflow_actions import build_contas_workflow_actions


def planos(*, days_other=25, liquid=67.99):
    return [
        {"desc":"TIM Controle Smart 8 0 (096/POS/SMP)","days":None,"valor_bruto":92.99,"valor_final":liquid,"msisdn":"44998254771","is_controle":True},
        {"desc":"TIM Black A 8 0 (114/POS/SMP)","days":days_other,"valor_bruto":158.30,"valor_final":83.38,"msisdn":"44998254771","is_controle":False},
    ]


def invoice(danfe=None):
    return {
        "Fatura Resumo":[{"desc":"PERÍODO","period":"19/09 a 18/10"},{"desc":"EMISSÃO","emissao":"29/10/2025"}],
        "DANFE-COM": danfe or {"Planos":{"TIM Controle Smart 8 0":[
            {"desc":"TIM Controle Smart 8 0","valor_final":40.0},
            {"desc":"Aya Books Premium","valor_final":15.0},
            {"desc":"Mulheres Positivas","valor_final":10.0},
        ]}},
    }


def test_calculo_pro_rata_usa_liquido_periodo_e_danfe():
    out=calculate_refund(planos=planos(), invoice_detail=invoice())
    assert out["dias_ciclo"] == 30
    assert out["dias_controle"] == 5
    assert out["valor_liquido"] == "67.99"
    assert out["valor_devolver"] == "56.66"
    assert out["invoice_amount"] == "56.66"
    assert [x["itemName"] for x in out["items"]] == ["TIM Controle Smart 8 0","Aya Books Premium","Mulheres Positivas"]
    assert sum(float(x["validatedAmount"]) for x in out["items"]) == 56.66


def test_calculo_pro_rata_outro_plano_30_dias_considera_um_dia_controle():
    out=calculate_refund(planos=planos(days_other=30), invoice_detail=invoice({"Planos":{"TIM Controle Smart 8 0":[{"desc":"TIM Controle Smart 8 0","valor_final":67.99}]}}))
    assert out["dias_controle"] == 1
    assert float(out["valor_devolver"]) > 65


def test_calculo_falha_sem_periodo():
    data=invoice(); data["Fatura Resumo"]=[]
    try:
        calculate_refund(planos=planos(), invoice_detail=data)
    except ValueError as exc:
        assert "Periodo" in str(exc)
    else:
        raise AssertionError("esperava falha")


def test_calculo_falha_quando_danfe_nao_cobre_credito():
    data=invoice({"Planos":{"TIM Controle Smart 8 0":[{"desc":"TIM Controle Smart 8 0","valor_final":1.0}]}})
    try:
        calculate_refund(planos=planos(), invoice_detail=data)
    except ValueError as exc:
        assert "insuficientes" in str(exc)
    else:
        raise AssertionError("esperava falha")


def test_mensagem_pagamento_sms_soma_items_e_protocolo():
    msg=payment_message({
        "items":[{"itemName":"Plano X","validatedAmount":10},{"itemName":"Extra","validatedAmount":4.99}],
        "format_text":"sms","barcode":"123","protocolo_id":"9988"
    })
    assert "R$ 14,99" in msg
    assert "codigo de barras atualizado" in msg
    assert "9988" in msg


class Client:
    def __init__(self): self.payload=None
    def contestar(self,payload):
        self.payload=payload
        return {"protocol_number":"PRT-1","sms_sent":True,"barcode":"3419","contestation_id":"C-1"}

class Service:
    def __init__(self): self.client=Client()
    def buscar_fatura_detalhada(self, **kwargs): return {"parsed_content":invoice()}


def test_action_definir_devolucao_busca_danfe_quando_ausente():
    svc=Service(); reg=build_contas_workflow_actions(svc)
    action=reg.get("definir_devolucao_ajuste_pro_rata")
    out=action({"planos":planos(),"invoice_id":"INV","customer_id":"C","msisdn":"44998254771"},{"input":{}})
    assert out["success"] is True
    assert out["invoice_amount"] == "56.66"
    assert out["items"]


def test_action_contestacao_pro_rata_usa_items_e_totais():
    svc=Service(); reg=build_contas_workflow_actions(svc)
    action=reg.get("executar_contestacao_plano_controle")
    devolucao={"items":[{"itemName":"Plano X","itemType":"PRO_RATA","claimedAmount":20.0,"validatedAmount":12.5}],"invoice_amount":"12.50","invoice_amount_open":"12.50"}
    out=action({"devolucao":devolucao,"msisdn":"44998254771","customer_id":"C1","invoice_id":"I1","cpf":"123.456.789-00"},{"input":{}})
    assert out["success"] is True
    assert svc.client.payload["tipo_atendimento"] == "pro_rata"
    assert svc.client.payload["skip_invoice_item_validation"] is True
    assert svc.client.payload["invoiceAmount"] == "12.50"
    assert svc.client.payload["socialSecNo"] == "12345678900"
    assert out["devolucao"]["format_text"] == "sms"


def test_orientar_pagamento_mantem_composicao_no_llm_do_framework():
    svc=Service(); reg=build_contas_workflow_actions(svc)
    action=reg.get("orientar_pagamento_pro_rata")
    out=action({"devolucao":{"items":[{"itemName":"Plano X","validatedAmount":10}],"format_text":"conta_futura"}},{"input":{}})
    assert "R$ 10,00" in out["mensagem"]
    assert out["requires_llm_composition"] is True
    assert "fonte de verdade" in out["response_instruction"]
