"""Main module called when launching the software."""

__authors__ = ["Lucas ROUAUD"]
__contact__ = ["lucas.rouaud@gmail.com"]
__version__ = "alpha.0.0.1"
__date__ = "2026-02-18"
__copyright__ = ["MIT License", "CC-BY-SA"]

# =======================
# Python internal package
# =======================
# A
import argparse

# =======================
# Python internal package
# =======================
# M
import MDAnalysis

# ==============
# Module package
# ==============
# P
from .parser.argument import (
    parse_argument,
)
from .parser.configuration import (
    Configuration,
)
from .parser.molecule import (
    Molecule,
    MoleculeParser,
)
from .pharmacophore import (
    PharmacophoreFactory,
)
from .plip_detection import (
    CheckNeighbour,
    InteractionDetection,
)

# U
from .utils.generic import (
    CsvWriter,
)
from .utils.messenger import (
    Error,
)

# V
from .visualization.molstar import (
    Molstar,
)
from .visualization.pymol import (
    Pymol,
)


def main() -> None:
    """Main function of the program. Launch everything."""
    # ==============
    # INITIALIZATION
    # ==============
    argument: argparse.Namespace = parse_argument(__version__)
    configuration: Configuration = Configuration(argument.parameter)

    check_neighbour: CheckNeighbour | None = None
    do_checking_neighbour: bool = False

    if len(argument.input) == 1:
        argument.input.append(argument.input[0])
        do_checking_neighbour = True

    if len(argument.selection) == 1:
        argument.selection.append("")

    if argument.pharmacophore == []:
        argument.pharmacophore = [[], []]

    if configuration["miscellaneous"].enable_vdw_radius:
        vdw_radius: dict = configuration["vdw_radius"].dict()
    else:
        vdw_radius = MDAnalysis.guesser.tables.vdwradii

    # ================
    # PARSING MOLECULE
    # ================
    parsed_molecule: list[Molecule] = []

    for index, input_file in enumerate(argument.input):
        parsed_molecule.append(
            MoleculeParser(
                file=input_file,
                selection=argument.selection[index],
                add_hydrogen=argument.add_hydrogen[index],
                vdw_radius=vdw_radius,
            ),
        )

    if do_checking_neighbour:
        check_neighbour = CheckNeighbour(
            parsed_molecule[0],
            parsed_molecule[1],
            configuration["miscellaneous"],
        )

    # =======================
    # COMPUTING PHARMACOPHORE
    # =======================
    factory: PharmacophoreFactory = PharmacophoreFactory(
        configuration["miscellaneous"], argument.feature_file
    )
    collection_list: list[dict] = []

    for index, molecule in enumerate(parsed_molecule):
        collection_list.append(factory.get_collection(molecule))

        if argument.pharmacophore[index] != []:
            csv = CsvWriter(
                [collection_list[-1]],
                "pharmacophore",
                configuration["miscellaneous"],
            )

            with open(
                argument.pharmacophore[index], "w", encoding="utf-8"
            ) as file:
                file.write(str(csv))

        if argument.selection != "":
            message: str = f"and given selection '{argument.selection[index]}'"
        else:
            message: str = ""

        if collection_list[-1] == {}:
            Error.NO_PHARMACOPHORE_DETECTED(
                ValueError,
                file=argument.input[index],
                message=message,
            )

    # =====================
    # COMPUTING INTERACTION
    # =====================
    interaction: InteractionDetection = InteractionDetection(
        collection_list[0],
        collection_list[1],
        configuration=configuration["interaction_configuration"],
        miscellaneous=configuration["miscellaneous"],
        check_neighbour=check_neighbour,
    )

    if interaction.collection:
        csv_interaction = CsvWriter(
            [interaction.collection],
            "interaction",
            configuration["miscellaneous"],
        )

        with open(argument.output, "w", encoding="utf-8") as file:
            file.write(str(csv_interaction))

    # =====================
    # MOLSTAR VISUALIZATION
    # =====================
    if argument.visualization is not None:
        create_visualization_argument: dict = {
            "path": argument.visualization,
            "pharmacophore_collection_a": collection_list[0],
            "pharmacophore_collection_b": collection_list[1],
            "interaction_collection": interaction.collection,
            "drawning_configuration": configuration["visualization"],
        }

        match argument.visualization.suffix.lower():
            case ".mvsj":
                Molstar(**create_visualization_argument)
            case ".pml":
                Pymol(**create_visualization_argument)

    if not interaction.collection:
        Error.NO_INTERACTION(ValueError)


if __name__ == "__main__":
    main()
