/* BdfServer_HtmlProducers - Copyright (c) 2012-2025 Vincent Calame - Exemole
 * Logiciel libre donné sous triple licence :
 * 1) selon les termes de la CeCILL V2
 * 2) selon les termes de l’EUPL V.1.1
 * 3) selon les termes de la GNU GPLv3
 * Voir le fichier licences.txt
 */


package fr.exemole.bdfserver.htmlproducers.thesaurus;

import fr.exemole.bdfserver.api.instruction.BdfParameters;
import fr.exemole.bdfserver.api.interaction.Domains;
import fr.exemole.bdfserver.api.interaction.InteractionConstants;
import fr.exemole.bdfserver.api.interaction.domains.EditionDomain;
import fr.exemole.bdfserver.api.interaction.domains.ThesaurusDomain;
import fr.exemole.bdfserver.commands.selection.UserSelectionByMotcleCommand;
import fr.exemole.bdfserver.commands.thesaurus.MotcleRemoveCommand;
import fr.exemole.bdfserver.html.BdfServerHtmlProducer;
import fr.exemole.bdfserver.html.consumers.PageUnit;
import fr.exemole.bdfserver.html.consumers.Tree;
import fr.exemole.bdfserver.html.jslib.BdfJsLibs;
import fr.exemole.bdfserver.htmlproducers.main.MainHtmlUtils;
import fr.exemole.bdfserver.tools.BH;
import fr.exemole.bdfserver.tools.BdfServerUtils;
import fr.exemole.bdfserver.tools.instruction.BdfInstructionUtils;
import java.util.ArrayList;
import java.util.List;
import net.fichotheque.corpus.Corpus;
import net.fichotheque.corpus.FicheMeta;
import net.fichotheque.thesaurus.Motcle;
import net.fichotheque.thesaurus.Thesaurus;
import net.fichotheque.thesaurus.metadata.ThesaurusMetadata;
import net.fichotheque.utils.CorpusMetadataUtils;
import net.fichotheque.utils.FichothequeUtils;
import net.mapeadores.util.html.CommandBox;
import net.mapeadores.util.html.HA;
import net.mapeadores.util.html.HtmlConstants;
import net.mapeadores.util.localisation.Lang;


/**
 *
 * @author Vincent Calame
 */
public class MotcleChangeFormHtmlProducer extends BdfServerHtmlProducer {

    private final Thesaurus thesaurus;
    private final Motcle motcle;
    private final boolean withFontAwesome;

    public MotcleChangeFormHtmlProducer(BdfParameters bdfParameters, Motcle motcle) {
        super(bdfParameters);
        this.thesaurus = motcle.getThesaurus();
        this.motcle = motcle;
        addJsLib(BdfJsLibs.COMMANDTEST);
        addJsLib(BdfJsLibs.COMMANDVEIL);
        addThemeCss("thesaurus.css");
        this.withFontAwesome = checkFontAwesome();
    }

    @Override
    public void printHtml() {
        ThesaurusMetadata thsmeta = thesaurus.getThesaurusMetadata();
        short thesaurusType = thsmeta.getThesaurusType();
        boolean withIdalpha = (thesaurusType == ThesaurusMetadata.IDALPHA_TYPE);
        Lang thesaurusLang = BdfServerUtils.checkLangDisponibility(bdfServer, thesaurus, workingLang);
        start();
        ThesaurusHtmlUtils.printMotcleToolBar(this, bdfServer, bdfUser, motcle, ThesaurusDomain.MOTCLE_CHANGEFORM_PAGE, thesaurusLang, withFontAwesome);
        printCommandMessageUnit();
        CommandBox commandBox = CommandBox.init()
                .action(Domains.THESAURUS)
                .family("THS")
                .veil(true)
                .page(ThesaurusDomain.MOTCLE_CHANGEFORM_PAGE);
        if (withIdalpha) {
            ThesaurusCommandBoxUtils.printIdalphaChangeBox(this, commandBox, motcle);
        }
        ThesaurusCommandBoxUtils.printParentChangeBox(this, commandBox, motcle, workingLang);
        ThesaurusCommandBoxUtils.printLabelChangeBox(this, commandBox, motcle, bdfServer);
        MotcleStats motcleStats = getStats();
        this
                .__(PageUnit.start("_ title.thesaurus.indexation"))
                .__(printIndexation(motcleStats))
                .__(PageUnit.END);
        if (motcleStats.hasSatellite()) {
            this
                    .__(PageUnit.start("_ link.global.satellites"))
                    .__(printSatellite(motcleStats))
                    .__(PageUnit.END);
        }
        ThesaurusCommandBoxUtils.printMotcleStatusBox(this, commandBox, motcle);
        if (MotcleRemoveCommand.isRemoveCandidate(bdfServer, motcle)) {
            commandBox
                    .page(InteractionConstants.MESSAGE_PAGE)
                    .errorPage(ThesaurusDomain.MOTCLE_CHANGEFORM_PAGE);
            ThesaurusCommandBoxUtils.printMotcleRemoveBox(this, commandBox, motcle, bdfUser.getWorkingLang(), bdfUser.getFormatLocale());
        }
        end();
    }

