from datetime import date

from ccma.domain.contributions import claim_status
from ccma.rules.api import RuleContext, task

RULE_ID = "claim-status"
ORDER = 50

# Overdue claims (delta < 0) are handled entirely by reminder-due: it owns the whole
# overdue lifecycle (grace period, dunning escalation, SEPA follow-up) so there is
# exactly one finding per overdue claim instead of this rule and that one both firing
# for the same problem.


def evaluate(context: RuleContext):
    actions = []
    for claim in context.contributions.claims:
        if claim_status(context.contributions, claim, today=context.today) not in {
            "open",
            "partially_paid",
            "overdue",
        }:
            continue
        try:
            due = date.fromisoformat(str(claim.get("due_date", "")))
        except ValueError:
            continue
        delta = (due - context.today).days
        if delta < 0 or delta > 14:
            continue
        claim_key = str(claim.get("claim_key") or claim.get("claim_id") or "unknown")
        title = str(claim.get("title") or "Beitragsforderung")
        claim_type = str(claim.get("type", ""))
        actions.append(
            task(
                rule_id=RULE_ID,
                member=context.member,
                key_suffix=f"due-soon:{claim_key}",
                severity="info",
                title=f"{context.member.display_name}: {title} bald fällig",
                detail=f"Fälligkeit in {delta} Tagen.",
                due_date=due,
                code="initial_payment_due_soon" if claim_type == "admission_fee" else "claim_due_soon",
            )
        )
    return actions
