# Copyright (c) 2026 Luigi Paone <ppc.luigi.paone@gmail.com>
# SPDX-License-Identifier: BSD-3-Clause

"""Module that generates Cheat Sheets in Markdown format.

A cheat sheet is a synthetic view of something, of objects with a lots of
properties. In this case, for example PlateMinimumAreaMdCS show input data,
calculations and output in synthetic manner.

This module mirrors latexCheatSheets.py but outputs Markdown instead of LaTeX.

Classes list:

    1. BeamMinimumAreaMdCS
    2. ConcreteMaterialMdCS
    3. PlateMinimumAreaMdCS
    4. RebarMaterialMdCS
"""

from pathlib import Path

from pycivil.EXAStructural.cheatsheets.codeEC2Rules import PlateMinimumArea
from pycivil.EXAStructural.cheatsheets.codeNTC2018Rules import (
    BeamMinimumArea,
    ConcreteMaterial,
    RebarMaterial,
)
from pycivil.EXAUtils.report import MarkdownFragment, MarkdownFragmentsBuilder


class ConcreteMaterialMdCS(MarkdownFragmentsBuilder):
    """Markdown cheat sheet builder for concrete material properties.

    Examples:

    ```
    fragBuilder = markdownCheatSheets.ConcreteMaterialMdCS(
        markdownTemplatePath=markdownTemplatePath,
        data=data
    )

    frag_title = MarkdownFragment()
    frag_title.add(line="## Concrete Material Properties")
    frag = fragBuilder.buildFragment()

    reporter = MarkdownReporter(markdownTemplatePath)
    reporter.linkFragments(ReportTemplateEnum.MD_ENG_CAL, [frag_title, frag])
    reporter.compileDocument(path=str(tmp_path), fileName="report", output_format="html")
    ```
    """

    def __init__(self, markdownTemplatePath: Path, data: ConcreteMaterial) -> None:
        super().__init__()
        self.__markdownTemplatePath = markdownTemplatePath
        self.__data = data

    def setDataModel(self, data: ConcreteMaterial) -> None:
        self.__data = data

    def buildFragment(self) -> MarkdownFragment:
        f = MarkdownFragment(self.__markdownTemplatePath)
        placeHolders = {
            "elementDescr": f"{self.__data.inputData.elementDescr:s}",
            "keyCode": f"{self.__data.inputData.keyCode:s}",
            "concreteClass": f"{self.__data.inputData.concreteClass:s}",
            "value_Rck": f"{self.__data.outputData.value_Rck:.1f}",
            "value_fck": f"{self.__data.outputData.value_fck:.1f}",
            "value_fcm": f"{self.__data.outputData.value_fcm:.2f}",
            "value_fctm": f"{self.__data.outputData.value_fctm:.2f}",
            "value_Ecm": f"{self.__data.outputData.value_Ecm:.2f}",
            "value_alphacc": f"{self.__data.outputData.value_alphacc:.2f}",
            "value_gammac": f"{self.__data.outputData.value_gammac:.2f}",
            "value_fcd": f"{self.__data.outputData.value_fcd:.2f}",
            "value_sigmaCar": f"{self.__data.outputData.value_sigmaCar:.2f}",
            "value_sigmaQp": f"{self.__data.outputData.value_sigmaQp:.2f}",
        }
        f.add(
            templateName="sheet-MatConcrete-NTC2018-ita.md",
            templatePlaceholders=placeHolders,
        )
        self._setFragment(f)
        return f


class RebarMaterialMdCS(MarkdownFragmentsBuilder):
    """Markdown cheat sheet builder for rebar steel material properties.

    Examples:

    ```
    fragBuilder = markdownCheatSheets.RebarMaterialMdCS(
        markdownTemplatePath=markdownTemplatePath,
        data=data
    )

    frag = fragBuilder.buildFragment()

    reporter = MarkdownReporter(markdownTemplatePath)
    reporter.linkFragments(ReportTemplateEnum.MD_ENG_CAL, [frag])
    reporter.compileDocument(path=str(tmp_path), fileName="report", output_format="html")
    ```
    """

    def __init__(self, markdownTemplatePath: Path, data: RebarMaterial) -> None:
        super().__init__()
        self.__markdownTemplatePath = markdownTemplatePath
        self.__data = data

    def setDataModel(self, data: RebarMaterial) -> None:
        self.__data = data

    def buildFragment(self) -> MarkdownFragment:
        f = MarkdownFragment(self.__markdownTemplatePath)
        placeHolders = {
            "elementDescr": f"{self.__data.inputData.elementDescr:s}",
            "keyCode": f"{self.__data.inputData.keyCode:s}",
            "steelClass": f"{self.__data.inputData.steelClass:s}",
            "value_fyk": f"{self.__data.outputData.value_fyk:.1f}",
            "value_ftk": f"{self.__data.outputData.value_ftk:.1f}",
            "value_gammas": f"{self.__data.outputData.value_gammas:.2f}",
            "value_Es": f"{self.__data.outputData.value_Es:.2f}",
            "value_fyd": f"{self.__data.outputData.value_fyd:.2f}",
            "value_sigmaCar": f"{self.__data.outputData.value_sigmaCar:.2f}",
        }
        f.add(
            templateName="sheet-MatRebar-NTC2018-ita.md",
            templatePlaceholders=placeHolders,
        )
        self._setFragment(f)
        return f


