# ============================================================
# 平台管理员端 — 全量端到端测试
# 覆盖 20 个 Controller，约 70 个 API 端点
# ============================================================
import pytest
import json
from config import KEEP_TEST_DATA
from api_client import ApiClient


# ============================================================
# 平台端 — 账号管理 (AccountManageController)
# ============================================================
class TestAdminAccountManage:

    def test_01_account_list(self, client, admin_token):
        """平台端账号列表查询"""
        resp = client.get("/agri/accountManage/list")
        client.assert_ok("查询账号列表失败")
        data = client.extract_data() or {}
        print(f"  [OK] 账号列表 total={data.get('total','?')}")

    def test_02_account_detail(self, client, admin_token):
        """平台端账号详情"""
        # 从列表取第一个
        resp = client.get("/agri/accountManage/list", params={"pageSize": 1, "pageNum": 1})
        data = client.assert_ok()
        rows = (data.get("data") or {}).get("rows") or []
        if not rows:
            pytest.skip("无账号数据")
        uid = rows[0].get("userId")
        resp = client.get(f"/agri/accountManage/{uid}")
        client.assert_ok("查询账号详情失败")
        print(f"  [OK] 账号详情 userId={uid}")


# ============================================================
# 平台端 — 管理员管理 (PlatformAdminController)
# ============================================================
class TestAdminPlatformAdmin:

    def test_03_admin_list(self, client, admin_token):
        """平台管理员列表"""
        resp = client.get("/agri/platformAdmin/list")
        client.assert_ok("查询管理员列表失败")
        data = client.extract_data() or {}
        print(f"  [OK] 管理员列表 total={data.get('total','?')}")

    def test_04_admin_role_options(self, client, admin_token):
        """平台管理员角色选项"""
        resp = client.get("/agri/platformAdmin/roleOptions")
        client.assert_ok("查询角色选项失败")
        roles = client.extract_data() or []
        print(f"  [OK] 角色选项 count={len(roles)}")

    def test_05_admin_detail(self, client, admin_token):
        """平台管理员详情"""
        resp = client.get("/agri/platformAdmin/list", params={"pageSize": 1})
        data = client.assert_ok()
        rows = (data.get("data") or {}).get("rows") or []
        if not rows:
            pytest.skip("无管理员数据")
        uid = rows[0].get("userId")
        resp = client.get(f"/agri/platformAdmin/{uid}")
        client.assert_ok("查询管理员详情失败")
        print(f"  [OK] 管理员详情 userId={uid}")


# ============================================================
# 平台端 — 会员管理 (MemberController)
# ============================================================
class TestAdminMember:

    def test_06_member_list(self, client, admin_token):
        """平台端会员列表"""
        resp = client.get("/agri/member/list")
        client.assert_ok("查询会员列表失败")
        data = client.extract_data() or {}
        print(f"  [OK] 会员列表 total={data.get('total','?')}")

    def test_07_member_levels(self, client, admin_token):
        """平台端会员等级列表"""
        resp = client.get("/agri/member/levels")
        client.assert_ok("查询会员等级失败")
        data = client.extract_data() or []
        if isinstance(data, list):
            print(f"  [OK] 会员等级 count={len(data)}")
        else:
            print(f"  [OK] 会员等级正常")

    def test_08_member_detail(self, client, admin_token):
        """平台端会员详情"""
        resp = client.get("/agri/member/list", params={"pageSize": 1})
        data = client.assert_ok()
        rows = (data.get("data") or {}).get("rows") or []
        if not rows:
            pytest.skip("无会员数据")
        mid = rows[0].get("memberId")
        resp = client.get(f"/agri/member/{mid}")
        client.assert_ok("查询会员详情失败")
        print(f"  [OK] 会员详情 memberId={mid}")