    private MotcleStats getStats() {
        MotcleStats motcleStats = new MotcleStats();
        for (Corpus corpus : fichotheque.getCorpusList()) {
            if (FichothequeUtils.isParentageCorpus(corpus, thesaurus)) {
                FicheMeta ficheMeta = (FicheMeta) corpus.getFicheMetaById(motcle.getId());
                if (ficheMeta != null) {
                    motcleStats.addSatellite(ficheMeta);
                }
            }
            motcleStats.addFicheCount(motcle.getCroisements(corpus).getEntryList().size());
        }
        return motcleStats;
    }

    private boolean printLabel(int ficheCount) {
        if (ficheCount == 1) {
            this
                    .__localize("_ info.thesaurus.indexation_one");
        } else {
            this
                    .__localize("_ info.thesaurus.indexation_many", ficheCount);
        }
        return true;
    }

    private boolean printIndexation(MotcleStats motcleStats) {
        int ficheCount = motcleStats.getFicheCount();
        if (ficheCount == 0) {
            this
                    .P("global-Warning")
                    .__localize("_ info.thesaurus.indexation_none")
                    ._P();
        } else {
            this
                    .P()
                    .__(printLabel(ficheCount))
                    .__space()
                    .SPAN("global-SmallLinks")
                    .__escape('(')
                    .A(HA.href(BH.domain(Domains.SELECTION).subsetItem(motcle).command(UserSelectionByMotcleCommand.COMMANDNAME).page(MainHtmlUtils.getMainPageName(this))).target(HtmlConstants.BLANK_TARGET))
                    .__localize("_ link.selection.bymotcle")
                    ._A()
                    .__escape(')')
                    ._SPAN()
                    ._P();
        }
        return true;
    }

    private boolean printSatellite(MotcleStats motcleStats) {
        this
                .__(Tree.TREE, () -> {
                    for (FicheMeta ficheMeta : motcleStats.getSatelliteList()) {
                        String affichageHref = BdfInstructionUtils.getFicheGetLink(ficheMeta, "html");
                        String ficheTitle = CorpusMetadataUtils.getFicheTitle(ficheMeta, workingLang, bdfUser.getFormatLocale());
                        this
                                .__(Tree.LEAF, () -> {
                                    this
                                            .__escape(ficheTitle)
                                            .__space()
                                            .SPAN("global-SmallLinks")
                                            .__escape('(')
                                            .A(HA.href(BH.domain(Domains.EDITION).page(EditionDomain.FICHE_CHANGE_PAGE).subsetItem(ficheMeta)))
                                            .__localize("_ link.edition.fichechange_short")
                                            ._A()
                                            .__dash()
                                            .A(HA.href(affichageHref))
                                            .__localize("_ link.global.display")
                                            ._A()
                                            .__escape(')')
                                            ._SPAN();
                                });
                    }
                });
        return true;
    }


    private static class MotcleStats {

        private List<FicheMeta> satelliteList;
        private int ficheCount = 0;

        private void addFicheCount(int ficheCount) {
            this.ficheCount += ficheCount;
        }

        private int getFicheCount() {
            return ficheCount;
        }

        private void addSatellite(FicheMeta ficheMeta) {
            if (satelliteList == null) {
                satelliteList = new ArrayList<FicheMeta>();
            }
            satelliteList.add(ficheMeta);
        }

        private List<FicheMeta> getSatelliteList() {
            return satelliteList;
        }

        private boolean hasSatellite() {
            return (satelliteList != null);
        }

    }

}
