"""
菜单管理测试用例
"""

import pytest
import time
from api.menu_api import MenuAPI


@pytest.mark.menu
@pytest.mark.regression
class TestMenu:
    """菜单管理测试类"""
    
    @pytest.fixture
    def test_menu_data(self):
        """测试菜单数据"""
        timestamp = int(time.time() * 1000)
        return {
            "menuName": f"测试菜单_{timestamp}",
            "parentId": 0,
            "orderNum": 1,
            "menuType": "C",
            "perms": f"system:menu:{timestamp}",
            "component": f"menu/component/{timestamp}",
            "status": "0"
        }
    
    @pytest.fixture
    async def cleanup_menu(self, authenticated_client):
        """清理测试菜单"""
        menu_ids = []
        
        yield menu_ids
        
        for menu_id in menu_ids:
            try:
                await authenticated_client.delete(f"/api/menus/{menu_id}")
            except Exception:
                pass
    
    @pytest.mark.asyncio
    async def test_create_menu_success(self, authenticated_client, test_menu_data, cleanup_menu):
        """测试创建菜单成功"""
        menu_api = MenuAPI(authenticated_client)
        response = await menu_api.create_menu(test_menu_data)
        
        assert response.status_code == 201
        data = response.json()
        assert "id" in data
        assert data["menuName"] == test_menu_data["menuName"]
        assert data["parentId"] == test_menu_data["parentId"]
        assert data["menuType"] == test_menu_data["menuType"]
        
        cleanup_menu.append(data["id"])
    
    @pytest.mark.asyncio
    async def test_get_menu_by_id_success(self, authenticated_client, test_menu_data, cleanup_menu):
        """测试根据ID获取菜单成功"""
        menu_api = MenuAPI(authenticated_client)
        
        create_response = await menu_api.create_menu(test_menu_data)
        menu_id = create_response.json()["id"]
        
        response = await menu_api.get_menu_by_id(menu_id)
        
        assert response.status_code == 200
        data = response.json()
        assert data["id"] == menu_id
        assert data["menuName"] == test_menu_data["menuName"]
        
        cleanup_menu.append(menu_id)
    
    @pytest.mark.asyncio
    async def test_get_menu_by_id_not_found(self, authenticated_client):
        """测试获取不存在的菜单"""
        menu_api = MenuAPI(authenticated_client)
        response = await menu_api.get_menu_by_id(999999)
        
        assert response.status_code == 404
    
    @pytest.mark.asyncio
    async def test_get_all_menus_success(self, authenticated_client):
        """测试获取所有菜单成功"""
        menu_api = MenuAPI(authenticated_client)
        response = await menu_api.get_all_menus()
        
        assert response.status_code == 200
        data = response.json()
        assert isinstance(data, list)
    
    @pytest.mark.asyncio
    async def test_get_menu_tree_success(self, authenticated_client):
        """测试获取菜单树成功"""
        menu_api = MenuAPI(authenticated_client)
        response = await menu_api.get_menu_tree()
        
        assert response.status_code == 200
        data = response.json()
        assert isinstance(data, list)
    
    @pytest.mark.asyncio
    async def test_update_menu_success(self, authenticated_client, test_menu_data, cleanup_menu):
        """测试更新菜单成功"""
        menu_api = MenuAPI(authenticated_client)
        
        create_response = await menu_api.create_menu(test_menu_data)
        menu_id = create_response.json()["id"]
        
        timestamp = int(time.time() * 1000)
        update_data = {
            "menuName": f"更新后菜单_{timestamp}",
            "orderNum": 2
        }
        response = await menu_api.update_menu(menu_id, update_data)
        
        assert response.status_code == 200
        data = response.json()
        assert data["menuName"] == f"更新后菜单_{timestamp}"
        assert data["orderNum"] == 2
        
        cleanup_menu.append(menu_id)
    
    @pytest.mark.asyncio
    async def test_delete_menu_success(self, authenticated_client, test_menu_data, cleanup_menu):
        """测试删除菜单成功"""
        menu_api = MenuAPI(authenticated_client)
        
        create_response = await menu_api.create_menu(test_menu_data)
        menu_id = create_response.json()["id"]
        
        response = await menu_api.delete_menu(menu_id)
        
        assert response.status_code == 204
    
    @pytest.mark.asyncio
    async def test_get_menus_by_parent_success(self, authenticated_client, test_menu_data, cleanup_menu):
        """测试根据父菜单ID获取子菜单成功"""
        menu_api = MenuAPI(authenticated_client)
        
        parent_response = await menu_api.create_menu(test_menu_data)
        parent_id = parent_response.json()["id"]
        
        timestamp = int(time.time() * 1000)
        child_menu_data = test_menu_data.copy()
        child_menu_data["menuName"] = f"子菜单_{timestamp}"
        child_menu_data["parentId"] = parent_id
        
        child_response = await menu_api.create_menu(child_menu_data)
        child_id = child_response.json()["id"]
        
        response = await menu_api.get_menus_by_parent(parent_id)
        
        assert response.status_code == 200
        data = response.json()
        assert isinstance(data, list)
        assert any(menu["id"] == child_id for menu in data)
        
        cleanup_menu.extend([parent_id, child_id])
    
    @pytest.mark.asyncio
    async def test_get_menus_by_type_success(self, authenticated_client, test_menu_data, cleanup_menu):
        """测试根据菜单类型获取菜单成功"""
        menu_api = MenuAPI(authenticated_client)
        
        create_response = await menu_api.create_menu(test_menu_data)
        menu_id = create_response.json()["id"]
        
        response = await menu_api.get_menus_by_type("C")
        
        assert response.status_code == 200
        data = response.json()
        assert isinstance(data, list)
        assert any(menu["id"] == menu_id for menu in data)
        
        cleanup_menu.append(menu_id)
    
    @pytest.mark.asyncio
    async def test_create_menu_with_parent_success(self, authenticated_client, test_menu_data, cleanup_menu):
        """测试创建带父菜单的子菜单成功"""
        menu_api = MenuAPI(authenticated_client)
        
        parent_response = await menu_api.create_menu(test_menu_data)
        parent_id = parent_response.json()["id"]
        
        timestamp = int(time.time() * 1000)
        child_menu_data = test_menu_data.copy()
        child_menu_data["menuName"] = f"子菜单_{timestamp}"
        child_menu_data["parentId"] = parent_id
        
        response = await menu_api.create_menu(child_menu_data)
        
        assert response.status_code == 201
        data = response.json()
        assert data["parentId"] == parent_id
        
        cleanup_menu.extend([parent_id, data["id"]])
    
    @pytest.mark.asyncio
    async def test_create_menu_directory_type_success(self, authenticated_client, cleanup_menu):
        """测试创建目录类型菜单成功"""
        menu_api = MenuAPI(authenticated_client)
        timestamp = int(time.time() * 1000)
        
        menu_data = {
            "menuName": f"目录_{timestamp}",
            "parentId": 0,
            "orderNum": 1,
            "menuType": "M",
            "status": "0"
        }
        
        response = await menu_api.create_menu(menu_data)
        
        assert response.status_code == 201
        data = response.json()
        assert data["menuType"] == "M"
        
        cleanup_menu.append(data["id"])
    
    @pytest.mark.asyncio
    async def test_create_menu_button_type_success(self, authenticated_client, cleanup_menu):
        """测试创建按钮类型菜单成功"""
        menu_api = MenuAPI(authenticated_client)
        timestamp = int(time.time() * 1000)
        
        menu_data = {
            "menuName": f"按钮_{timestamp}",
            "parentId": 1,
            "orderNum": 1,
            "menuType": "F",
            "perms": f"system:button:{timestamp}",
            "status": "0"
        }
        
        response = await menu_api.create_menu(menu_data)
        
        assert response.status_code == 201
        data = response.json()
        assert data["menuType"] == "F"
        
        cleanup_menu.append(data["id"])