# ============================================================
# 平台端 — 商家管理 (MerchantController)
# ============================================================
class TestAdminMerchant:

    def test_09_merchant_list(self, client, admin_token):
        """平台端商家列表"""
        resp = client.get("/agri/merchant/list")
        client.assert_ok("查询商家列表失败")
        data = client.extract_data() or {}
        print(f"  [OK] 商家列表 total={data.get('total','?')}")

    def test_10_merchant_detail(self, client, admin_token):
        """平台端商家详情"""
        resp = client.get("/agri/merchant/list", params={"pageSize": 1})
        data = client.assert_ok()
        rows = (data.get("data") or {}).get("rows") or []
        if not rows:
            pytest.skip("无商家数据")
        mid = rows[0].get("merchantId")
        resp = client.get(f"/agri/merchant/{mid}")
        client.assert_ok("查询商家详情失败")
        print(f"  [OK] 商家详情 merchantId={mid}")


# ============================================================
# 平台端 — 入驻审核 (MerchantEntryApplyController)
# ============================================================
class TestAdminEntryAudit:

    def test_11_entry_apply_list(self, client, admin_token):
        """入驻申请列表"""
        resp = client.get("/agri/merchantEntryApply/list")
        client.assert_ok("查询入驻申请失败")
        data = client.extract_data() or {}
        total = data.get("total", 0) if isinstance(data, dict) else 0
        print(f"  [OK] 入驻申请 total={total}")

    def test_12_entry_pending_count(self, client, admin_token):
        """待审核入驻数量"""
        resp = client.get("/agri/merchantEntryApply/pendingCount")
        data = client.assert_ok("查询待审核入驻数量失败")
        cnt = (data.get("data") or {}).get("pendingCount", 0)
        print(f"  [OK] 待审核入驻 count={cnt}")

    def test_13_entry_apply_detail(self, client, admin_token):
        """入驻申请详情"""
        resp = client.get("/agri/merchantEntryApply/list", params={"pageSize": 1})
        data = client.assert_ok()
        rows = (data.get("data") or {}).get("rows") or []
        if not rows:
            pytest.skip("无入驻申请")
        aid = rows[0].get("applyId")
        resp = client.get(f"/agri/merchantEntryApply/{aid}")
        client.assert_ok("查询入驻申请详情失败")
        print(f"  [OK] 入驻申请详情 applyId={aid}")

    def test_14_entry_approve_flow(self, client, admin_token):
        """入驻审核通过流程（需有待审核数据）"""
        resp = client.get("/agri/merchantEntryApply/list", params={
            "pageSize": 1, "pageNum": 1
        })
        data = client.assert_ok()
        rows = (data.get("data") or {}).get("rows") or []
        if not rows:
            pytest.skip("无入驻申请")

        apply = rows[0]
        aid = apply.get("applyId")
        status = apply.get("applyStatus", "")
        print(f"  [INFO] 入驻申请 applyId={aid} status={status}")

        if status == "PENDING":
            resp = client.put(f"/agri/merchantEntryApply/approve/{aid}", json={})
            client.assert_ok("入驻审核通过失败")
            print(f"  [OK] 入驻申请 {aid} 审核通过")
        elif status == "APPROVED":
            resp = client.put(f"/agri/merchantEntryApply/completePublicity/{aid}")
            client.assert_ok("完成公示失败")
            print(f"  [OK] 入驻申请 {aid} 完成公示")
        else:
            print(f"  [SKIP] 当前状态 {status}，跳过")


