"""
parsers.py — payment message parsing + amount/currency helpers.
Ported from the original desktop app's regex engine.
"""
import re

CUR = r'(?:USD|KHR|KWD|THB)'
AMOUNT_RE = r'(?P<amount>[$]?[\d,]+(?:[.,]\d+)?)'
AMT = AMOUNT_RE + r'(?:\s*' + CUR + r')?'
SENDER_STOP = (r'(?=\s+on\b|\s+at\b|\s+via\b|\s+using\b|'
               r'\s+through\b|\s+\(|\s+for\b|\s*$|[,.;])')

PAYMENT_PATTERNS = [
    re.compile(AMT + r'\s+paid\s+by\s+(?P<sender>.+?)\s+\(\*',
               re.IGNORECASE | re.DOTALL),
    re.compile(AMT + r'\s+paid\s+by\s+(?P<sender>.+?)' + SENDER_STOP,
               re.IGNORECASE | re.DOTALL),
    re.compile(CUR + r'\s*' + AMOUNT_RE + r'(?:\s*' + CUR + r')?\s+paid\s+by\s+'
               r'(?P<sender>.+?)' + SENDER_STOP,
               re.IGNORECASE | re.DOTALL),
    re.compile(AMT + r'\s+(?:received|transferred|transfer)\s+(?:from|by)\s+'
               r'(?P<sender>.+?)' + SENDER_STOP,
               re.IGNORECASE | re.DOTALL),
    re.compile(r'(?:you\s+)?(?:have\s+)?received\s+' + AMT +
               r'\s+(?:from|by)\s+(?P<sender>.+?)' + SENDER_STOP,
               re.IGNORECASE | re.DOTALL),
    re.compile(r'credited\s+(?:with\s+)?' + AMT +
               r'\s+(?:by|from)\s+(?P<sender>.+?)' + SENDER_STOP,
               re.IGNORECASE | re.DOTALL),
    re.compile(r'(?P<sender>[A-Z][A-Za-z\.\'\- ]{1,40}?)\s+(?:has\s+)?paid\s+'
               + AMT + SENDER_STOP,
               re.IGNORECASE | re.DOTALL),
    re.compile(r'(?P<sender>[A-Z][A-Za-z\.\'\- ]{1,40}?)\s+(?:has\s+)?sent\s+you\s+'
               + AMT + SENDER_STOP,
               re.IGNORECASE | re.DOTALL),
]


def clean_sender(name):
    if not name:
        return "Supporter"
    name = re.sub(r'\s*\(\*[^)]*\)', '', name)
    name = re.sub(r'^(?:wing|aba|payway|acleda|bakong|truemoney|pi pay|nala)'
                  r'\s*[:.\-]\s*', '', name, flags=re.IGNORECASE)
    name = re.sub(r'\s+', ' ', name).strip(" .,;:-")
    return name or "Supporter"


def donor_key(raw_sender):
    if not raw_sender:
        return "supporter"
    return re.sub(r'\s+', ' ', raw_sender).strip().lower()


def extract_currency(text):
    m = re.search(r'\b(' + CUR + r')\b', text, re.IGNORECASE)
    return m.group(1).upper() if m else None


def detect_provider(text):
    t = text.lower()
    checks = [
        ("ABA PayWay", ("aba", "payway", "khqr")),
        ("Wing", ("wing",)),
        ("ACLEDA", ("acleda",)),
        ("Bakong", ("bakong", "nala")),
        ("TrueMoney", ("truemoney", "true money")),
        ("Pi Pay", ("pi pay", "pipay")),
    ]
    for name, keywords in checks:
        if any(k in t for k in keywords):
            return name
    return "Payment"


def parse_payment_message(text):
    if not text:
        return None
    clean = " ".join(text.split())
    for pattern in PAYMENT_PATTERNS:
        m = pattern.search(clean)
        if not m:
            continue
        amount = m.group("amount").strip()
        sender_raw = m.group("sender").strip()
        sender = clean_sender(sender_raw)
        if not sender:
            continue
        cur = extract_currency(clean)
        if cur and not amount.startswith("$") and not amount.upper().endswith(cur):
            amount = f"{amount} {cur}"
        return {
            "amount": amount,
            "sender": sender,
            "sender_key": donor_key(sender_raw),
            "provider": detect_provider(clean),
            "raw": clean,
        }
    return None


def normalize_amount(amount_str, khr_rate=4000.0):
    m = re.match(r'\$?([\d,]+(?:[.,]\d+)?)\s*(USD|KHR|KWD|THB)?',
                 amount_str or "", re.IGNORECASE)
    if not m:
        return 0.0
    num = float(m.group(1).replace(",", ""))
    cur = (m.group(2) or "USD").upper()
    if cur == "KHR":
        return num / max(khr_rate, 1.0)
    return num


def format_usd(value):
    return f"${value:,.2f}"
