from __future__ import annotations

from datetime import datetime
from decimal import Decimal, InvalidOperation, ROUND_HALF_UP

import pendulum


def clean_money(value) -> Decimal:
    text = str(value or "").replace("$", "").replace(",", "").strip()
    if not text:
        return Decimal("0")
    try:
        return Decimal(text)
    except InvalidOperation:
        return Decimal("0")


def clean_int(value) -> int:
    try:
        return max(0, int(str(value or "0").strip()))
    except ValueError:
        return 0


def money(value: Decimal) -> str:
    value = value.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
    return f"${value:,.2f}"


def parse_date(value):
    text = str(value or "").strip()
    if not text:
        return None

    for fmt in ("YYYY-MM-DD", "MM/DD/YYYY", "MM-DD-YYYY"):
        try:
            return pendulum.from_format(text, fmt)
        except Exception:
            pass

    try:
        return pendulum.parse(text)
    except Exception:
        return None


def format_date(value) -> str:
    if not value:
        return ""
    return value.format("MMMM Do, YYYY")


def add_months(date_value, months: int):
    if not date_value:
        return None
    return date_value.add(months=months)


def add_last_four_fields(data: dict) -> dict:
    # Existing old-template compatibility.
    for key, value in list(data.items()):
        if not key.endswith("Account"):
            continue

        base = key[:-len("Account")]
        digits = "".join(ch for ch in str(value or "") if ch.isdigit())
        data[f"{base}AccLastFour"] = digits[-4:] if len(digits) >= 4 else digits

    ssn = "".join(ch for ch in str(data.get("SSN", "")) if ch.isdigit())
    if ssn:
        data["SSNLastFour"] = ssn[-4:]

    ssn2 = "".join(ch for ch in str(data.get("client2SSN", "")) if ch.isdigit())
    if ssn2:
        data["SSN2LastFour"] = ssn2[-4:]

    return data


def add_case_filename_fields(data: dict) -> dict:
    plaintiff = str(data.get("casePlaintiff", "") or "")
    data["casePlaintiffFileName"] = plaintiff.replace(" ", "-").replace(",", "").replace(".", "")
    return data


def add_settlement_schedule(data: dict, calculation: dict) -> dict:
    config = (calculation.get("outputsDynamic") or {}).get("settlementSchedule", {})

    count_field = config.get("countField", "settlementInstallmentNo")
    count = clean_int(data.get(count_field))

    # Safety cap. Old app used many fixed fields; 120 is plenty for MVP.
    count = min(count, int(config.get("maxCount", 120)))

    settlement_amount = clean_money(data.get("settlementAmount"))
    installment_amount = clean_money(data.get("settlementInstallmentAmount"))
    first_payment_date = parse_date(data.get("settlementFirstPaymentDate"))

    if count <= 0:
        return data

    if installment_amount == 0 and settlement_amount > 0:
        installment_amount = (settlement_amount / Decimal(count)).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)

    remaining = settlement_amount

    for i in range(count):
        suffix = f"{i:02d}"
        payment_date = add_months(first_payment_date, i)

        payment = installment_amount
        if settlement_amount > 0:
            if i == count - 1:
                payment = remaining
            remaining = max(Decimal("0"), remaining - payment)

        data[f"settlementPaymentDate{suffix}"] = format_date(payment_date)
        data[f"settlementPaymentAmount{suffix}"] = money(payment)
        data[f"settlementRemaingBalance{suffix}"] = money(remaining)

        # Correct spelling alias for future templates.
        data[f"settlementRemainingBalance{suffix}"] = money(remaining)

    return data


def apply_legacy_legal_calculations(data: dict, calculation: dict) -> dict:
    data = dict(data)

    data = add_last_four_fields(data)
    data = add_case_filename_fields(data)
    data = add_settlement_schedule(data, calculation)

    return data
