from importlib import import_module

from .kinetic_modeling import (
    fit_compartment_model,
    lls_3k,
    lls_3k_vB,
    lls_4k,
    lls_4k_vB,
    make_compartment_model,
)

__all__ = [
    "make_compartment_model",
    "lls_3k",
    "lls_3k_vB",
    "lls_4k",
    "lls_4k_vB",
    "fit_compartment_model",
]

_OPTIONAL_EXPORTS = {
    "sample_config": ("._omegaconf_interpreter", "sample_config"),
    "make_table": ("._parquet_shards", "make_table"),
    "write_parquet_dataset": ("._parquet_shards", "write_parquet_dataset"),
    "write_time_sidecar": ("._parquet_shards", "write_time_sidecar"),
    "batch_to_table": ("._parquet_shards", "batch_to_table"),
    "write_batch": ("._parquet_shards", "write_batch"),
}

_OPTIONAL_DEPENDENCIES = {"omegaconf", "pandas", "pyarrow", "rich"}


def __getattr__(name: str):
    target = _OPTIONAL_EXPORTS.get(name)
    if target is None:
        raise AttributeError(f"module {__name__!r} has no attribute {name!r}")

    module_name, attr_name = target
    try:
        module = import_module(module_name, __name__)
    except ModuleNotFoundError as exc:
        missing = exc.name.split(".")[0] if exc.name else None
        if missing is None:
            message = str(exc)
            for dependency in _OPTIONAL_DEPENDENCIES:
                if dependency in message:
                    missing = dependency
                    break

        if missing in _OPTIONAL_DEPENDENCIES:
            raise ModuleNotFoundError(
                f"`lls.{name}` requires optional simulation/analysis dependencies. "
                "Install them with `lls[sim]`."
            ) from exc
        raise

    value = getattr(module, attr_name)
    globals()[name] = value
    return value