class PlateMinimumAreaMdCS(MarkdownFragmentsBuilder):
    """Markdown cheat sheet builder for plate minimum area per EC2.

    The class builds a fragment report starting from PlateMinimumArea class.
    The class needs a MarkdownReporter class in report module to build real
    html/md file.

    Examples:

    ```
    fragBuilder = markdownCheatSheets.PlateMinimumAreaMdCS(
        markdownTemplatePath=markdownTemplatePath,
        data=data
    )

    frag_title = MarkdownFragment()
    frag_title.add(line="## Area minima delle piastre secondo EC2")
    frag = fragBuilder.buildFragment()

    reporter = MarkdownReporter(markdownTemplatePath)
    reporter.linkFragments(ReportTemplateEnum.MD_ENG_CAL, [frag_title, frag])
    reporter.compileDocument(path=str(tmp_path), fileName="report", output_format="html")
    ```
    """

    def __init__(self, markdownTemplatePath: Path, data: PlateMinimumArea) -> None:
        super().__init__()
        self.__markdownTemplatePath = markdownTemplatePath
        self.__data = data

    def setDataModel(self, data: PlateMinimumArea) -> None:
        self.__data = data

    def buildFragment(self) -> MarkdownFragment:
        f = MarkdownFragment(self.__markdownTemplatePath)
        placeHolders = {
            "elementDescr": f"{self.__data.inputData.elementDescr:s}",
            "keyCode": f"{self.__data.inputData.keyCode:s}",
            "concreteClass": f"{self.__data.inputData.concreteClass:s}",
            "cls_fck": f"{self.__data.logsData.cls_fck:.2f}",
            "cls_fctm": f"{self.__data.logsData.cls_fctm:.2f}",
            "steelClass": f"{self.__data.inputData.steelClass:s}",
            "steel_fyk": f"{self.__data.logsData.steel_fyk:.2f}",
            "hEl": f"{self.__data.inputData.hEl:.2f}",
            "rebarD": f"{self.__data.inputData.rebarD:.2f}",
            "rebarDSec": f"{self.__data.inputData.rebarDSec:.2f}",
            "cover": f"{self.__data.inputData.cover:.2f}",
            "coverSec": f"{self.__data.inputData.coverSec:.2f}",
            "stirrupD": f"{self.__data.inputData.stirrupD:.2f}",
            "nbLegDirX": f"{self.__data.inputData.nbLegDirX:.2f}",
            "heightUtil": f"{self.__data.logsData.heightUtil:.2f}",
            "areaUtil": f"{self.__data.logsData.areaUtil:.2f}",
            "minimumRebarAreaCrit1": f"{self.__data.logsData.minimumRebarAreaCrit1:.2f}",
            "minimumRebarAreaCrit2": f"{self.__data.logsData.minimumRebarAreaCrit2:.2f}",
            "minimumRebarArea": f"{self.__data.logsData.minimumRebarArea:.2f}",
            "distMaxRebar": f"{self.__data.logsData.distMaxRebar:.2f}",
            "distMaxRebarMaxLoad": f"{self.__data.logsData.distMaxRebarMaxLoad:.2f}",
            "disposedRebarArea": f"{self.__data.logsData.disposedRebarArea:.2f}",
            "disposedRebarNumber": f"{self.__data.logsData.disposedRebarNumber:.2f}",
            "disposedRebarAreaMaxLoad": f"{self.__data.logsData.disposedRebarAreaMaxLoad:.2f}",
            "disposedRebarNumberMaxLoad": f"{self.__data.logsData.disposedRebarNumberMaxLoad:.2f}",
            "heightUtilSec": f"{self.__data.logsData.heightUtilSec:.2f}",
            "areaUtilSec": f"{self.__data.logsData.areaUtilSec:.2f}",
            "minimumRebarAreaCrit1Sec": f"{self.__data.logsData.minimumRebarAreaCrit1Sec:.2f}",
            "minimumRebarAreaCrit2Sec": f"{self.__data.logsData.minimumRebarAreaCrit2Sec:.2f}",
            "minimumRebarAreaSec": f"{self.__data.logsData.minimumRebarAreaSec:.2f}",
            "distMaxRebarSec": f"{self.__data.logsData.distMaxRebarSec:.2f}",
            "distMaxRebarMaxLoadSec": f"{self.__data.logsData.distMaxRebarMaxLoadSec:.2f}",
            "disposedRebarAreaSec": f"{self.__data.logsData.disposedRebarAreaSec:.2f}",
            "disposedRebarNumberSec": f"{self.__data.logsData.disposedRebarNumberSec:.2f}",
            "disposedRebarAreaMaxLoadSec": f"{self.__data.logsData.disposedRebarAreaMaxLoadSec:.2f}",
            "disposedRebarNumberMaxLoadSec": f"{self.__data.logsData.disposedRebarNumberMaxLoadSec:.2f}",
            "minimumRebarAreaForElementLenght": f"{self.__data.logsData.minimumRebarAreaForElementLenght:.2f}",
            "maxStepTrasv": f"{self.__data.logsData.maxStepTrasv:.2f}",
            "legsNumber": f"{self.__data.logsData.legsNumber:.2f}",
            "legsNumberTrasv": f"{self.__data.logsData.legsNumberTrasv:.2f}",
            "maxStepLongCrit1": f"{self.__data.logsData.maxStepLongCrit1:.2f}",
            "maxStepLongCrit2": f"{self.__data.logsData.maxStepLongCrit2:.2f}",
            "maxStep": f"{self.__data.logsData.maxStep:.2f}",
            "rebarAreaForElementLenght": f"{self.__data.logsData.rebarAreaForElementLenght:.2f}",
        }
        f.add(
            templateName="sheet-PlateMinimumArea-EC211-ita.md",
            templatePlaceholders=placeHolders,
        )
        self._setFragment(f)
        return f


