"""
Tests for the MolecularInteractionAnalyzer class.
"""

import pytest
import math
from hbat.core.analyzer import MolecularInteractionAnalyzer
from hbat.constants.parameters import AnalysisParameters
from tests.conftest import (
    ExpectedResults, 
    PDBFixingExpectedResults,
    validate_hydrogen_bond, 
    validate_pi_interaction, 
    validate_cooperativity_chain
)


class TestMolecularInteractionAnalyzer:
    """Test cases for MolecularInteractionAnalyzer."""
    
    def test_analyzer_creation(self):
        """Test analyzer creation with different parameters."""
        # Default parameters
        analyzer = MolecularInteractionAnalyzer()
        assert analyzer is not None
        assert hasattr(analyzer, 'parameters')
        
        # Custom parameters
        params = AnalysisParameters(hb_distance_cutoff=3.0)
        analyzer = MolecularInteractionAnalyzer(params)
        assert analyzer.parameters.hb_distance_cutoff == 3.0
    
    def test_analyzer_with_pdb_fixing_parameters(self):
        """Test analyzer creation with PDB fixing parameters."""
        # Valid PDB fixing parameters
        params = AnalysisParameters(
            fix_pdb_enabled=True,
            fix_pdb_method="pdbfixer",
            fix_pdb_add_hydrogens=True,
            fix_pdb_add_heavy_atoms=False
        )
        analyzer = MolecularInteractionAnalyzer(params)
        assert analyzer.parameters.fix_pdb_enabled is True
        assert analyzer.parameters.fix_pdb_method == "pdbfixer"
        
        # Invalid PDB fixing parameters should raise error
        invalid_params = AnalysisParameters(
            fix_pdb_enabled=True,
            fix_pdb_method="invalid_method"
        )
        with pytest.raises(ValueError):
            MolecularInteractionAnalyzer(invalid_params)
    
    def test_analyzer_initial_state(self):
        """Test analyzer initial state."""
        analyzer = MolecularInteractionAnalyzer()
        
        assert len(analyzer.hydrogen_bonds) == 0
        assert len(analyzer.halogen_bonds) == 0
        assert len(analyzer.pi_interactions) == 0
        assert len(analyzer.cooperativity_chains) == 0
        
        summary = analyzer.get_summary()
        assert summary['hydrogen_bonds']['count'] == 0
        assert summary['halogen_bonds']['count'] == 0
        assert summary['pi_interactions']['count'] == 0
        assert summary['total_interactions'] == 0
        
        # Test that analyzer has PDB fixing methods
        assert hasattr(analyzer, '_apply_pdb_fixing'), "Should have _apply_pdb_fixing method"
    
    @pytest.mark.integration
    def test_complete_analysis_workflow(self, sample_pdb_file):
        """Test complete analysis workflow with real PDB file."""
        analyzer = MolecularInteractionAnalyzer()
        
        # Run analysis
        success = analyzer.analyze_file(sample_pdb_file)
        assert success, "Analysis should succeed"
        
        # Validate results
        stats = analyzer.get_summary()
        
        assert summary['hydrogen_bonds']['count'] >= ExpectedResults.MIN_HYDROGEN_BONDS, \
            f"Expected >={ExpectedResults.MIN_HYDROGEN_BONDS} H-bonds, got {summary['hydrogen_bonds']['count']}"
        assert stats['pi_interactions'] >= ExpectedResults.MIN_PI_INTERACTIONS, \
            f"Expected >={ExpectedResults.MIN_PI_INTERACTIONS} π-interactions, got {stats['pi_interactions']}"
        assert stats['total_interactions'] >= ExpectedResults.MIN_TOTAL_INTERACTIONS, \
            f"Expected >={ExpectedResults.MIN_TOTAL_INTERACTIONS} total interactions, got {stats['total_interactions']}"
    
    @pytest.mark.integration
    def test_pdb_fixing_workflow(self, pdb_fixing_test_file):
        """Test analysis workflow with PDB fixing enabled using 1ubi.pdb."""
        # Test with OpenBabel fixing
        params_ob = AnalysisParameters(
            fix_pdb_enabled=True,
            fix_pdb_method="openbabel",
            fix_pdb_add_hydrogens=True
        )
        analyzer_ob = MolecularInteractionAnalyzer(params_ob)
        
        success = analyzer_ob.analyze_file(pdb_fixing_test_file)
        assert success, "Analysis with OpenBabel PDB fixing should succeed"
        
        stats_ob = analyzer_ob.get_statistics()
        assert stats_ob['hydrogen_bonds'] >= 0, "Should have non-negative hydrogen bonds"
        assert stats_ob['total_interactions'] >= PDBFixingExpectedResults.MIN_TOTAL_INTERACTIONS, \
            f"Expected >={PDBFixingExpectedResults.MIN_TOTAL_INTERACTIONS} total interactions with fixing"
        
        # Test with PDBFixer fixing
        params_pdb = AnalysisParameters(
            fix_pdb_enabled=True,
            fix_pdb_method="pdbfixer",
            fix_pdb_add_hydrogens=True,
            fix_pdb_add_heavy_atoms=True
        )
        analyzer_pdb = MolecularInteractionAnalyzer(params_pdb)
        
        success = analyzer_pdb.analyze_file(pdb_fixing_test_file)
        assert success, "Analysis with PDBFixer PDB fixing should succeed"
        
        stats_pdb = analyzer_pdb.get_statistics()
        assert stats_pdb['hydrogen_bonds'] >= 0, "Should have non-negative hydrogen bonds"
    
    @pytest.mark.integration
    def test_hydrogen_bond_analysis(self, sample_pdb_file):
        """Test hydrogen bond detection and validation."""
        analyzer = MolecularInteractionAnalyzer()
        success = analyzer.analyze_file(sample_pdb_file)
        assert success
        
        hbonds = analyzer.hydrogen_bonds
        assert len(hbonds) > 0, "Should find hydrogen bonds"
        
        # Validate first few hydrogen bonds
        for hb in hbonds[:5]:
            validate_hydrogen_bond(hb)
            
            # Additional validation
            assert hb.distance > 0, "Distance should be positive"
            assert hb.distance <= analyzer.parameters.hb_distance_cutoff, \
                "Distance should be within cutoff"
            
            # Angle should be in reasonable range
            angle_degrees = math.degrees(hb.angle)
            assert angle_degrees >= analyzer.parameters.hb_angle_cutoff, \
                f"Angle {angle_degrees}° should be >= {analyzer.parameters.hb_angle_cutoff}°"
    
    def test_bond_based_hydrogen_donor_detection(self, sample_pdb_file):
        """Test that hydrogen bond donor detection uses pre-calculated bonds."""
        analyzer = MolecularInteractionAnalyzer()
        success = analyzer.analyze_file(sample_pdb_file)
        assert success, "Analysis should succeed"
        
        # Get hydrogen bond donors using the updated method
        donors = analyzer._get_hydrogen_bond_donors()
        assert isinstance(donors, list), "Should return a list of donors"
        
        # Validate donor structure (NumPy analyzer returns 4-tuples)
        for heavy_atom, hydrogen_atom, donor_idx, hydrogen_idx in donors[:5]:  # Check first 5 donors
            # Heavy atom should be a donor element
            assert heavy_atom.element.upper() in ["N", "O", "S"], \
                f"Heavy atom element {heavy_atom.element} should be N, O, or S"
            
            # Hydrogen should be hydrogen
            assert hydrogen_atom.is_hydrogen(), "Hydrogen atom should be hydrogen"
            
            # Verify they are actually bonded according to the bond list
            bonded_serials = analyzer.parser.get_bonded_atoms(hydrogen_atom.serial)
            assert heavy_atom.serial in bonded_serials, \
                "Heavy atom and hydrogen should be bonded according to bond list"
        
        # Test that we're actually using bonds vs falling back to distance calculation
        # The parser should have detected bonds during parsing
        bonds = analyzer.parser.get_bonds()
        assert len(bonds) > 0, "Parser should have detected bonds"
    
    @pytest.mark.integration
    def test_pi_interaction_analysis(self, sample_pdb_file):
        """Test π interaction detection and validation."""
        analyzer = MolecularInteractionAnalyzer()
        success = analyzer.analyze_file(sample_pdb_file)
        assert success
        
        pi_interactions = analyzer.pi_interactions
        if len(pi_interactions) > 0:
            # Validate π interactions
            for pi in pi_interactions[:3]:
                validate_pi_interaction(pi)
                
                # Additional validation
                assert pi.distance > 0, "Distance should be positive"
                assert pi.distance <= analyzer.parameters.pi_distance_cutoff, \
                    "Distance should be within cutoff"
                
                # Check π center coordinates
                assert hasattr(pi.pi_center, 'x'), "π center should have coordinates"
                assert hasattr(pi.pi_center, 'y'), "π center should have coordinates"
                assert hasattr(pi.pi_center, 'z'), "π center should have coordinates"
    
    @pytest.mark.integration
    def test_cooperativity_analysis(self, sample_pdb_file):
        """Test cooperativity chain analysis."""
        analyzer = MolecularInteractionAnalyzer()
        success = analyzer.analyze_file(sample_pdb_file)
        assert success
        
        chains = analyzer.cooperativity_chains
        stats = analyzer.get_summary()
        
        if len(chains) > 0:
            assert stats.get('cooperativity_chains', 0) == len(chains), \
                "Statistics should match actual chain count"
            
            # Validate cooperativity chains
            for chain in chains[:3]:
                validate_cooperativity_chain(chain)
    
    def test_bond_based_halogen_detection(self, sample_pdb_file):
        """Test that halogen bond detection uses pre-calculated bonds."""
        analyzer = MolecularInteractionAnalyzer()
        success = analyzer.analyze_file(sample_pdb_file)
        assert success, "Analysis should succeed"
        
        # Test halogen atom detection - NumPy analyzer uses different internal structure
        # We'll test the halogen bonds that were actually found instead
        halogens = []
        for xb in analyzer.halogen_bonds:
            if hasattr(xb, 'halogen'):
                halogens.append(xb.halogen)
        
        # If no halogen bonds found, that's expected for 6RSA.pdb (no halogens)
        if not halogens:
            pytest.skip("No halogen bonds found in test file - expected for 6RSA.pdb")
        
        assert isinstance(halogens, list), "Should return a list of halogens"
        
        # Verify that each halogen is actually bonded to carbon
        atom_map = {atom.serial: atom for atom in analyzer.parser.atoms}
        
        for halogen in halogens:
            # Should be a halogen element
            assert halogen.element.upper() in ["F", "CL", "BR", "I"], \
                f"Atom element {halogen.element} should be a halogen"
            
            # Should be bonded to at least one carbon according to bond list
            bonded_serials = analyzer.parser.get_bonded_atoms(halogen.serial)
            has_carbon_bond = False
            for bonded_serial in bonded_serials:
                bonded_atom = atom_map.get(bonded_serial)
                if bonded_atom is not None and bonded_atom.element.upper() == "C":
                    has_carbon_bond = True
                    break
            
            assert has_carbon_bond, \
                f"Halogen {halogen.element} at serial {halogen.serial} should be bonded to carbon"
        
        # Test finding bonded carbon for each halogen (inline logic since _find_bonded_carbon doesn't exist)
        for halogen in halogens[:5]:  # Test first 5 halogens
            # Use the same logic as in _get_halogen_atoms to find bonded carbon
            bonded_serials = analyzer.parser.get_bonded_atoms(halogen.serial)
            bonded_carbon = None
            for bonded_serial in bonded_serials:
                bonded_atom = atom_map.get(bonded_serial)
                if bonded_atom is not None and bonded_atom.element.upper() == "C":
                    bonded_carbon = bonded_atom
                    break
            
            if bonded_carbon is not None:  # May be None if no carbon bonded
                assert bonded_carbon.element.upper() == "C", \
                    "Bonded atom should be carbon"
                
                # Verify they are actually bonded according to bond list
                assert bonded_carbon.serial in bonded_serials, \
                    "Carbon and halogen should be bonded according to bond list"
        
        # Verify bond detection is working
        bonds = analyzer.parser.get_bonds()
        assert len(bonds) > 0, "Parser should have detected bonds"
    
    def test_halogen_bond_classification(self):
        """Test halogen bond classification via _check_halogen_bond method."""
        analyzer = MolecularInteractionAnalyzer()
        
        # Create test atoms for different halogen bond types
        from hbat.core.structure import Atom
        from hbat.core.np_vector import NPNPVec3D
        
        # Test that _check_halogen_bond creates correct bond_type
        # Note: This test is indirect since _classify_halogen_bond doesn't exist
        # The bond_type is created in _check_halogen_bond method
        
        # For this test, we'll verify that the bond_type property
        # in HalogenBond objects has the expected format
        cl_atom = Atom(
            serial=1, name="CL", alt_loc="", res_name="TEST", chain_id="A",
            res_seq=1, i_code="", coords=NPVec3D(0, 0, 0), occupancy=1.0,
            temp_factor=20.0, element="CL", charge="", record_type="ATOM"
        )
        
        o_atom = Atom(
            serial=2, name="O", alt_loc="", res_name="TEST", chain_id="A",
            res_seq=2, i_code="", coords=NPVec3D(2, 0, 0), occupancy=1.0,
            temp_factor=20.0, element="O", charge="", record_type="ATOM"
        )
        
        # The _check_halogen_bond method creates bond_type as f"C-{halogen.element}...{acceptor.element}"
        # So we expect "C-CL...O" format, not "CL...O"
        # This test validates the bond type creation logic indirectly
        
        # Test format expectations - the actual classification is done in _check_halogen_bond
        expected_formats = [
            ("CL", "O", "C-CL...O"),
            ("BR", "N", "C-BR...N"), 
            ("I", "S", "C-I...S"),
            ("F", "N", "C-F...N")
        ]
        
        for halogen_elem, acceptor_elem, expected_format in expected_formats:
            # Test that the expected format matches what _check_halogen_bond would create
            assert expected_format == f"C-{halogen_elem}...{acceptor_elem}", \
                f"Bond type format check failed for {halogen_elem}...{acceptor_elem}"

    @pytest.mark.integration
    def test_interaction_statistics(self, sample_pdb_file):
        """Test interaction statistics consistency."""
        analyzer = MolecularInteractionAnalyzer()
        success = analyzer.analyze_file(sample_pdb_file)
        assert success
        
        stats = analyzer.get_summary()
        
        # Check that statistics match actual counts
        assert summary['hydrogen_bonds']['count'] == len(analyzer.hydrogen_bonds), \
            "H-bond count mismatch"
        assert stats['halogen_bonds'] == len(analyzer.halogen_bonds), \
            "Halogen bond count mismatch"
        assert stats['pi_interactions'] == len(analyzer.pi_interactions), \
            "π-interaction count mismatch"
        
        # Total should be sum of individual types
        expected_total = (summary['hydrogen_bonds']['count'] + 
                         stats['halogen_bonds'] + 
                         stats['pi_interactions'])
        assert stats['total_interactions'] == expected_total, \
            "Total interactions should sum correctly"
    
    @pytest.mark.integration
    def test_analysis_modes(self, sample_pdb_file):
        """Test different analysis modes."""
        # Complete mode
        params_complete = AnalysisParameters(analysis_mode="complete")
        analyzer_complete = MolecularInteractionAnalyzer(params_complete)
        success = analyzer_complete.analyze_file(sample_pdb_file)
        assert success
        
        stats_complete = analyzer_complete.get_statistics()
        
        # Local mode
        params_local = AnalysisParameters(analysis_mode="local")
        analyzer_local = MolecularInteractionAnalyzer(params_local)
        success = analyzer_local.analyze_file(sample_pdb_file)
        assert success
        
        stats_local = analyzer_local.get_statistics()
        
        # Complete mode should generally find more interactions
        assert stats_complete['total_interactions'] >= stats_local['total_interactions'], \
            "Complete mode should find at least as many interactions as local mode"
    
    @pytest.mark.integration
    def test_parameter_effects(self, sample_pdb_file):
        """Test effects of different parameter values."""
        # Strict parameters
        strict_params = AnalysisParameters(
            hb_distance_cutoff=3.0,
            hb_angle_cutoff=140.0
        )
        analyzer_strict = MolecularInteractionAnalyzer(strict_params)
        success = analyzer_strict.analyze_file(sample_pdb_file)
        assert success
        
        # Permissive parameters
        permissive_params = AnalysisParameters(
            hb_distance_cutoff=4.0,
            hb_angle_cutoff=110.0
        )
        analyzer_permissive = MolecularInteractionAnalyzer(permissive_params)
        success = analyzer_permissive.analyze_file(sample_pdb_file)
        assert success
        
        strict_stats = analyzer_strict.get_statistics()
        permissive_stats = analyzer_permissive.get_statistics()
        
        # Permissive should generally find more interactions
        assert permissive_summary['hydrogen_bonds']['count'] >= strict_summary['hydrogen_bonds']['count'], \
            "Permissive parameters should find at least as many H-bonds"
    
    @pytest.mark.integration
    def test_pdb_fixing_effects(self, pdb_fixing_test_file):
        """Test effects of PDB fixing on analysis results using 1ubi.pdb."""
        # Analysis without PDB fixing
        params_no_fix = AnalysisParameters(fix_pdb_enabled=False)
        analyzer_no_fix = MolecularInteractionAnalyzer(params_no_fix)
        success = analyzer_no_fix.analyze_file(pdb_fixing_test_file)
        assert success
        
        # Analysis with PDB fixing (add hydrogens)
        params_with_fix = AnalysisParameters(
            fix_pdb_enabled=True,
            fix_pdb_method="openbabel",
            fix_pdb_add_hydrogens=True
        )
        analyzer_with_fix = MolecularInteractionAnalyzer(params_with_fix)
        success = analyzer_with_fix.analyze_file(pdb_fixing_test_file)
        assert success
        
        stats_no_fix = analyzer_no_fix.get_statistics()
        stats_with_fix = analyzer_with_fix.get_statistics()
        
        # PDB fixing should generally not decrease interaction count
        # (may find more interactions with added hydrogens)
        assert stats_with_fix['total_interactions'] >= 0, "Should have non-negative interactions"
        assert stats_no_fix['total_interactions'] >= 0, "Should have non-negative interactions"
        
        print(f"\nPDB fixing effects on 1ubi.pdb:")
        print(f"  Without fixing: {stats_no_fix['total_interactions']} interactions")
        print(f"  With fixing: {stats_with_fix['total_interactions']} interactions")


    @pytest.mark.integration
    def test_specific_hydrogen_bond_measurements(self):
        """Test specific hydrogen bond measurements for 6RSA.pdb atom pairs."""
        # Use 6RSA.pdb for this test
        analyzer = MolecularInteractionAnalyzer()
        success = analyzer.analyze_file("example_pdb_files/6rsa.pdb")
        assert success, "Analysis of 6RSA.pdb should succeed"
        
        # Define the specific atom pairs to test
        # Format: (donor_serial, acceptor_serial)
        test_pairs = [
            (173, 1880),
            (191, 1880),
            (619, 1872),
            (677, 1868),
            (682, 1868),
            (682, 1864),
            (1791, 1882)
        ]
        
        # Get all hydrogen bonds
        hbonds = analyzer.hydrogen_bonds
        
        # Find hydrogen bonds involving our test pairs
        found_pairs = {}
        reversed_pairs = {}  # Check reversed donor-acceptor pairs
        for hb in hbonds:
            donor_serial = hb.donor.serial
            acceptor_serial = hb.acceptor.serial
            
            for donor, acceptor in test_pairs:
                if donor_serial == donor and acceptor_serial == acceptor:
                    found_pairs[(donor, acceptor)] = hb
                    break
                elif donor_serial == acceptor and acceptor_serial == donor:
                    # Found the pair but with reversed roles
                    reversed_pairs[(donor, acceptor)] = hb
        
        # Print results for documentation
        print(f"\nHydrogen bond measurements for 6RSA.pdb specific atom pairs:")
        print("=" * 100)
        print(f"{'Donor':<10} {'D-Elem':<8} {'Acceptor':<10} {'A-Elem':<8} {'D-A (Å)':<10} {'H-A (Å)':<10} {'D-H-A (°)':<10} {'H-Bond':<10}")
        print("-" * 100)
        
        for donor, acceptor in test_pairs:
            if (donor, acceptor) in found_pairs:
                hb = found_pairs[(donor, acceptor)]
                # D-A distance
                da_distance = hb.donor_acceptor_distance
                # H-A distance
                ha_distance = hb.distance
                # D-H-A angle in degrees
                dha_angle = math.degrees(hb.angle)
                # Get element names
                donor_elem = hb.donor.element
                acceptor_elem = hb.acceptor.element
                
                print(f"{donor:<10} {donor_elem:<8} {acceptor:<10} {acceptor_elem:<8} {da_distance:<10.3f} {ha_distance:<10.3f} {dha_angle:<10.1f} {'Yes':<10}")
                
                # Validate measurements
                assert da_distance > 0, f"D-A distance should be positive for {donor}/{acceptor}"
                assert ha_distance > 0, f"H-A distance should be positive for {donor}/{acceptor}"
                assert 0 <= dha_angle <= 180, f"D-H-A angle should be between 0-180° for {donor}/{acceptor}"
                
                # Check that distances are within expected ranges
                assert 2.0 <= da_distance <= 4.0, f"D-A distance {da_distance:.3f} outside expected range for {donor}/{acceptor}"
                assert 1.0 <= ha_distance <= 3.5, f"H-A distance {ha_distance:.3f} outside expected range for {donor}/{acceptor}"
                assert dha_angle >= 90, f"D-H-A angle {dha_angle:.1f} too acute for {donor}/{acceptor}"
            else:
                # Find the atoms to calculate distance even if no H-bond
                donor_atom = None
                acceptor_atom = None
                for atom in analyzer.parser.atoms:
                    if atom.serial == donor:
                        donor_atom = atom
                    elif atom.serial == acceptor:
                        acceptor_atom = atom
                    if donor_atom and acceptor_atom:
                        break
                
                if donor_atom and acceptor_atom:
                    # Calculate D-A distance
                    da_distance = donor_atom.coords.distance_to(acceptor_atom.coords)
                    donor_elem = donor_atom.element
                    acceptor_elem = acceptor_atom.element
                    # H-A distance and D-H-A angle are N/A without a hydrogen bond
                    print(f"{donor:<10} {donor_elem:<8} {acceptor:<10} {acceptor_elem:<8} {da_distance:<10.3f} {'N/A':<10} {'N/A':<10} {'No':<10}")
                else:
                    print(f"{donor:<10} {'N/A':<8} {acceptor:<10} {'N/A':<8} {'N/A':<10} {'N/A':<10} {'N/A':<10} {'No':<10}")
        
        print("=" * 100)
        
        # Check for reversed pairs
        if reversed_pairs:
            print(f"\nFound {len(reversed_pairs)} hydrogen bonds with reversed donor-acceptor roles:")
            print("=" * 100)
            print(f"{'Expected D':<12} {'Expected A':<12} {'Actual D':<10} {'Actual A':<10} {'D-Elem':<8} {'A-Elem':<8}")
            print("-" * 100)
            for (expected_d, expected_a), hb in reversed_pairs.items():
                print(f"{expected_d:<12} {expected_a:<12} {hb.donor.serial:<10} {hb.acceptor.serial:<10} {hb.donor.element:<8} {hb.acceptor.element:<8}")
            print("=" * 100)
        
        # Ensure we found at least some of the expected pairs
        found_count = len(found_pairs)
        print(f"\nFound {found_count} out of {len(test_pairs)} expected hydrogen bonds")
        assert found_count > 0, "Should find at least some of the expected hydrogen bonds"


