#!/usr/bin/env python3
"""Offline companion to the SoldFetch draft. Standard library only; no API calls."""

from decimal import Decimal, InvalidOperation
from statistics import median

IDENTITY_FIELDS = (
    "set", "cardNumber", "parallel", "language",
    "edition", "grader", "grade",
)

def summarize_reviewed(rows, target, site, currency):
    if any(not target.get(k) for k in IDENTITY_FIELDS):
        raise ValueError("The target identity must be complete")
    values, seen = [], set()
    for row in rows:
        identity = row.get("identity", {})
        listing = row.get("listing", {})
        key = (row.get("ebaySite"), listing.get("itemId"))
        if row.get("reviewStatus") != "accepted" or key[0] != site:
            continue
        if not key[1] or key in seen:
            continue
        if any(identity.get(k) != target[k] for k in IDENTITY_FIELDS):
            continue
        if listing.get("soldCurrency") != currency:
            continue
        if listing.get("quality", {}).get("priceBasis") != "displayed_listing_price":
            continue
        try:
            value = Decimal(str(listing.get("soldPrice")))
        except InvalidOperation:
            continue
        if not value.is_finite() or value <= 0:
            continue
        seen.add(key)
        values.append(value)
    return {"count": len(values), "currency": currency,
            "medianDisplayedItemPrice": median(values) if values else None}


def offline_checks():
    from copy import deepcopy
    target = {"set": "Garden Creatures", "cardNumber": "017/100",
              "parallel": "standard foil", "language": "English",
              "edition": "unlimited", "grader": "Example Grading Co", "grade": "9"}
    def make_row(item_id, value):
        return {"reviewStatus": "accepted", "identity": dict(target), "ebaySite": "ebay.com",
                "listing": {"itemId": item_id, "soldPrice": value, "soldCurrency": "USD",
                            "quality": {"priceBasis": "displayed_listing_price"}}}
    rows = [make_row(str(100000000000+i), value) for i, value in enumerate(["40.00", "42.00", "44.00"])]
    def summary(candidates):
        return summarize_reviewed(candidates, target, "ebay.com", "USD")
    expected = {"count": 3, "currency": "USD", "medianDisplayedItemPrice": Decimal("42.00")}
    assert summary(rows) == expected
    assert summary(rows + [deepcopy(rows[0])]) == expected
    checks_run = 2
    for field in IDENTITY_FIELDS:
        different = make_row("100000000009", "95.00")
        different["identity"][field] = "different"
        assert summary(rows+[different]) == expected
        checks_run += 1
    for value in [None, "invalid", "NaN", "Infinity", "0", "-5"]:
        assert summary(rows+[make_row("100000000009", value)]) == expected
        checks_run += 1
    for field, value in [("reviewStatus", "needs_review"), ("ebaySite", "ebay.de")]:
        different = make_row("100000000009", "95.00")
        different[field] = value
        assert summary(rows+[different]) == expected
        checks_run += 1
    for field, value in [("soldCurrency", "EUR"), ("quality", {"priceBasis": "range_lower_bound"})]:
        different = make_row("100000000009", "95.00")
        different["listing"][field] = value
        assert summary(rows+[different]) == expected
        checks_run += 1
    assert summary([]) == {"count": 0, "currency": "USD", "medianDisplayedItemPrice": None}
    checks_run += 1
    try:
        summarize_reviewed(rows, {**target, "grade": None}, "ebay.com", "USD")
        raise AssertionError("Incomplete target accepted")
    except ValueError:
        checks_run += 1
    print(f"{checks_run} offline card-cohort checks passed; all examples synthetic")

if __name__ == "__main__":
    offline_checks()
