"""Tests for database components."""

from __future__ import annotations

from unittest.mock import Mock

import pytest

from pytola_sim.lscsim.components.helpmodel import HelpComponent
from pytola_sim.lscsim.components.productdb import ProductDatabaseComponent
from pytola_sim.lscsim.components.setmodel import SettingsComponent
from pytola_sim.lscsim.components.simdb import SimulationDatabaseComponent


class TestProductDatabaseComponent:
    """Tests for ProductDatabaseComponent."""

    def test_component_initialization(self) -> None:
        """Test component initialization."""
        component = ProductDatabaseComponent()
        assert component.get_id() == "ProductDatabase"
        assert component.get_interface_count() == 1
        assert component.get_interface_id(0) == "IProductDBCommands"

    def test_product_operations(self) -> None:
        """Test product database operations."""
        component = ProductDatabaseComponent()
        main_ctrl = Mock()
        component.set_main_ctrl(main_ctrl)
        component.init()

        # Test adding product
        product_data = {"name": "测试产品", "code": "TEST-001", "category": "测试类别"}
        result = component.execute_command("ProductDB.AddProduct", product_data)
        assert result is True

        # Test loading products
        out_param = {}
        result = component.execute_command("ProductDB.LoadProducts", out_param=out_param)
        assert result is True
        assert "products" in out_param
        assert len(out_param["products"]) > 0

    def test_product_search(self) -> None:
        """Test product search functionality."""
        component = ProductDatabaseComponent()
        main_ctrl = Mock()
        component.set_main_ctrl(main_ctrl)
        component.init()

        # Test search
        search_criteria = {"name": "防护"}
        out_param = {}
        result = component.execute_command("ProductDB.SearchProducts", search_criteria, out_param)
        assert result is True
        assert "results" in out_param


class TestSimulationDatabaseComponent:
    """Tests for SimulationDatabaseComponent."""

    def test_component_initialization(self) -> None:
        """Test component initialization."""
        component = SimulationDatabaseComponent()
        assert component.get_id() == "SimulationDatabase"
        assert component.get_interface_count() == 1
        assert component.get_interface_id(0) == "ISimDBCommands"

    def test_material_operations(self) -> None:
        """Test material database operations."""
        component = SimulationDatabaseComponent()
        main_ctrl = Mock()
        component.set_main_ctrl(main_ctrl)
        component.init()

        # Test adding material
        material_data = {"name": "测试材料", "density": 7850, "young_modulus": 200e9}
        result = component.execute_command("SimDB.AddMaterial", material_data)
        assert result is True

        # Test loading materials
        out_param = {}
        result = component.execute_command("SimDB.LoadMaterials", out_param=out_param)
        assert result is True
        assert "materials" in out_param

    def test_target_plate_operations(self) -> None:
        """Test target plate operations."""
        component = SimulationDatabaseComponent()
        main_ctrl = Mock()
        component.set_main_ctrl(main_ctrl)
        component.init()

        # Test adding target plate
        plate_data = {"name": "测试靶板", "thickness": 20, "material": "钢材"}
        result = component.execute_command("SimDB.AddTargetPlate", plate_data)
        assert result is True

    def test_template_operations(self) -> None:
        """Test template operations."""
        component = SimulationDatabaseComponent()
        main_ctrl = Mock()
        component.set_main_ctrl(main_ctrl)
        component.init()

        # Test adding template
        template_data = {
            "name": "测试模板",
            "analysis_type": "static",
            "solver": "implicit",
        }
        result = component.execute_command("SimDB.AddTemplate", template_data)
        assert result is True


class TestSettingsComponent:
    """Tests for SettingsComponent."""

    def test_component_initialization(self) -> None:
        """Test component initialization."""
        component = SettingsComponent()
        assert component.get_id() == "Settings"
        assert component.get_interface_count() == 1
        assert component.get_interface_id(0) == "ISettingsCommands"

    def test_settings_operations(self) -> None:
        """Test settings operations."""
        component = SettingsComponent()
        main_ctrl = Mock()
        component.set_main_ctrl(main_ctrl)
        component.init()

        # Test loading settings
        out_param = {}
        result = component.execute_command("Settings.LoadSettings", out_param=out_param)
        assert result is True
        assert "settings" in out_param

        # Test updating setting
        update_data = {"key": "general.theme", "value": "dark"}
        result = component.execute_command("Settings.UpdateSetting", update_data)
        assert result is True

    def test_user_profile_operations(self) -> None:
        """Test user profile operations."""
        component = SettingsComponent()
        main_ctrl = Mock()
        component.set_main_ctrl(main_ctrl)
        component.init()

        # Test adding user profile
        user_data = {"username": "testuser", "role": "engineer"}
        result = component.execute_command("Settings.AddUserProfile", user_data)
        assert result is True

        # Test loading user profiles
        out_param = {}
        result = component.execute_command("Settings.LoadUserProfiles", out_param=out_param)
        assert result is True
        assert "profiles" in out_param


class TestHelpComponent:
    """Tests for HelpComponent."""

    def test_component_initialization(self) -> None:
        """Test component initialization."""
        component = HelpComponent()
        assert component.get_id() == "Help"
        assert component.get_interface_count() == 1
        assert component.get_interface_id(0) == "IHelpCommands"

    def test_help_operations(self) -> None:
        """Test help operations."""
        component = HelpComponent()
        main_ctrl = Mock()
        component.set_main_ctrl(main_ctrl)
        component.init()

        # Test showing documentation
        out_param = {}
        result = component.execute_command("Help.ShowDocumentation", {"topic": "index"}, out_param)
        assert result is True
        assert "content" in out_param

        # Test listing tutorials
        out_param = {}
        result = component.execute_command("Help.ListTutorials", out_param=out_param)
        assert result is True
        assert "tutorials" in out_param

        # Test showing FAQ
        out_param = {}
        result = component.execute_command("Help.ShowFAQ", {"category": "general"}, out_param)
        assert result is True
        assert "faq_items" in out_param

    def test_about_and_system_info(self) -> None:
        """Test about and system info operations."""
        component = HelpComponent()
        main_ctrl = Mock()
        component.set_main_ctrl(main_ctrl)
        component.init()

        # Test showing about info
        out_param = {}
        result = component.execute_command("Help.ShowAbout", out_param=out_param)
        assert result is True
        assert "about_info" in out_param

        # Test showing system info
        out_param = {}
        result = component.execute_command("Help.ShowSystemInfo", out_param=out_param)
        assert result is True
        assert "system_info" in out_param


if __name__ == "__main__":
    pytest.main([__file__, "-v"])