class BeamMinimumAreaMdCS(MarkdownFragmentsBuilder):
    """Markdown cheat sheet builder for beam minimum area per NTC2018.

    Examples:

    ```
    fragBuilder = markdownCheatSheets.BeamMinimumAreaMdCS(
        markdownTemplatePath=markdownTemplatePath,
        data=data
    )

    frag = fragBuilder.buildFragment()

    reporter = MarkdownReporter(markdownTemplatePath)
    reporter.linkFragments(ReportTemplateEnum.MD_ENG_CAL, [frag])
    reporter.compileDocument(path=str(tmp_path), fileName="report", output_format="html")
    ```
    """

    def __init__(self, markdownTemplatePath: Path, data: BeamMinimumArea) -> None:
        super().__init__()
        self.__markdownTemplatePath = markdownTemplatePath
        self.__data = data

    def setDataModel(self, data: BeamMinimumArea) -> None:
        self.__data = data

    def buildFragment(self) -> MarkdownFragment:
        f = MarkdownFragment(self.__markdownTemplatePath)
        placeHolders = {
            "elementDescr": f"{self.__data.inputData.elementDescr:s}",
            "keyCode": f"{self.__data.inputData.keyCode:s}",
            "concreteClass": f"{self.__data.inputData.concreteClass:s}",
            "cls_fck": f"{self.__data.logsData.cls_fck:.2f}",
            "cls_fctm": f"{self.__data.logsData.cls_fctm:.2f}",
            "steelClass": f"{self.__data.inputData.steelClass:s}",
            "steel_fyk": f"{self.__data.logsData.steel_fyk:.2f}",
            "hEl": f"{self.__data.inputData.hEl:.2f}",
            "wEl": f"{self.__data.inputData.wEl:.2f}",
            "bt": f"{self.__data.inputData.bt:.2f}",
            "rebarD": f"{self.__data.inputData.rebarD:.2f}",
            "cover": f"{self.__data.inputData.cover:.2f}",
            "bMin": f"{self.__data.inputData.bMin:.2f}",
            "rebarDComp": f"{self.__data.inputData.rebarDComp:.2f}",
            "stirrupD": f"{self.__data.inputData.stirrupD:.2f}",
            "nbLegDirX": f"{self.__data.inputData.nbLegDirX:.2f}",
            "heightUtil": f"{self.__data.logsData.heightUtil:.2f}",
            "areaUtil": f"{self.__data.logsData.areaUtil:.2f}",
            "minimumRebarAreaCrit1": f"{self.__data.logsData.minimumRebarAreaCrit1:.2f}",
            "minimumRebarAreaCrit2": f"{self.__data.logsData.minimumRebarAreaCrit2:.2f}",
            "minimumRebarArea": f"{self.__data.logsData.minimumRebarArea:.2f}",
            "rebarAreaDisposed": f"{self.__data.logsData.rebarAreaDisposed:.2f}",
            "rebarNumber": f"{self.__data.outputData.rebarNumber:.2f}",
            "minimumRebarAreaForElementLenght": f"{self.__data.logsData.minimumRebarAreaForElementLenght:.2f}",
            "minimumLegsForElementLenght": f"{self.__data.logsData.minimumLegsForElementLenght:.2f}",
            "maxStepCrit1": f"{self.__data.logsData.maxStepCrit1:.2f}",
            "maxStepCrit2": f"{self.__data.logsData.maxStepCrit2:.2f}",
            "maxStepCrit3": f"{self.__data.logsData.maxStepCrit3:.2f}",
            "maxStepCrit4": f"{self.__data.logsData.maxStepCrit4:.2f}",
            "stirrupStepMin": f"{self.__data.outputData.stirrupStepMin:.2f}",
            "stirrupCompStepMin": f"{self.__data.outputData.stirrupCompStepMin:.2f}",
        }
        f.add(
            templateName="sheet-BeamMinimumArea-NTC2018-ita.md",
            templatePlaceholders=placeHolders,
        )
        self._setFragment(f)
        return f
