import pytest
import allure
import logging
import requests
import json
import time
from dulizhan.library.BusinessKw.JoyHub.AppVersionManage import AppVersionManage

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')


@allure.feature("管理后台 - app版本号管理模块")
class TestAppVersionManage:
    appversion_id = None
    token_set = False

    @classmethod
    def setup_class(cls):
        """在整个测试类开始时登录一次，所有测试用例共享token"""
        logging.info("=============================================")
        logging.info("=========== 开始登录，获取Token ============")
        logging.info("=============================================")

        cls.test_case = AppVersionManage()
        username = "joytest"
        password = "Zhou1599"

        cls.test_case._clear_user_fingerprint(username)

        url = "https://joyhub-website-manager-api-test.best-envision.com/admin-api/system/auth/login-dev"
        payload = {"username": username, "password": password}
        headers = {'Content-Type': 'application/json', 'tenant-id': '126'}

        try:
            response = requests.post(url, json=payload, headers=headers, verify=False, timeout=10)
            login_response = response.json()

            if login_response and login_response.get('code') == 0:
                token = login_response.get('data', {}).get('accessToken', '')
                if token:
                    cls.test_case.set_joyhub_token(token)
                    cls.token_set = True
                    logging.info("登录成功，获取到Token: {}...".format(token[:20]))
                else:
                    logging.warning("登录成功但未获取到Token")
            else:
                logging.error("登录失败: {}".format(login_response))
        except Exception as e:
            logging.error("登录异常: {}".format(str(e)))

    @allure.story("验证登录")
    @allure.title("测试登录接口")
    def test_joyhub_login_post(self):
        """测试登录接口"""
        assert self.token_set is True, "登录失败，Token未设置"
        logging.info("登录验证通过，Token已设置")

    @allure.story("验证获得app版本号分页")
    @allure.title("测试获得app版本号管理分页接口")
    def test_joyhub_appversion_page_get(self):
        """测试获得app版本号管理分页接口"""
        with allure.step("1. 准备请求参数"):
            params = {
                "page_no": 1,
                "page_size": 10,
                "store_name": "",
                "version": "",
                "download_url": "",
                "is_on": "",
                "status": ""
            }
            allure.attach(json.dumps(params, ensure_ascii=False), name="请求参数", attachment_type=allure.attachment_type.TEXT)

        with allure.step("2. 调用接口"):
            resp = self.test_case.kw_joyhub_appversion_page_get(**params)
            allure.attach(json.dumps(resp, ensure_ascii=False, indent=2), name="响应数据", attachment_type=allure.attachment_type.JSON)

        with allure.step("3. 验证响应"):
            assert resp is not None, "响应为空"
            assert "code" in resp, "响应中缺少code字段"
            assert resp["code"] == 0, f"请求失败，code={resp.get('code')}"
            assert "data" in resp, "响应中缺少data字段"
            assert "list" in resp["data"], "响应中缺少list字段"
            assert "total" in resp["data"], "响应中缺少total字段"
            assert isinstance(resp["data"]["list"], list), "list字段不是列表类型"
            assert isinstance(resp["data"]["total"], int), "total字段不是整数类型"
            logging.info("获得app版本号分页列表验证通过")

    @allure.story("验证创建app版本号")
    @allure.title("测试创建app版本号管理接口")
    def test_joyhub_appversion_create_post(self):
        """测试创建app版本号管理接口"""
        with allure.step("1. 准备请求参数"):
            timestamp = int(time.time())
            params = {
                "store_name": "App Store",
                "version": f"1.0.{timestamp % 1000}",
                "download_url": "https://www.example.com/download",
                "is_on": 1,
                "status": 1
            }
            allure.attach(json.dumps(params, ensure_ascii=False), name="请求参数", attachment_type=allure.attachment_type.TEXT)

        with allure.step("2. 调用接口"):
            resp = self.test_case.kw_joyhub_appversion_create_post(**params)
            allure.attach(json.dumps(resp, ensure_ascii=False, indent=2), name="响应数据", attachment_type=allure.attachment_type.JSON)

        with allure.step("3. 验证响应"):
            assert resp is not None, "响应为空"
            assert "code" in resp, "响应中缺少code字段"
            assert resp["code"] == 0, f"请求失败，code={resp.get('code')}"
            assert "data" in resp, "响应中缺少data字段"
            assert isinstance(resp["data"], int), "data字段不是整数类型"
            TestAppVersionManage.appversion_id = resp["data"]
            logging.info(f"创建app版本号成功，app版本号ID: {TestAppVersionManage.appversion_id}")

    @allure.story("验证获得app版本号详情")
    @allure.title("测试获得app版本号详情接口")
    def test_joyhub_appversion_get_get(self):
        """测试获得app版本号详情接口"""
        with allure.step("1. 先创建一个app版本号"):
            timestamp = int(time.time())
            create_resp = self.test_case.kw_joyhub_appversion_create_post(
                store_name="Google Play",
                version=f"2.0.{timestamp % 1000}",
                download_url="https://www.example.com/download",
                is_on=1,
                status=1
            )
            appversion_id = create_resp.get("data") if create_resp and create_resp.get("code") == 0 else None

            if not appversion_id:
                pytest.skip("创建测试app版本号失败，跳过详情测试")

            allure.attach(json.dumps({"id": appversion_id}, ensure_ascii=False), name="app版本号 ID", attachment_type=allure.attachment_type.TEXT)

        with allure.step("2. 调用获得详情接口"):
            resp = self.test_case.kw_joyhub_appversion_get_get(appversion_id=appversion_id)
            allure.attach(json.dumps(resp, ensure_ascii=False, indent=2), name="响应数据", attachment_type=allure.attachment_type.JSON)

        with allure.step("3. 验证响应"):
            assert resp is not None, "响应为空"
            assert "code" in resp, "响应中缺少code字段"
            assert resp["code"] == 0, f"请求失败，code={resp.get('code')}"
            assert "data" in resp, "响应中缺少data字段"
            assert isinstance(resp["data"], dict), "data字段不是字典类型"
            assert "id" in resp["data"], "响应中缺少id字段"
            assert resp["data"]["id"] == appversion_id, "返回的ID与请求的不一致"
            logging.info("获得app版本号详情验证通过")

    @allure.story("验证更新app版本号")
    @allure.title("测试更新app版本号管理接口")
    def test_joyhub_appversion_update_put(self):
        """测试更新app版本号管理接口"""
        with allure.step("1. 先创建一个app版本号"):
            timestamp = int(time.time())
            create_resp = self.test_case.kw_joyhub_appversion_create_post(
                store_name="Huawei Store",
                version=f"3.0.{timestamp % 1000}",
                download_url="https://www.example.com/download",
                is_on=1,
                status=1
            )
            appversion_id = create_resp.get("data") if create_resp and create_resp.get("code") == 0 else None

            if not appversion_id:
                pytest.skip("创建测试app版本号失败，跳过更新测试")

            allure.attach(json.dumps({"id": appversion_id}, ensure_ascii=False), name="app版本号 ID", attachment_type=allure.attachment_type.TEXT)

        with allure.step("2. 调用更新接口"):
            timestamp = int(time.time())
            update_params = {
                "appversion_id": appversion_id,
                "store_name": "Updated Store",
                "version": f"4.0.{timestamp % 1000}",
                "download_url": "https://www.updated-example.com/download",
                "is_on": 2,
                "status": 2
            }
            resp = self.test_case.kw_joyhub_appversion_update_put(**update_params)
            allure.attach(json.dumps(resp, ensure_ascii=False, indent=2), name="响应数据", attachment_type=allure.attachment_type.JSON)

        with allure.step("3. 验证响应"):
            assert resp is not None, "响应为空"
            assert "code" in resp, "响应中缺少code字段"
            assert resp["code"] == 0, f"请求失败，code={resp.get('code')}"
            assert "data" in resp, "响应中缺少data字段"
            assert resp["data"] is True, "更新app版本号失败"
            logging.info("更新app版本号验证通过")

    @allure.story("验证删除app版本号")
    @allure.title("测试删除app版本号管理接口")
    def test_joyhub_appversion_delete_delete(self):
        """测试删除app版本号管理接口"""
        with allure.step("1. 先创建一个测试app版本号"):
            timestamp = int(time.time())
            create_resp = self.test_case.kw_joyhub_appversion_create_post(
                store_name="Test Store",
                version=f"5.0.{timestamp % 1000}",
                download_url="https://www.example.com/download",
                is_on=1,
                status=2
            )
            appversion_id = create_resp.get("data") if create_resp and create_resp.get("code") == 0 else None

            if not appversion_id:
                pytest.skip("创建测试app版本号失败，跳过删除测试")

            allure.attach(json.dumps({"id": appversion_id}, ensure_ascii=False), name="待删除app版本号 ID", attachment_type=allure.attachment_type.TEXT)

        with allure.step("2. 调用删除接口"):
            resp = self.test_case.kw_joyhub_appversion_delete_delete(appversion_id=appversion_id)
            allure.attach(json.dumps(resp, ensure_ascii=False, indent=2), name="响应数据", attachment_type=allure.attachment_type.JSON)

        with allure.step("3. 验证响应"):
            assert resp is not None, "响应为空"
            assert "code" in resp, "响应中缺少code字段"
            assert resp["code"] == 0, f"请求失败，code={resp.get('code')}"
            assert "data" in resp, "响应中缺少data字段"
            assert resp["data"] is True, "删除app版本号失败"
            logging.info("删除app版本号验证通过")

    @allure.story("验证批量删除app版本号")
    @allure.title("测试批量删除app版本号管理接口")
    def test_joyhub_appversion_delete_list_delete(self):
        """测试批量删除app版本号管理接口"""
        with allure.step("1. 先创建两个测试app版本号"):
            timestamp = int(time.time())
            resp1 = self.test_case.kw_joyhub_appversion_create_post(
                store_name="Batch Store 1",
                version=f"6.0.{timestamp % 1000}",
                download_url="https://www.example.com/download",
                is_on=1,
                status=2
            )
            resp2 = self.test_case.kw_joyhub_appversion_create_post(
                store_name="Batch Store 2",
                version=f"7.0.{timestamp % 1000 + 1}",
                download_url="https://www.example.com/download",
                is_on=1,
                status=2
            )

            appversion_id1 = resp1.get("data") if resp1 and resp1.get("code") == 0 else None
            appversion_id2 = resp2.get("data") if resp2 and resp2.get("code") == 0 else None

            if not appversion_id1 or not appversion_id2:
                pytest.skip("创建测试app版本号失败，跳过批量删除测试")

            appversion_ids = [appversion_id1, appversion_id2]
            allure.attach(json.dumps({"ids": appversion_ids}, ensure_ascii=False), name="待删除app版本号 IDs", attachment_type=allure.attachment_type.TEXT)

        with allure.step("2. 调用批量删除接口"):
            resp = self.test_case.kw_joyhub_appversion_delete_list_delete(appversion_ids=appversion_ids)
            allure.attach(json.dumps(resp, ensure_ascii=False, indent=2), name="响应数据", attachment_type=allure.attachment_type.JSON)

        with allure.step("3. 验证响应"):
            assert resp is not None, "响应为空"
            assert "code" in resp, "响应中缺少code字段"
            assert resp["code"] == 0, f"请求失败，code={resp.get('code')}"
            assert "data" in resp, "响应中缺少data字段"
            assert resp["data"] is True, "批量删除app版本号失败"
            logging.info("批量删除app版本号验证通过")

    @allure.story("验证获得导入模板")
    @allure.title("测试获得导入app版本号管理模板接口")
    def test_joyhub_appversion_get_import_template_get(self):
        """测试获得导入app版本号管理模板接口"""
        with allure.step("1. 调用获得导入模板接口"):
            resp = self.test_case.kw_joyhub_appversion_get_import_template_get()
            
            with allure.step("2. 验证响应"):
                assert resp is not None, "响应为空"
                assert resp.status_code == 200, f"请求失败，status_code={resp.status_code}"
                assert len(resp.content) > 0, "响应内容为空"
                logging.info("获得导入app版本号模板验证通过")

    @allure.story("验证导出Excel")
    @allure.title("测试导出app版本号管理Excel接口")
    def test_joyhub_appversion_export_excel_get(self):
        """测试导出app版本号管理Excel接口"""
        with allure.step("1. 准备请求参数"):
            params = {
                "page_no": 1,
                "page_size": 10,
                "store_name": "",
                "version": "",
                "download_url": "",
                "is_on": "",
                "status": ""
            }
            allure.attach(json.dumps(params, ensure_ascii=False), name="请求参数", attachment_type=allure.attachment_type.TEXT)

        with allure.step("2. 调用导出Excel接口"):
            resp = self.test_case.kw_joyhub_appversion_export_excel_get(**params)

        with allure.step("3. 验证响应"):
            assert resp is not None, "响应为空"
            assert resp.status_code == 200, f"请求失败，status_code={resp.status_code}"
            assert len(resp.content) > 0, "响应内容为空"
            logging.info("导出app版本号Excel验证通过")
