"""
Extract natural frequencies from modal analysis
Auto-generated by Atomizer Phase 3 - pyNastran Research Agent

Pattern: eigenvalue_extraction
Element Type: General
Result Type: eigenvalues
API: model.eigenvalues[subcase]
"""

from pathlib import Path
from typing import Dict, Any
import numpy as np
from pyNastran.op2.op2 import OP2


def extract_frequency(op2_file: Path, subcase: int = 1, mode_number: int = 1):
    """
    Extract natural frequency results from modal analysis OP2 file.

    Args:
        op2_file: Path to OP2 file
        subcase: Subcase ID for modal analysis (default: 1)
        mode_number: Which mode to extract (1-indexed, default: 1 for fundamental frequency)

    Returns:
        Dictionary containing frequency data
    """
    from pyNastran.op2.op2 import OP2
    import numpy as np

    model = OP2()
    model.read_op2(str(op2_file))

    # Access eigenvalues from modal analysis
    # NX Nastran often uses empty string '' as subcase key
    available_subcases = list(model.eigenvalues.keys())
    if not available_subcases:
        raise ValueError(f"No eigenvalue data found in OP2 file: {op2_file}")

    # Use the first available subcase (often '' for NX Nastran)
    actual_subcase = available_subcases[0]
    eigenvalues = model.eigenvalues[actual_subcase]

    # Extract frequency data for the specified mode
    # RealEigenvalues object has different attributes than expected
    # Try to access frequencies - could be in different formats

    # Mode number is 1-indexed, array is 0-indexed
    mode_idx = mode_number - 1

    # Try different attribute names for frequencies
    if hasattr(eigenvalues, 'cycles'):
        frequencies = eigenvalues.cycles
    elif hasattr(eigenvalues, 'frequencies'):
        frequencies = eigenvalues.frequencies
    else:
        # Try to get eigenvalues and convert to frequency
        if hasattr(eigenvalues, 'eigenvalues'):
            # eigenvalue (lambda) = (2*pi*f)^2, so f = sqrt(lambda) / (2*pi)
            eigenvals = eigenvalues.eigenvalues
            frequencies = np.sqrt(np.abs(eigenvals)) / (2.0 * np.pi)
        else:
            raise ValueError(f"Cannot find frequency data in eigenvalues object. Available attributes: {dir(eigenvalues)}")

    if mode_idx >= len(frequencies):
        raise ValueError(f"Mode {mode_number} not found. Only {len(frequencies)} modes available.")

    frequency = frequencies[mode_idx]  # Hz

    # Try to get eigenvalue if available
    if hasattr(eigenvalues, 'eigenvalues'):
        eigenvalue = eigenvalues.eigenvalues[mode_idx]
    elif hasattr(eigenvalues, 'eigrs'):
        eigenvalue = eigenvalues.eigrs[mode_idx]
    else:
        eigenvalue = (2.0 * np.pi * frequency) ** 2  # Convert back from frequency

    # Also return all frequencies for reference
    all_frequencies = list(frequencies)

    return {
        'frequency': float(frequency),
        'mode_number': int(mode_number),
        'eigenvalue': float(eigenvalue),
        'all_frequencies': all_frequencies,
        'n_modes': len(all_frequencies)
    }


if __name__ == '__main__':
    # Example usage
    import sys
    if len(sys.argv) > 1:
        op2_file = Path(sys.argv[1])
        mode_num = int(sys.argv[2]) if len(sys.argv) > 2 else 1
        result = extract_frequency(op2_file, mode_number=mode_num)
        print(f"Extraction result: {result}")
    else:
        print(f"Usage: python {sys.argv[0]} <op2_file> [mode_number]")
