"""记账测试:比价后下单上报 → 写 savings_record(source='compare')。

覆盖:上报落库 + 门店/菜品/原价随之入库、(user,client_event_id) 幂等、
纯真实口径(demo 兜底已停用:新用户空、上报后才有数)、省额 = 源平台原价 − 实付。
"""
from __future__ import annotations


def _login(client, phone: str) -> str:
    client.post("/api/v1/auth/sms/send", json={"phone": phone})
    r = client.post("/api/v1/auth/sms/login", json={"phone": phone, "code": "123456"})
    assert r.status_code == 200, r.text
    return r.json()["access_token"]


def _auth(token: str) -> dict[str, str]:
    return {"Authorization": f"Bearer {token}"}


def _report_body(**over) -> dict:
    body = {
        "client_event_id": "evt-1",
        "platform": "淘宝闪购",
        "platform_package": "com.taobao.taobao",
        "pay_channel": "alipay",
        "compared_price_cents": 3300,
        "paid_amount_cents": 3300,
        "device_id": "device_test",
        "shop_name": "肯德基宅急送（天北路店）",
        "dishes": ["史迪奇玩具套餐 x1"],
        "original_price_cents": 3680,
        "source_platform_name": "美团",
        "source_deeplink": "https://example.com/reorder",
    }
    body.update(over)
    return body


def test_order_report_creates_real_savings(client) -> None:
    """上报一笔 → savings 统计/明细只反映这笔真实数据,含门店/菜品/原价。"""
    token = _login(client, "13800002001")
    r = client.post("/api/v1/order/report", json=_report_body(), headers=_auth(token))
    assert r.status_code == 200, r.text
    out = r.json()
    assert out["duplicated"] is False
    assert out["paid_amount_cents"] == 3300
    assert out["platform"] == "淘宝闪购"

    # summary:真实优先,只算这一笔(demo 不再混入)
    s = client.get("/api/v1/savings/summary", headers=_auth(token)).json()
    assert s["order_count"] == 1
    assert s["total_saved_cents"] == 380  # 3680 − 3300
    assert s["avg_saved_cents"] == 380

    # records:门店/菜品/原价/支付渠道/源平台都在
    page = client.get("/api/v1/savings/records", headers=_auth(token)).json()
    assert len(page["items"]) == 1
    it = page["items"][0]
    assert it["shop_name"] == "肯德基宅急送（天北路店）"
    assert it["dishes"] == ["史迪奇玩具套餐 x1"]
    assert it["order_amount_cents"] == 3300
    assert it["saved_amount_cents"] == 380
    assert it["original_price_cents"] == 3680
    assert it["platform"] == "淘宝闪购"
    assert it["pay_channel"] == "alipay"
    assert it["source_platform_name"] == "美团"


def test_order_report_idempotent(client) -> None:
    """同 (user, client_event_id) 重复上报:第二次 duplicated=True,不新增。"""
    token = _login(client, "13800002002")
    body = _report_body(client_event_id="evt-dup")
    r1 = client.post("/api/v1/order/report", json=body, headers=_auth(token))
    assert r1.json()["duplicated"] is False
    r2 = client.post("/api/v1/order/report", json=body, headers=_auth(token))
    assert r2.json()["duplicated"] is True
    s = client.get("/api/v1/savings/summary", headers=_auth(token)).json()
    assert s["order_count"] == 1


def test_fresh_user_empty_until_report(client) -> None:
    """纯真实(demo 兜底已停用):新用户 summary/battle/records 全空,上报后才有数。"""
    token = _login(client, "13800002003")

    # 未上报:无任何 demo,统计全 0、明细空
    s0 = client.get("/api/v1/savings/summary", headers=_auth(token)).json()
    assert s0["order_count"] == 0
    assert s0["total_saved_cents"] == 0
    b0 = client.get("/api/v1/savings/battle", headers=_auth(token)).json()
    assert b0["compare_count"] == 0
    assert b0["streak_days"] == 0
    p0 = client.get("/api/v1/savings/records", headers=_auth(token)).json()
    assert p0["items"] == []

    # 上报一笔真实 → 统计只算这一笔
    client.post(
        "/api/v1/order/report",
        json=_report_body(
            client_event_id="evt-real", original_price_cents=5000, paid_amount_cents=4200
        ),
        headers=_auth(token),
    )
    s = client.get("/api/v1/savings/summary", headers=_auth(token)).json()
    assert s["order_count"] == 1
    assert s["total_saved_cents"] == 800  # 5000 − 4200

    page = client.get("/api/v1/savings/records", headers=_auth(token)).json()
    assert len(page["items"]) == 1
    assert page["items"][0]["saved_amount_cents"] == 800


def test_order_report_requires_auth(client) -> None:
    r = client.post("/api/v1/order/report", json=_report_body())
    assert r.status_code == 401
