"""Outstanding finance on a bought car, read from the platform's own
purchase page (2026-09-16, Steven: "some cars that are on finance have
negative equity as the price we agree to pay for the car is less than what
the seller currently owes. Carwow and motorway both track this").

Both platforms settle the seller's finance out of the dealer's payment on
collection (Motorway through Motorway Pay, Carwow through the dealer), and
when the settlement figure is more than the price agreed the seller pays
the shortfall, the negative equity, to the platform before the car moves.
What the dealer needs on file is the settlement figure (DealerKit's own
Stocklisting step has a finance settlement field for it) and the negative
equity, so the car is marked NEGATIVE EQUITY here and the office knows the
logbook waits on the seller's shortfall.

The exact words each platform prints are read from the purchase summary
page's own text, label by label, the same way the payment breakdown is.
Every line mentioning finance, settlement or equity is written to the
platform's detail log once per car, so the labels below can be tightened
against the real wording after the first read. Pure, tested.
"""
import datetime
import os
import re

MONEY = re.compile(r"£\s*([\d,]+)(?:\.(\d{2}))?")

# The label a settlement figure sits under, in the order tried. Matched on
# the start of a line, case blind, with the figure on the same line or the
# next one (Motorway splits pounds and pence across two lines).
# Seen live 2026-09-16: Carwow prints "Settlement amount" (the lender's
# figure) above "Amount to finance company"; Motorway prints only "Amount
# to finance company", so that is its settlement when nothing else is.
SETTLEMENT_LABELS = ("settlement amount", "finance settlement", "settlement figure", "outstanding finance settlement",
                     "outstanding finance", "finance to settle", "settlement", "amount to finance company")
FINANCE_COMPANY_LABELS = ("amount to finance company",)
SELLER_LABELS = ("amount to seller", "amount to you", "paid to seller", "seller receives")
NEGATIVE_LABELS = ("negative equity", "shortfall", "seller to pay", "seller pays", "amount due from seller",
                   "seller contribution", "seller shortfall")
VEHICLE_PRICE_LABELS = ("final vehicle price", "vehicle price")
_WORDS = ("finance", "settle", "equity", "shortfall", "lender", "hp ", "pcp")


PENCE_LINE = re.compile(r"^\.(\d{2})$")


def _money_at(lines, i):
    """The money on line i, else on line i+1 (Motorway's two line split),
    with the pence Motorway prints on the line after the pounds ("£10,370"
    then ".04", seen live 2026-09-16) added back on."""
    for j in (i, i + 1):
        if j < len(lines):
            m = MONEY.search(lines[j])
            if m and (j == i or lines[j].lstrip().startswith("£")):
                value = float(m.group(1).replace(",", ""))
                if m.group(2):
                    value += float(m.group(2)) / 100
                elif j + 1 < len(lines):
                    pm = PENCE_LINE.match(lines[j + 1].strip())
                    if pm:
                        value += float(pm.group(1)) / 100
                return value
    return None


def _labelled(lines, labels):
    """The first label in `labels` order that has a figure, wherever it
    sits on the page: label order is priority, not page order (Carwow
    prints the amount to the finance company above the settlement)."""
    for lab in labels:
        for i, l in enumerate(lines):
            low = l.lower().strip(" :")
            if low == lab or low.startswith(lab + " ") or low.startswith(lab + ":"):
                v = _money_at(lines, i)
                if v is not None:
                    return v
    return None


def finance_from_purchase_text(text):
    """{finance_settlement, negative_equity, to_finance_company, finance_lines}
    from a purchase page's text. A figure is only ever read from a
    labelled line; the negative equity is worked out from settlement less
    vehicle price when the page names no shortfall itself. None for
    anything not on the page. finance_lines carries each matching line
    with the two lines after it, short, for the log."""
    lines = [l.strip() for l in (text or "").splitlines() if l.strip()]
    settlement = _labelled(lines, SETTLEMENT_LABELS)
    to_company = _labelled(lines, FINANCE_COMPANY_LABELS)
    negative = _labelled(lines, NEGATIVE_LABELS)
    if negative is None and settlement is not None:
        price = _labelled(lines, VEHICLE_PRICE_LABELS)
        if price is not None and settlement > price:
            negative = round(settlement - price, 2)
    hits = []
    for i, l in enumerate(lines):
        low = l.lower()
        if len(l) <= 80 and any(w in low for w in _WORDS + ("amount to", "vehicle price")):
            hits.append(" / ".join(x[:60] for x in lines[i:i + 3]))
        if len(hits) >= 16:
            break
    return {"finance_settlement": settlement, "negative_equity": negative, "to_finance_company": to_company, "finance_lines": hits}


_noted = set()


def finance_lines_note(platform, reg, found):
    """Once per car per process: the finance lines and what was read from
    them, into data/logs/<platform>_detail.log (already sent to Dealer OS
    with the diagnostics), so the real wording can be seen."""
    key = (platform, reg)
    if key in _noted or not found.get("finance_lines"):
        return
    _noted.add(key)
    try:
        root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
        logs = os.path.join(root, "data", "logs")
        os.makedirs(logs, exist_ok=True)
        with open(os.path.join(logs, f"{platform}_detail.log"), "a") as f:
            # One short line each (2026-09-16): the diagnostics document
            # cuts a long line, and the first read's lists were unreadable.
            f.write(f"{platform} purchase finance lines {datetime.datetime.now().isoformat(timespec='seconds')} for {reg}:\n")
            for hit in found["finance_lines"]:
                f.write(f"  fin | {hit[:200]}\n")
            f.write(f"  read as: settlement {found.get('finance_settlement')!r}, to finance company {found.get('to_finance_company')!r}, negative equity {found.get('negative_equity')!r}\n")
    except Exception:
        pass
