"""
Main module for the Metamaterial Analysis Code (MAC) package. It represents the whole analysis.
"""

from os import remove, path
from datetime import datetime

from .MACModel import MACModel
from .MACGlobals import MAC_VERSION
from MetamaterialAnalysisCode.classes.MACSubcase import MACSubcase
from MetamaterialAnalysisCode.classes.MACLoadCase import MACForce, MACSpc, MACEigrl

class MACAnalysis:
    """
    Main class for the Metamaterial Analysis Code (MAC) package. It represents the whole analysis.

    Attributes:
        Model: MACModel of the model
        Subcases: list of MACSubcase
        Parameters: list of strings with the parameters.
    """

    def __init__(self, model: MACModel, subcases: list[MACSubcase, ...], parameters: list[str, ...]):
        """
        Constructor for MACAnalysis class
        """
        self.Model = model
        self.Subcases = subcases
        self.Parameters = parameters

    @property
    def Loads(self) -> list[MACForce | MACSpc, ...]:
        loads = []
        for subcase in self.Subcases:
            for load in subcase.Load:
                if load not in loads:
                    loads.append(load)

        return loads

    @property
    def Spcs(self) -> list[MACSpc, ...]:
        spcs = []
        for subcase in self.Subcases:
            for spc in subcase.Spc:
                if spc not in spcs:
                    spcs.append(spc)
        return spcs

    @property
    def Eigrs(self) -> list[MACEigrl, ...]:
        eigrs = []
        for subcase in self.Subcases:
            if subcase.Eigr is not None and subcase.Eigr not in eigrs:
                eigrs.append(subcase.Eigr)
        return eigrs

    def write_fem(self, pathfem: str) -> None:
        """
        Writes the .fem file for the analysis in the specified path. It overwrites the file if it already exists.
        """

        if pathfem[-4:] != ".fem":
            pathfem += ".fem"

        if path.exists(pathfem):
            remove(pathfem)
            print(f"File {pathfem} already exists. It has been overwritten.")

        today = datetime.now().strftime("%d/%m/%Y - %H:%M:%S")
        analysis_name = pathfem.split("\\")[-1].split(".")[0]
        macverlen = 78 - (len(MAC_VERSION) + len("$ MAC version: "))
        analysis_namelen = 78 - (len(analysis_name) + len("$ Analysis Name: "))

        header = "$" * 82 + "\n" + \
                 "$" * 14 + "  File generated by Metamaterial Analysis Code (MAC)  " + "$" * 14 + "\n" + \
                 "$" * 82 + "\n" + \
                 "$$" + " " * 78 + "$$" + "\n" + \
                 "$$  Escuela Tecnica Superior de Ingenieria Aeronautica" + " " * 26 + "$$" + "\n" + \
                 "$$" + " " * 78 + "$$" + "\n" + \
                 f"$$  MAC version: {MAC_VERSION}" + " " * macverlen + "$$" + "\n" + \
                 "$$" + " " * 78 + "$$" + "\n" + \
                 f"$$  Date: {today}" + " " * 49 + "$$" "\n" + \
                 "$$" + " " * 78 + "$$" + "\n" + \
                 f"$$  Analysis Name: {analysis_name}" + " " * analysis_namelen + "$$" + "\n" + \
                 "$$" + " " * 78 + "$$" + "\n" + \
                 "$" * 82 + "\n"

        with open(pathfem, "a") as w:
            w.writelines(header)
            w.writelines("\n$$" + "-"*78 + "$$\n" +
                         "$$                       Case Control Cards                                     $$\n" +
                         "$$" + "-"*78 + "$$\n\n")
            for subcase in self.Subcases:
                w.writelines(str(subcase))
                w.writelines("\n")
            if self.Parameters is not None:
                for parameter in self.Parameters:
                    w.writelines(parameter)
            w.writelines("\nBEGIN BULK\n")

        # Write model calling the model method. header=False to avoid writing the header again.
        self.Model.write_fem(pathfem, writeheader=False)

        with open(pathfem, "a") as w:

            w.writelines("\n$$\n$$ Load cases\n$$\n")

            for load in self.Loads:
                w.writelines(str(load))
            for spc in self.Spcs:
                w.writelines(str(spc))
            for eigr in self.Eigrs:
                if eigr is not None:
                    w.writelines("\n" + str(eigr))
            for subcase in self.Subcases:
                if subcase.NLaprmLD is not None:
                    w.writelines("\n" + str(subcase.NLaprmLD))
            for subcase in self.Subcases:
                if subcase.NLout is not None:
                    w.writelines("\n" + str(subcase.NLout))

            w.writelines("$$\n")
            w.writelines("\n\nENDDATA\n")


def set_analysis(model: MACModel, subcases: list, parameters: list = None) -> MACAnalysis:
    """
    Function to set the analysis. It returns a MACAnalysis object.
    """
    analysis = MACAnalysis(model, subcases, parameters)

    return analysis
