"""Tests for business components."""

from __future__ import annotations

from unittest.mock import Mock

import pytest

from pytola_sim.lscsim.analysismodel import AnalysisComponent
from pytola_sim.lscsim.components.filemodel import FileModelComponent
from pytola_sim.lscsim.components.modelingmodel import ModelingComponent


class TestFileModelComponent:
    """Tests for FileModelComponent."""

    def test_component_initialization(self) -> None:
        """Test component initialization."""
        component = FileModelComponent()
        assert component.get_id() == "FileModel"
        assert component.get_interface_count() == 1
        assert component.get_interface_id(0) == "IFileModelCommands"

    def test_command_execution(self) -> None:
        """Test command execution."""
        component = FileModelComponent()
        main_ctrl = Mock()
        component.set_main_ctrl(main_ctrl)
        component.init()

        # Test known commands
        result = component.execute_command("File.NewProject")
        assert result is True

        result = component.execute_command("File.ImportCoordinates", {"file_path": "test.txt"})
        assert result is True

        # Test unknown command
        result = component.execute_command("Unknown.Command")
        assert result is False

    def test_interface_retrieval(self) -> None:
        """Test interface retrieval."""
        component = FileModelComponent()

        # Test valid interface
        interface = component.get_interface_ptr("IFileModelCommands")
        assert interface is not None
        assert interface == component  # Should return self

        # Test invalid interface
        interface = component.get_interface_ptr("InvalidInterface")
        assert interface is None


class TestModelingComponent:
    """Tests for ModelingComponent."""

    def test_component_initialization(self) -> None:
        """Test component initialization."""
        component = ModelingComponent()
        assert component.get_id() == "Modeling"
        assert component.get_interface_count() == 1
        assert component.get_interface_id(0) == "IModelingCommands"

    def test_modeling_commands(self) -> None:
        """Test modeling command execution."""
        component = ModelingComponent()
        main_ctrl = Mock()
        component.set_main_ctrl(main_ctrl)
        component.init()

        # Test geometry creation
        result = component.execute_command(
            "Modeling.CreateGeometry",
            {
                "type": "plate",
                "parameters": {"length": 100, "width": 50, "thickness": 10},
            },
        )
        assert result is True

        # Test material assignment
        result = component.execute_command("Modeling.AssignMaterial", {"material_name": "Steel", "elements": ["all"]})
        assert result is True

    def test_mesh_operations(self) -> None:
        """Test mesh-related operations."""
        component = ModelingComponent()
        main_ctrl = Mock()
        component.set_main_ctrl(main_ctrl)
        component.init()

        # Test mesh parameters
        result = component.execute_command("Modeling.SetMeshParameters", {"mesh_size": 2.0, "element_type": "solid"})
        assert result is True

        # Test mesh generation
        result = component.execute_command("Modeling.GenerateMesh")
        assert result is True


class TestAnalysisComponent:
    """Tests for AnalysisComponent."""

    def test_component_initialization(self) -> None:
        """Test component initialization."""
        component = AnalysisComponent()
        assert component.get_id() == "Analysis"
        assert component.get_interface_count() == 1
        assert component.get_interface_id(0) == "IAnalysisCommands"

    def test_analysis_commands(self) -> None:
        """Test analysis command execution."""
        component = AnalysisComponent()
        main_ctrl = Mock()
        component.set_main_ctrl(main_ctrl)
        component.init()

        # Test calculation setup
        result = component.execute_command(
            "Analysis.SetupCalculation",
            {"analysis_type": "static", "solver_type": "implicit"},
        )
        assert result is True

        # Test calculation control
        result = component.execute_command("Analysis.StartCalculation")
        assert result is True

        result = component.execute_command("Analysis.PauseCalculation")
        assert result is True

        result = component.execute_command("Analysis.StopCalculation")
        assert result is True

    def test_result_operations(self) -> None:
        """Test result-related operations."""
        component = AnalysisComponent()
        main_ctrl = Mock()
        component.set_main_ctrl(main_ctrl)
        component.init()

        # Test progress retrieval
        out_param = {}
        result = component.execute_command("Analysis.GetProgress", out_param=out_param)
        assert result is True
        assert "progress" in out_param

        # Test results retrieval
        out_param = {}
        result = component.execute_command("Analysis.GetResults", out_param=out_param)
        assert result is True
        assert "results" in out_param

        # Test envelope analysis
        result = component.execute_command("Analysis.EnvelopeAnalysis")
        assert result is True


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