class TestPerformanceMetrics:
    """Test performance and expected results."""
    
    @pytest.mark.integration
    @pytest.mark.slow
    def test_performance_benchmarks(self, sample_pdb_file):
        """Test that analysis meets performance expectations."""
        analyzer = MolecularInteractionAnalyzer()
        
        import time
        start_time = time.time()
        success = analyzer.analyze_file(sample_pdb_file)
        analysis_time = time.time() - start_time
        
        assert success, "Analysis should succeed"
        
        # Analysis should complete in reasonable time (adjust as needed)
        assert analysis_time < 60.0, f"Analysis took too long: {analysis_time:.2f}s"
        
        stats = analyzer.get_summary()
        
        # Performance metrics - should find substantial interactions
        assert summary['hydrogen_bonds']['count'] >= ExpectedResults.MIN_HYDROGEN_BONDS, \
            "Should find substantial number of hydrogen bonds"
        assert stats['total_interactions'] >= ExpectedResults.MIN_TOTAL_INTERACTIONS, \
            "Should find substantial total interactions"
    
    @pytest.mark.integration
    def test_expected_results_documentation(self, sample_pdb_file):
        """Document expected results for 6RSA.pdb."""
        analyzer = MolecularInteractionAnalyzer()
        success = analyzer.analyze_file(sample_pdb_file)
        assert success
        
        stats = analyzer.get_summary()
        
        # Print results for documentation
        print(f"\nExpected results for 6RSA.pdb:")
        print(f"  - Hydrogen bonds: {summary['hydrogen_bonds']['count']}")
        print(f"  - Halogen bonds: {stats['halogen_bonds']}")
        print(f"  - π interactions: {stats['pi_interactions']}")
        print(f"  - Cooperativity chains: {stats.get('cooperativity_chains', 0)}")
        print(f"  - Total interactions: {stats['total_interactions']}")
        
        # Validate against minimum expectations
        assert summary['hydrogen_bonds']['count'] >= ExpectedResults.MIN_HYDROGEN_BONDS
        assert stats['pi_interactions'] >= ExpectedResults.MIN_PI_INTERACTIONS
        assert stats['total_interactions'] >= ExpectedResults.MIN_TOTAL_INTERACTIONS
    
    @pytest.mark.integration
    def test_pdb_fixing_results_documentation(self, pdb_fixing_test_file):
        """Document expected results for 1ubi.pdb with PDB fixing."""
        # Test with OpenBabel fixing
        params_ob = AnalysisParameters(
            fix_pdb_enabled=True,
            fix_pdb_method="openbabel",
            fix_pdb_add_hydrogens=True
        )
        analyzer_ob = MolecularInteractionAnalyzer(params_ob)
        success = analyzer_ob.analyze_file(pdb_fixing_test_file)
        assert success
        
        stats_ob = analyzer_ob.get_statistics()
        
        # Print results for documentation
        print(f"\nExpected results for 1ubi.pdb with OpenBabel PDB fixing:")
        print(f"  - Hydrogen bonds: {stats_ob['hydrogen_bonds']}")
        print(f"  - Halogen bonds: {stats_ob['halogen_bonds']}")
        print(f"  - π interactions: {stats_ob['pi_interactions']}")
        print(f"  - Total interactions: {stats_ob['total_interactions']}")
        
        # Test with PDBFixer fixing
        params_pdb = AnalysisParameters(
            fix_pdb_enabled=True,
            fix_pdb_method="pdbfixer",
            fix_pdb_add_hydrogens=True,
            fix_pdb_add_heavy_atoms=True
        )
        analyzer_pdb = MolecularInteractionAnalyzer(params_pdb)
        success = analyzer_pdb.analyze_file(pdb_fixing_test_file)
        assert success
        
        stats_pdb = analyzer_pdb.get_statistics()
        
        print(f"\nExpected results for 1ubi.pdb with PDBFixer PDB fixing:")
        print(f"  - Hydrogen bonds: {stats_pdb['hydrogen_bonds']}")
        print(f"  - Halogen bonds: {stats_pdb['halogen_bonds']}")
        print(f"  - π interactions: {stats_pdb['pi_interactions']}")
        print(f"  - Total interactions: {stats_pdb['total_interactions']}")
        
        # Both should produce valid results
        assert stats_ob['total_interactions'] >= 0
        assert stats_pdb['total_interactions'] >= 0