# ============================================================
# 平台端 — 商品管理 (GoodsController + GoodsAuditController)
# ============================================================
class TestAdminGoods:

    def test_15_goods_list(self, client, admin_token):
        """平台端商品列表"""
        resp = client.get("/agri/goods/list")
        client.assert_ok("查询商品列表失败")
        data = client.extract_data() or {}
        print(f"  [OK] 商品列表 total={data.get('total','?')}")

    def test_16_goods_pending_count(self, client, admin_token):
        """待审核商品数量"""
        resp = client.get("/agri/goods/pendingCount")
        data = client.assert_ok("查询待审核商品数量失败")
        cnt = (data.get("data") or {}).get("pendingCount", 0)
        print(f"  [OK] 待审核商品 count={cnt}")

    def test_17_goods_detail(self, client, admin_token):
        """平台端商品详情"""
        resp = client.get("/agri/goods/list", params={"pageSize": 1})
        data = client.assert_ok()
        rows = (data.get("data") or {}).get("rows") or []
        if not rows:
            resp = client.get("/agri/goodsAudit/list", params={"pageSize": 1})
            data = client.assert_ok()
            rows = (data.get("data") or {}).get("rows") or []
        if not rows:
            pytest.skip("无商品数据")
        gid = rows[0].get("goodsId")
        resp = client.get(f"/agri/goods/{gid}")
        client.assert_ok("查询商品详情失败")
        print(f"  [OK] 商品详情 goodsId={gid}")

    def test_18_goods_audit_list(self, client, admin_token):
        """商品审核列表"""
        resp = client.get("/agri/goodsAudit/list")
        client.assert_ok("查询商品审核列表失败")
        data = client.extract_data() or {}
        print(f"  [OK] 商品审核列表 total={data.get('total','?')}")

    def test_19_goods_audit_pending_count(self, client, admin_token):
        """商品审核待审数量"""
        resp = client.get("/agri/goodsAudit/pendingCount")
        data = client.assert_ok("查询审核待审数量失败")
        cnt = (data.get("data") or {}).get("pendingCount", 0)
        print(f"  [OK] 审核待审商品 count={cnt}")

    def test_20_goods_audit_detail(self, client, admin_token):
        """商品审核详情"""
        resp = client.get("/agri/goodsAudit/list", params={"pageSize": 1})
        data = client.assert_ok()
        rows = (data.get("data") or {}).get("rows") or []
        if not rows:
            pytest.skip("无待审商品")
        gid = rows[0].get("goodsId")
        resp = client.get(f"/agri/goodsAudit/{gid}")
        client.assert_ok("查询审核商品详情失败")
        print(f"  [OK] 审核商品详情 goodsId={gid}")


# ============================================================
# 平台端 — 分类管理 (PlatformCategoryController)
# ============================================================
class TestAdminCategory:

    def test_21_category_list(self, client, admin_token):
        """平台分类列表"""
        resp = client.get("/agri/category/list")
        client.assert_ok("查询分类列表失败")
        data = client.extract_data() or {}
        print(f"  [OK] 分类列表 total={data.get('total','?')}")

    def test_22_category_tree(self, client, admin_token):
        """平台分类树"""
        resp = client.get("/agri/category/tree")
        client.assert_ok("查询分类树失败")
        tree = client.extract_data() or []
        print(f"  [OK] 分类树 nodes={len(tree)}")

    def test_23_category_detail(self, client, admin_token):
        """平台分类详情"""
        resp = client.get("/agri/category/list", params={"pageSize": 1})
        data = client.assert_ok()
        rows = (data.get("data") or {}).get("rows") or []
        if not rows:
            pytest.skip("无分类数据")
        cid = rows[0].get("categoryId")
        resp = client.get(f"/agri/category/{cid}")
        client.assert_ok("查询分类详情失败")
        print(f"  [OK] 分类详情 categoryId={cid}")


# ============================================================
# 平台端 — Banner管理 (BannerController)
# ============================================================
class TestAdminBanner:

    def test_24_banner_list(self, client, admin_token):
        """Banner列表"""
        resp = client.get("/agri/banner/list")
        client.assert_ok("查询Banner列表失败")
        data = client.extract_data() or {}
        print(f"  [OK] Banner列表 total={data.get('total','?')}")

    def test_25_banner_detail(self, client, admin_token):
        """Banner详情"""
        resp = client.get("/agri/banner/list", params={"pageSize": 1})
        data = client.assert_ok()
        rows = (data.get("data") or {}).get("rows") or []
        if not rows:
            pytest.skip("无Banner数据")
        bid = rows[0].get("bannerId")
        resp = client.get(f"/agri/banner/{bid}")
        client.assert_ok("查询Banner详情失败")
        print(f"  [OK] Banner详情 bannerId={bid}")


