"""
Radar material properties for electromagnetic calculations.

This module provides functions for accessing radar material properties including
permittivity and permeability data based on the Michielssen database. It supports
16 different radar materials with frequency-dependent properties in the GHz range.
"""

import jax.numpy as jnp
import numpy as onp

from jaxlayerlumos import utils_units


def get_eps_mu_Michielssen(material_indices, frequencies):
    """
    Get permittivity and permeability for radar materials from the Michielssen database.
    
    This function provides frequency-dependent permittivity and permeability values
    for 16 different radar materials. The materials include various types of
    absorbers and coatings commonly used in radar applications.
    
    Args:
        material_indices (onp.ndarray): Material indices (1-16) corresponding to
                                       different radar materials.
        frequencies (jnp.ndarray): Frequencies in Hz for which to calculate properties.
    
    Returns:
        tuple: (eps_r, mu_r) - Relative permittivity and permeability arrays
               with shape (n_materials, n_frequencies).
    
    Note:
        - Material indices must be between 1 and 16
        - Frequencies are converted to GHz internally for the calculations
        - Materials 1-5 have constant permittivity and frequency-dependent permeability
        - Materials 6-8 have frequency-dependent permittivity and constant permeability
        - Materials 9-16 have frequency-dependent permittivity and permeability
    """
    assert isinstance(material_indices, onp.ndarray)
    assert isinstance(frequencies, jnp.ndarray)
    assert material_indices.ndim == 1
    assert frequencies.ndim == 1
    for material_index in material_indices:
        assert material_index in onp.arange(1, 17)

    # Gets parameters from Michiellsen
    f = frequencies / utils_units.get_giga()  # in GHz
    M_epsr = jnp.vstack(
        [
            jnp.tile(
                jnp.array([10, 50, 15, 15, 15])[:, None], (1, len(f))
            ),  # Materials 1 to 5
            jnp.array(
                [  # Frequency-dependent permittivity for materials 6 to 8
                    5 / (f**0.861) - 1j * (8 / (f**0.569)),
                    8 / (f**0.778) - 1j * (10 / (f**0.682)),
                    10 / (f**0.778) - 1j * (6 / (f**0.861)),
                ]
            ),
            jnp.full((8, len(f)), 15, dtype=complex),  # Materials 9 to 16
        ]
    )

    # Fill constant values for permeability (mur)
    M_mur = jnp.vstack(
        [
            jnp.ones((2, len(f))),  # Materials 1 and 2
            jnp.array(
                [  # Frequency-dependent permeability for materials 3 to 5
                    5 / (f**0.974) - 1j * (10 / (f**0.961)),
                    3 / (f**1.0) - 1j * (15 / (f**0.957)),
                    7 / (f**1.0) - 1j * (12 / (f**1.0)),
                ]
            ),
            jnp.ones((3, len(f))),  # Materials 6 to 8
            jnp.array(
                [  # Frequency-dependent permeability for materials 9 to 16
                    (35 * (0.8**2)) / (f**2 + 0.8**2)
                    - 1j * (35 * 0.8 * f) / (f**2 + 0.8**2),
                    (35 * (0.5**2)) / (f**2 + 0.5**2)
                    - 1j * (35 * 0.5 * f) / (f**2 + 0.5**2),
                    (30 * (1**2)) / (f**2 + 1**2) - 1j * (30 * f) / (f**2 + 1**2),
                    (18 * (0.5**2)) / (f**2 + 0.5**2)
                    - 1j * (18 * 0.5 * f) / (f**2 + 0.5**2),
                    (20 * (1.5**2)) / (f**2 + 1.5**2)
                    - 1j * (20 * 1.5 * f) / (f**2 + 1.5**2),
                    (30 * (2.5**2)) / (f**2 + 2.5**2)
                    - 1j * (30 * 2.5 * f) / (f**2 + 2.5**2),
                    (30 * (2**2)) / (f**2 + 2**2) - 1j * (30 * 2 * f) / (f**2 + 2**2),
                    (25 * (3.5**2)) / (f**2 + 3.5**2)
                    - 1j * (25 * 3.5 * f) / (f**2 + 3.5**2),
                ]
            ),
        ]
    )

    # Initialize epsr and mur for the given material_indices
    eps_r = M_epsr[material_indices - 1, :]  # Python uses 0-based indexing
    mu_r = M_mur[material_indices - 1, :]

    return eps_r, mu_r
