"""用户反馈接口测试。"""
from __future__ import annotations

from app.db.session import SessionLocal
from app.models.feedback import Feedback
from app.repositories import user as user_repo


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 test_feedback_records_empty_returns_200(client) -> None:
    token = _login(client, "13622000001")

    r = client.get("/api/v1/feedback/records", headers={"Authorization": f"Bearer {token}"})

    assert r.status_code == 200, r.text
    assert r.json() == {
        "records": [],
        "counts": {"all": 0, "pending": 0, "adopted": 0, "rejected": 0},
    }


def test_feedback_config_returns_default(client) -> None:
    token = _login(client, "13622000002")

    r = client.get("/api/v1/feedback/config", headers={"Authorization": f"Bearer {token}"})

    assert r.status_code == 200, r.text
    body = r.json()
    assert body["enabled"] is True
    assert body["group_name"] == "傻瓜比价官方群"


def test_submit_feedback_derives_source_from_scene(client) -> None:
    """比价结果页反馈带 scene → source=comparison 并存 scene;「我的」页不带 → profile;
    客户端显式传 source 优先(即便没 scene 也判 comparison)。历史接口带回 scene。"""
    token = _login(client, "13622000010")
    h = {"Authorization": f"Bearer {token}"}

    r = client.post("/api/v1/feedback", data={"content": "比价太慢了", "scene": "比价太慢"}, headers=h)
    assert r.status_code == 200, r.text
    fid_cmp = r.json()["id"]

    r = client.post("/api/v1/feedback", data={"content": "普通建议"}, headers=h)
    assert r.status_code == 200, r.text
    fid_prof = r.json()["id"]

    r = client.post(
        "/api/v1/feedback", data={"content": "只填了描述", "source": "comparison"}, headers=h
    )
    assert r.status_code == 200, r.text
    fid_explicit = r.json()["id"]

    db = SessionLocal()
    try:
        cmp_fb = db.get(Feedback, fid_cmp)
        assert cmp_fb.source == "comparison" and cmp_fb.scene == "比价太慢"
        prof_fb = db.get(Feedback, fid_prof)
        assert prof_fb.source == "profile" and prof_fb.scene is None
        assert db.get(Feedback, fid_explicit).source == "comparison"
    finally:
        db.close()

    r = client.get("/api/v1/feedback/records", headers=h)
    assert r.status_code == 200, r.text
    scenes = {item["id"]: item["scene"] for item in r.json()["records"]}
    assert scenes[fid_cmp] == "比价太慢"
    assert scenes[fid_prof] is None


def test_feedback_records_maps_existing_statuses(client) -> None:
    phone = "13622000003"
    token = _login(client, phone)

    db = SessionLocal()
    try:
        user = user_repo.get_user_by_phone(db, phone)
        assert user is not None
        db.add(Feedback(user_id=user.id, content="待处理反馈", contact="", status="pending"))
        db.add(
            Feedback(
                user_id=user.id,
                content="已采纳反馈",
                contact="",
                status="adopted",
                reward_coins=800,
            )
        )
        db.add(
            Feedback(
                user_id=user.id,
                content="未采纳反馈",
                contact="",
                status="rejected",
                reject_reason="暂未提供可复现信息",
            )
        )
        db.commit()
    finally:
        db.close()

    r = client.get("/api/v1/feedback/records", headers={"Authorization": f"Bearer {token}"})

    assert r.status_code == 200, r.text
    body = r.json()
    assert body["counts"] == {"all": 3, "pending": 1, "adopted": 1, "rejected": 1}
    by_status = {item["status"]: item for item in body["records"]}
    assert by_status["adopted"]["reward_coins"] == 800
    assert by_status["rejected"]["reject_reason"] == "暂未提供可复现信息"