# ============================================================
# 平台端 — 商城设置 (MallSettingController)
# ============================================================
class TestAdminMallSetting:

    def test_26_mall_setting_get(self, client, admin_token):
        """商城设置查询"""
        resp = client.get("/agri/mallSetting")
        client.assert_ok("查询商城设置失败")
        setting = client.extract_data() or {}
        print(f"  [OK] 商城设置: {json.dumps(setting, ensure_ascii=False)[:100]}")


# ============================================================
# 平台端 — 服务协议 (MallServiceAgreementController)
# ============================================================
class TestAdminAgreement:

    def test_27_service_agreement_get(self, client, admin_token):
        """商城服务协议查询"""
        resp = client.get("/agri/mallServiceAgreement")
        client.assert_ok("查询服务协议失败")
        agmt = client.extract_data() or {}
        print(f"  [OK] 服务协议: {str(agmt.get('agreementType',''))[:80]}")

    def test_28_entry_agreement_get(self, client, admin_token):
        """入驻协议查询"""
        resp = client.get("/agri/merchantEntryAgreement")
        client.assert_ok("查询入驻协议失败")
        agmt = client.extract_data() or {}
        print(f"  [OK] 入驻协议: {str(agmt.get('agreementType',''))[:80]}")
        client._test_has_agreement = True


# ============================================================
# 平台端 — 地区管理 (RegionController)
# ============================================================
class TestAdminRegion:

    def test_29_region_tree(self, client, admin_token):
        """地区树查询"""
        resp = client.get("/agri/region/tree")
        client.assert_ok("查询地区树失败")
        tree = client.extract_data() or []
        print(f"  [OK] 地区树 nodes={len(tree) if isinstance(tree, list) else 'ok'}")


# ============================================================
# 平台端 — 店铺管理 (ShopController)
# ============================================================
class TestAdminShop:

    def test_30_shop_list(self, client, admin_token):
        """平台端店铺列表"""
        resp = client.get("/agri/shop/list")
        client.assert_ok("查询店铺列表失败")
        data = client.extract_data() or {}
        total = data.get("total", 0) if isinstance(data, dict) else 0
        print(f"  [OK] 店铺列表 total={total}")

    def test_31_shop_detail(self, client, admin_token):
        """平台端店铺详情"""
        resp = client.get("/agri/shop/list", params={"pageSize": 1})
        data = client.assert_ok()
        rows = (data.get("data") or {}).get("rows") or []
        if not rows:
            pytest.skip("无店铺数据")
        sid = rows[0].get("shopId")
        resp = client.get(f"/agri/shop/{sid}")
        client.assert_ok("查询店铺详情失败")
        print(f"  [OK] 店铺详情 shopId={sid}")


# ============================================================
# 平台端 — 商品服务 (GoodsServiceController)
# ============================================================
class TestAdminGoodsService:

    def test_32_goods_service_list(self, client, admin_token):
        """商品服务列表"""
        resp = client.get("/agri/goodsService/list")
        client.assert_ok("查询商品服务列表失败")
        data = client.extract_data() or {}
        print(f"  [OK] 商品服务列表 total={data.get('total','?') if isinstance(data, dict) else 'ok'}")

    def test_33_goods_service_detail(self, client, admin_token):
        """商品服务详情"""
        resp = client.get("/agri/goodsService/list", params={"pageSize": 1})
        data = client.assert_ok()
        # 可能返回 list 或 {rows, total}
        rows = []
        if isinstance(data.get("data"), dict):
            rows = data["data"].get("rows", [])
        elif isinstance(data.get("data"), list):
            rows = data["data"]
        if not rows:
            pytest.skip("无商品服务数据")
        sid = rows[0].get("serviceId")
        resp = client.get(f"/agri/goodsService/{sid}")
        client.assert_ok("查询商品服务详情失败")
        print(f"  [OK] 商品服务详情 serviceId={sid}")


