/* BdfServer_Html - Copyright (c) 2020-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.BdfServer;
import fr.exemole.bdfserver.api.instruction.BdfCommandResult;
import fr.exemole.bdfserver.api.instruction.BdfInstructionConstants;
import fr.exemole.bdfserver.api.users.BdfUser;
import fr.exemole.bdfserver.commands.thesaurus.SelectionIndexationCommand;
import fr.exemole.bdfserver.html.BdfServerHtmlProducer;
import fr.exemole.bdfserver.html.consumers.PageUnit;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import net.fichotheque.Fichotheque;
import net.fichotheque.corpus.Corpus;
import net.fichotheque.corpus.FicheMeta;
import net.fichotheque.corpus.Fiches;
import net.fichotheque.junction.Liaison;
import net.fichotheque.thesaurus.Motcle;
import net.fichotheque.utils.CorpusMetadataUtils;
import net.fichotheque.utils.FichothequeUtils;
import net.fichotheque.utils.JunctionUtils;
import net.mapeadores.util.html.HA;
import net.mapeadores.util.html.HtmlPrinter;


/**
 *
 * @author Vincent Calame
 */
public class SelectionIndexation implements Consumer<HtmlPrinter> {

    private final BdfServer bdfServer;
    private final BdfUser bdfUser;
    private final Motcle motcle;
    private final List<CorpusEntry> corpusEntryList = new ArrayList<CorpusEntry>();

    private SelectionIndexation(BdfServer bdfServer, BdfUser bdfUser, Motcle motcle) {
        this.bdfServer = bdfServer;
        this.bdfUser = bdfUser;
        this.motcle = motcle;
    }

    private void init(Fiches fiches, String mode) {
        Fichotheque fichotheque = bdfServer.getFichotheque();
        for (Fiches.Entry selectionEntry : fiches.getEntryList()) {
            Corpus corpus = selectionEntry.getCorpus();
            List<FicheMeta> ficheMetaList = selectionEntry.getFicheMetaList();
            Set<FicheMeta> existingSet = new HashSet<FicheMeta>();
            for (Liaison liaison : JunctionUtils.filter(fichotheque.getJunctions(motcle, corpus), mode)) {
                existingSet.add((FicheMeta) liaison.getSubsetItem());
            }
            corpusEntryList.add(new CorpusEntry(corpus, ficheMetaList, existingSet));
        }
    }


    @Override
    public void accept(HtmlPrinter hp) {
        hp
                .DIV("selectionindexation-Grid");
        for (CorpusEntry corpusEntry : corpusEntryList) {
            hp
                    .__(corpusEntry);
        }
        hp
                ._DIV();
    }

    public static SelectionIndexation build(BdfServer bdfServer, BdfUser bdfUser, Motcle motcle, Fiches fiches, String mode) {
        SelectionIndexation selectionIndexation = new SelectionIndexation(bdfServer, bdfUser, motcle);
        selectionIndexation.init(fiches, mode);
        return selectionIndexation;
    }

    public static boolean printCommandResult(BdfServerHtmlProducer bdfHtmlProducer) {
        BdfCommandResult bdfCommandResult = bdfHtmlProducer.getBdfCommandResult();
        if (bdfCommandResult != null) {
            Object obj = bdfCommandResult.getResultObject(BdfInstructionConstants.INTARRAY_OBJ);
            if ((obj != null) && (obj instanceof int[])) {
                return printMessages(bdfHtmlProducer, (int[]) obj);
            }
        }
        return bdfHtmlProducer.printCommandMessageUnit();
    }

    private static boolean printMessages(BdfServerHtmlProducer hp, int[] countArray) {
        hp.__(PageUnit.SIMPLE, () -> {
            hp
                    .__(hp.printCommandMessage());
            if (countArray[0] == 1) {
                hp
                        .P()
                        .__localize("_ info.edition.indexationadd_one")
                        ._P();
            } else if (countArray[0] > 1) {
                hp
                        .P()
                        .__localize("_ info.edition.indexationadd_many", countArray[0])
                        ._P();
            }
            if (countArray[1] == 1) {
                hp
                        .P()
                        .__localize("_ info.edition.indexationremove_one")
                        ._P();
            } else if (countArray[1] > 1) {
                hp
                        .P()
                        .__localize("_ info.edition.indexationremove_many", countArray[1])
                        ._P();
            }
        });
        return true;
    }


    private class CorpusEntry implements Consumer<HtmlPrinter> {

        private final Corpus corpus;
        private final List<FicheMeta> ficheMetaList;
        private final Set<FicheMeta> existingSet;

        private CorpusEntry(Corpus corpus, List<FicheMeta> ficheMetaList, Set<FicheMeta> existingSet) {
            this.corpus = corpus;
            this.ficheMetaList = ficheMetaList;
            this.existingSet = existingSet;
        }

        @Override
        public void accept(HtmlPrinter hp) {
            hp
                    .H2(HA.attr("data-selectionindexation-corpus", corpus.getSubsetName()).classes("selectionindexation-Corpus"))
                    .__escape(FichothequeUtils.getTitle(corpus, bdfUser.getWorkingLang()))
                    .__space()
                    .__escape('(')
                    .__escape(bdfUser.format(ficheMetaList.size()))
                    .__escape(')')
                    ._H2();
            for (FicheMeta ficheMeta : ficheMetaList) {
                printFicheMetaRow(hp, ficheMeta, existingSet.contains(ficheMeta));
            }
        }

        private boolean printFicheMetaRow(HtmlPrinter hp, FicheMeta ficheMeta, boolean ficheIndexee) {
            String corpusName = ficheMeta.getSubsetName();
            String ficheId = String.valueOf(ficheMeta.getId());
            String genId = hp.generateId();
            if (!ficheIndexee) {
                hp
                        .DIV("selectionindexation-AddCheck")
                        .INPUT_checkbox(HA.name(SelectionIndexationCommand.getAddParamName(corpusName)).id(genId).value(ficheId))
                        .__space()
                        .INPUT_text(HA.name(SelectionIndexationCommand.getWeightParamName(corpusName, ficheId)).attr("placeholder", "1").attr("data-selectionindexation-weight", genId).size("3").titleLocKey("_ label.global.weight"))
                        ._DIV();
            }
            hp
                    .DIV((ficheIndexee) ? "selectionindexation-Fiche selectionindexation-FicheIndexee" : "selectionindexation-Fiche")
                    .LABEL_for(genId)
                    .__escape(CorpusMetadataUtils.getFicheTitle(ficheMeta, bdfUser.getWorkingLang(), bdfUser.getFormatLocale()))
                    ._LABEL()
                    ._DIV();
            if (ficheIndexee) {
                hp
                        .DIV("selectionindexation-DelCheck")
                        .INPUT_checkbox(HA.name(SelectionIndexationCommand.getRemoveParamName(corpusName)).id(genId).value(ficheId))
                        ._DIV();
            }
            return true;
        }

    }

}
