/* 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.domains.ThesaurusDomain;
import fr.exemole.bdfserver.commands.thesaurus.MotclePonderationCommand;
import fr.exemole.bdfserver.html.BdfServerHtmlProducer;
import fr.exemole.bdfserver.html.jslib.BdfJsLibs;
import fr.exemole.bdfserver.htmlproducers.CommandBoxUtils;
import fr.exemole.bdfserver.tools.BH;
import fr.exemole.bdfserver.tools.BdfServerUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import net.fichotheque.SubsetItem;
import net.fichotheque.corpus.Corpus;
import net.fichotheque.corpus.FicheMeta;
import net.fichotheque.junction.Liaison;
import net.fichotheque.permission.PermissionSummary;
import net.fichotheque.thesaurus.Motcle;
import net.fichotheque.thesaurus.Thesaurus;
import net.fichotheque.utils.CorpusMetadataUtils;
import net.fichotheque.utils.JunctionUtils;
import net.fichotheque.utils.FichothequeUtils;
import net.mapeadores.util.html.CommandBox;
import net.mapeadores.util.html.HA;
import net.mapeadores.util.html.HtmlAttributes;
import net.mapeadores.util.localisation.Lang;


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

    private final Thesaurus thesaurus;
    private final Motcle motcle;
    private final String sortValue;
    private final PermissionSummary permissionSummary;
    private final boolean asc;
    private final boolean parCorpus;
    private final String mode = "";
    private final boolean withFontAwesome;

    public MotclePonderationFormHtmlProducer(BdfParameters bdfParameters, Motcle motcle, String sortValue) {
        super(bdfParameters);
        this.thesaurus = motcle.getThesaurus();
        this.motcle = motcle;
        this.permissionSummary = bdfParameters.getPermissionSummary();
        this.sortValue = sortValue;
        asc = (sortValue.equals(ThesaurusDomain.CORPUSASC_TRI_PARAMVALUE)) || (sortValue.equals(ThesaurusDomain.ASC_TRI_PARAMVALUE));
        parCorpus = (sortValue.equals(ThesaurusDomain.CORPUSASC_TRI_PARAMVALUE)) || (sortValue.equals(ThesaurusDomain.CORPUSDESC_TRI_PARAMVALUE));
        addJsLib(BdfJsLibs.COMMANDVEIL);
        addThemeCss("thesaurus.css");
        this.withFontAwesome = checkFontAwesome();
    }

    @Override
    public void printHtml() {
        Lang thesaurusLang = BdfServerUtils.checkLangDisponibility(bdfServer, thesaurus, workingLang);
        start();
        ThesaurusHtmlUtils.printMotcleToolBar(this, bdfServer, bdfUser, motcle, ThesaurusDomain.MOTCLE_PONDERATIONFORM_PAGE, thesaurusLang, withFontAwesome);
        printCommandMessageUnit();
        CommandBox commandBox = CommandBox.init()
                .action(Domains.THESAURUS)
                .family("THS")
                .veil(true)
                .page(ThesaurusDomain.MOTCLE_PONDERATIONFORM_PAGE)
                .name(MotclePonderationCommand.COMMANDNAME)
                .lockey(MotclePonderationCommand.COMMANDKEY)
                .__(CommandBoxUtils.insert(motcle))
                .hidden(ThesaurusDomain.SORT_PARAMNAME, sortValue)
                .submitLocKey("_ submit.thesaurus.motcleponderation");
        this
                .__start(commandBox);
        this
                .DIV("global-PageToolbar")
                .__(printTriLink(ThesaurusDomain.CORPUSASC_TRI_PARAMVALUE, "_ link.thesaurus.sort_corpusasc"))
                .__dash()
                .__(printTriLink(ThesaurusDomain.CORPUSDESC_TRI_PARAMVALUE, "_ link.thesaurus.sort_corpusdesc"))
                .__dash()
                .__(printTriLink(ThesaurusDomain.ASC_TRI_PARAMVALUE, "_ link.thesaurus.sort_asc"))
                .__dash()
                .__(printTriLink(ThesaurusDomain.DESC_TRI_PARAMVALUE, "_ link.thesaurus.sort_desc"))
                ._DIV();
        if (parCorpus) {
            printCorpusTri();
        } else {
            printAllTri();
        }
        this
                .__end(commandBox);
        end();
    }

    private boolean printTriLink(String paramValue, String messageKey) {
        if (paramValue.equals(sortValue)) {
            this
                    .SPAN("global-CurrentPage")
                    .__localize(messageKey)
                    ._SPAN();
        } else {
            this
                    .A(HA.href(BH.domain(Domains.THESAURUS).page(ThesaurusDomain.MOTCLE_PONDERATIONFORM_PAGE).subsetItem(motcle).param(ThesaurusDomain.SORT_PARAMNAME, paramValue)))
                    .__localize(messageKey)
                    ._A();
        }
        return true;
    }

    private void printCorpusTri() {
        for (Corpus corpus : fichotheque.getCorpusList()) {
            if (!permissionSummary.hasAccess(corpus)) {
                continue;
            }
            List<Liaison> liaisonList = new ArrayList<Liaison>(JunctionUtils.sortByWeight(fichotheque.getJunctions(motcle, corpus), mode));
            int length = liaisonList.size();
            if (length > 0) {
                this
                        .H2()
                        .__escape(FichothequeUtils.getTitle(corpus, workingLang))
                        ._H2();
                this
                        .TABLE();
                if (asc) {
                    for (int i = 0; i < length; i++) {
                        Liaison liaison = liaisonList.get(i);
                        FicheMeta ficheMeta = (FicheMeta) liaison.getSubsetItem();
                        printRow(ficheMeta, liaison.getTie().getWeight());
                    }
                } else {
                    for (int i = length - 1; i >= 0; i--) {
                        Liaison liaison = liaisonList.get(i);
                        FicheMeta ficheMeta = (FicheMeta) liaison.getSubsetItem();
                        printRow(ficheMeta, liaison.getTie().getWeight());
                    }
                }
                this
                        ._TABLE();
            }

        }
    }

    private void printAllTri() {
        ArrayList ponderationKeyList = new ArrayList();
        for (Corpus corpus : fichotheque.getCorpusList()) {
            if (!permissionSummary.hasAccess(corpus)) {
                continue;
            }
            Collection<Liaison> liaisons = JunctionUtils.filter(fichotheque.getJunctions(motcle, corpus), "");
            int p = 0;
            for (Liaison liaison : liaisons) {
                int weight = liaison.getTie().getWeight();
                ponderationKeyList.add(new PonderationKey(corpus, p, liaison.getSubsetItem(), weight));
                p++;
            }
        }
        Collections.sort(ponderationKeyList);
        int size = ponderationKeyList.size();
        this
                .TABLE();
        if (asc) {
            for (int i = 0; i < size; i++) {
                PonderationKey ponderationKey = (PonderationKey) ponderationKeyList.get(i);
                printPonderationRow(ponderationKey);
            }
        } else {
            for (int i = size - 1; i >= 0; i--) {
                PonderationKey ponderationKey = (PonderationKey) ponderationKeyList.get(i);
                printPonderationRow(ponderationKey);
            }
        }
        this
                ._TABLE();
    }

    private void printPonderationRow(PonderationKey ponderationKey) {
        FicheMeta ficheMeta = ponderationKey.getFicheMeta();
        printRow(ficheMeta, ponderationKey.getWeight());
    }

    private boolean printRow(FicheMeta ficheMeta, int weight) {
        String value = String.valueOf(weight);
        HtmlAttributes input = name(ficheMeta.getSubsetName() + "_" + String.valueOf(ficheMeta.getId())).value(value).size("3");
        this
                .TR();
        this
                .TD()
                .INPUT_text(input)
                ._TD();
        this
                .TD()
                .LABEL_for(input.id())
                .__escape(CorpusMetadataUtils.getFicheTitle(ficheMeta, workingLang, formatLocale))
                ._LABEL()
                ._TD();
        this
                ._TR();
        return true;
    }


    private static class PonderationKey implements Comparable {

        private final int weight;
        private final Corpus corpus;
        private final SubsetItem subsetItem;
        private final int position;

        private PonderationKey(Corpus corpus, int position, SubsetItem subsetItem, int weight) {
            this.corpus = corpus;
            this.subsetItem = subsetItem;
            this.weight = weight;
            this.position = position;
        }

        private FicheMeta getFicheMeta() {
            return (FicheMeta) subsetItem;
        }

        private int getWeight() {
            return weight;
        }

        @Override
        public int compareTo(Object obj) {
            PonderationKey other = (PonderationKey) obj;
            if (this.weight < other.weight) {
                return -1;
            }
            if (this.weight > other.weight) {
                return 1;
            }
            int result = this.corpus.getSubsetKey().compareTo(other.corpus.getSubsetKey());
            if (result != 0) {
                return result;
            }
            if (this.position < other.position) {
                return -1;
            }
            if (this.position > other.position) {
                return 1;
            }
            if (this.subsetItem.getId() < other.subsetItem.getId()) {
                return -1;
            }
            if (this.subsetItem.getId() > other.subsetItem.getId()) {
                return 1;
            }
            return 0;
        }

    }

}