# ============================================================
# 平台端 — 财务管理 (FundOverview / WithdrawAudit / WithdrawSummary)
# ============================================================
class TestAdminFinance:

    def test_34_fund_summary(self, client, admin_token):
        """资金概览"""
        resp = client.get("/agri/finance/fundOverview/summary")
        client.assert_ok("查询资金概览失败")
        summary = client.extract_data() or {}
        print(f"  [OK] 资金概览: {json.dumps(summary, ensure_ascii=False)[:120]}")

    def test_35_fund_shops(self, client, admin_token):
        """资金概览-店铺列表"""
        resp = client.get("/agri/finance/fundOverview/shops")
        client.assert_ok("查询资金店铺列表失败")
        data = client.extract_data() or {}
        print(f"  [OK] 资金店铺列表: {json.dumps(data, ensure_ascii=False)[:120]}")

    def test_36_fund_details(self, client, admin_token):
        """资金概览-明细"""
        resp = client.get("/agri/finance/fundOverview/details", params={"pageSize": 1})
        client.assert_ok("查询资金明细失败")
        data = client.extract_data() or {}
        print(f"  [OK] 资金明细正常")

    def test_37_withdraw_audit_list(self, client, admin_token):
        """提现审核列表"""
        resp = client.get("/agri/finance/withdrawAudit/list")
        client.assert_ok("查询提现列表失败")
        data = client.extract_data() or {}
        total = data.get("total", 0) if isinstance(data, dict) else 0
        print(f"  [OK] 提现审核列表 total={total}")

    def test_38_withdraw_pending_count(self, client, admin_token):
        """提现待审数量"""
        resp = client.get("/agri/finance/withdrawAudit/pendingCount")
        client.assert_ok("查询提现待审数量失败")
        cnt = (client.extract_data() or {}).get("pendingCount", 0)
        print(f"  [OK] 提现待审 count={cnt}")

    def test_39_withdraw_summary_shops(self, client, admin_token):
        """提现汇总-店铺"""
        resp = client.get("/agri/finance/withdrawSummary/shops")
        client.assert_ok("查询提现汇总店铺失败")
        data = client.extract_data() or {}
        print(f"  [OK] 提现汇总-店铺正常")

    def test_40_withdraw_summary_details(self, client, admin_token):
        """提现汇总-明细"""
        resp = client.get("/agri/finance/withdrawSummary/details", params={"pageSize": 1})
        client.assert_ok("查询提现汇总明细失败")
        data = client.extract_data() or {}
        print(f"  [OK] 提现汇总-明细正常")


# ============================================================
# 平台端 — 微信支付配置 (PlatformShopWechatPayController)
# ============================================================
class TestAdminWechatPay:

    def test_41_wechat_pay_list(self, client, admin_token):
        """微信支付配置列表"""
        resp = client.get("/agri/shop/wechat-pay/list")
        client.assert_ok("查询支付配置列表失败")
        data = client.extract_data() or {}
        total = data.get("total", 0) if isinstance(data, dict) else 0
        print(f"  [OK] 支付配置列表 total={total}")

    def test_42_wechat_pay_pending_count(self, client, admin_token):
        """微信支付待审数量"""
        resp = client.get("/agri/shop/wechat-pay/pendingCount")
        client.assert_ok("查询支付待审数量失败")
        cnt = (client.extract_data() or {}).get("pendingCount", 0)
        print(f"  [OK] 支付待审 count={cnt}")

    def test_43_wechat_pay_detail(self, client, admin_token):
        """微信支付配置详情"""
        resp = client.get("/agri/shop/wechat-pay/list", params={"pageSize": 1})
        data = client.assert_ok()
        rows = (data.get("data") or {}).get("rows") or []
        if not rows:
            pytest.skip("无支付配置数据")
        sid = rows[0].get("shopId")
        resp = client.get(f"/agri/shop/wechat-pay/{sid}")
        client.assert_ok("查询支付配置详情失败")
        print(f"  [OK] 支付配置详情 shopId={sid}")


# ============================================================
# 平台端 — 全局设置 (ShopGlobalSettingController)
# ============================================================
class TestAdminGlobalSetting:

    def test_44_global_setting_get(self, client, admin_token):
        """全局设置查询"""
        resp = client.get("/agri/shopSetting")
        client.assert_ok("查询全局设置失败")
        setting = client.extract_data() or {}
        print(f"  [OK] 全局设置: {json.dumps(setting, ensure_ascii=False)[:100]}")
