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

from decimal import Decimal, InvalidOperation, ROUND_HALF_UP

def amount_or_none(value):
    if value is None:
        return None
    try:
        result = Decimal(str(value))
    except InvalidOperation:
        return None
    return result if result.is_finite() and result >= 0 else None

def same_currency_total(row):
    item = amount_or_none(row.get("soldPrice"))
    shipping = amount_or_none(row.get("shippingPrice"))
    currency = row.get("soldCurrency")
    if item is None or shipping is None or not currency:
        return None
    if currency != row.get("shippingCurrency"):
        return None
    return item + shipping

def convert_to_usd(amount, currency, rates, rate_timestamp):
    value = amount_or_none(amount)
    rate = amount_or_none(rates.get(currency))
    if value is None or rate is None or rate <= 0 or not rate_timestamp:
        raise ValueError("Amount, explicit rate, and timestamp are required")
    return {
        "sourceAmount": str(value), "sourceCurrency": currency,
        "rateToUSD": str(rate), "rateTimestamp": rate_timestamp,
        "convertedUSD": str((value * rate).quantize(
            Decimal("0.01"), rounding=ROUND_HALF_UP)),
    }


def offline_checks():
    rates = {"USD": "1", "GBP": "1.25", "EUR": "1.10"}
    timestamp = "2026-10-24T12:00:00Z"
    rows = [
        {"soldPrice": "80.00", "soldCurrency": "USD", "shippingPrice": "5.00", "shippingCurrency": "USD"},
        {"soldPrice": "70.00", "soldCurrency": "GBP", "shippingPrice": None, "shippingCurrency": None},
        {"soldPrice": "90.00", "soldCurrency": "EUR", "shippingPrice": "0.00", "shippingCurrency": "EUR"},
    ]
    assert [same_currency_total(r) for r in rows] == [Decimal("85.00"), None, Decimal("90.00")]
    converted = [convert_to_usd(r["soldPrice"],r["soldCurrency"], rates,timestamp) for r in rows]
    assert [r["convertedUSD"] for r in converted] == ["80.00", "87.50", "99.00"]
    assert all(r["rateTimestamp"] == timestamp for r in converted)
    assert [r["sourceCurrency"] for r in converted] == ["USD", "GBP", "EUR"]
    checks_run = 4
    for value in [None, "invalid", "NaN", "Infinity", "-1"]:
        assert amount_or_none(value) is None
        checks_run += 1
    assert same_currency_total({**rows[0], "shippingCurrency": "EUR"}) is None
    assert same_currency_total({**rows[0], "soldCurrency": None}) is None
    assert same_currency_total({**rows[0], "shippingPrice": None}) is None
    checks_run += 3
    for amount, currency, selected_rates, stamp in [
        (None, "USD", rates, timestamp),
        ("10", "GBP", {}, timestamp),
        ("10", "GBP", {"GBP": "0"}, timestamp),
        ("10", "GBP", {"GBP": "-1"}, timestamp),
        ("10", "GBP", rates, ""),
    ]:
        try:
            convert_to_usd(amount, currency, selected_rates, stamp)
            raise AssertionError("Invalid conversion input accepted")
        except ValueError:
            checks_run += 1
    assert convert_to_usd("1.005", "USD", rates, timestamp)["convertedUSD"] == "1.01"
    checks_run += 1
    print(f"{checks_run} offline currency checks passed; amounts and rates are synthetic")

if __name__ == "__main__":
    offline_checks()
