/* BdfServer - Copyright (c) 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.tools.ficheform.builders;

import fr.exemole.bdfserver.api.ficheform.FicheFormParameters;
import fr.exemole.bdfserver.api.ficheform.include.LiageEntry;
import fr.exemole.bdfserver.api.ficheform.include.SubsetItemValue;
import fr.exemole.bdfserver.api.ui.IncludeUi;
import fr.exemole.bdfserver.api.ui.SpecialIncludeUi;
import fr.exemole.bdfserver.tools.L10nUtils;
import fr.exemole.bdfserver.tools.ficheform.FicheFormUtils;
import fr.exemole.bdfserver.tools.ui.UiUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import net.fichotheque.FichothequeConstants;
import net.fichotheque.corpus.FicheMeta;
import net.fichotheque.junction.Liaison;
import net.fichotheque.include.LiageTest;
import net.fichotheque.pointeurs.FichePointeur;
import net.fichotheque.utils.JunctionUtils;
import net.mapeadores.util.annotation.Nullable;
import net.mapeadores.util.attr.AttributeUtils;
import net.mapeadores.util.attr.Attributes;


/**
 *
 * @author Vincent Calame
 */
public class LiageEntryBuilder {

    private final List<SubsetItemValue> valueList = new ArrayList<SubsetItemValue>();
    private String label = "";
    private int rows = 1;
    private boolean mandatory = false;
    private Attributes attributes = AttributeUtils.EMPTY_ATTRIBUTES;

    public LiageEntryBuilder() {

    }

    public LiageEntryBuilder setLabel(String label) {
        if (label == null) {
            throw new IllegalArgumentException("label is null");
        }
        this.label = label;
        return this;
    }

    public LiageEntryBuilder setMandatory(boolean mandatory) {
        this.mandatory = mandatory;
        return this;
    }

    public LiageEntryBuilder setAttributes(Attributes attributes) {
        if (attributes == null) {
            this.attributes = AttributeUtils.EMPTY_ATTRIBUTES;
        } else {
            this.attributes = attributes;
        }
        return this;
    }

    public LiageEntryBuilder setRows(int rows) {
        this.rows = rows;
        return this;
    }

    public LiageEntryBuilder addFicheMeta(FicheMeta ficheMeta, int weight) {
        String value = ficheMeta.getGlobalId();
        if (weight > 1) {
            value = value + "<" + weight + ">";
        }
        valueList.add(FicheFormUtils.toSubsetItemValue(value, weight, ficheMeta));
        return this;
    }

    public LiageEntryBuilder populateOptions(FicheFormParameters ficheFormParameters, IncludeUi includeUi) {
        return this
                .setLabel(L10nUtils.toLabelString(ficheFormParameters, includeUi))
                .setMandatory(includeUi.isMandatory())
                .setAttributes(includeUi.getAttributes());
    }

    @Nullable
    public static LiageEntryBuilder check(FichePointeur fichePointeur, FicheFormParameters ficheFormParameters, SpecialIncludeUi includeUi) {
        if (!includeUi.getName().equals(FichothequeConstants.LIAGE_NAME)) {
            return null;
        }
        LiageEntryBuilder builder = init()
                .setRows(4);
        if (!fichePointeur.isEmpty()) {
            Collection<Liaison> liaisons = JunctionUtils.getNoList(fichePointeur, "", getLiageTest(fichePointeur, ficheFormParameters), ficheFormParameters.getPermissionSummary().getSubsetAccessPredicate(), null);
            for (Liaison liaison : liaisons) {
                builder.addFicheMeta((FicheMeta) liaison.getSubsetItem(), liaison.getTie().getWeight());
            }
        }
        if (includeUi.isObsolete()) {
            if (fichePointeur.isEmpty()) {
                return null;
            } else {
                if (builder.valueList.isEmpty()) {
                    return null;
                }
            }
        }
        return builder
                .populateOptions(ficheFormParameters, includeUi);
    }

    public LiageEntry toLiageEntry() {
        List<SubsetItemValue> finalList = FicheFormUtils.wrap(valueList.toArray(new SubsetItemValue[valueList.size()]));
        return new InternalLiageEntry(label, mandatory, attributes, finalList, rows);

    }

    public static LiageEntryBuilder init() {
        return new LiageEntryBuilder();
    }

    private static LiageTest getLiageTest(FichePointeur fichePointeur, FicheFormParameters ficheFormParameters) {
        String liageTestName = LiageTest.class.getName();
        Object obj = fichePointeur.getPointeurObject(liageTestName);
        if ((obj != null) && (obj instanceof LiageTest)) {
            return (LiageTest) obj;
        }
        LiageTest liageTest = UiUtils.checkLiageTest(ficheFormParameters.getBdfServer().getUiManager().getMainUiComponents(fichePointeur.getCorpus()));
        fichePointeur.putPointeurObject(liageTestName, liageTest);
        return liageTest;
    }


    private static class InternalLiageEntry implements LiageEntry {

        private final String label;
        private final boolean mandatory;
        private final Attributes attributes;
        private final List<SubsetItemValue> valueList;
        private final int rows;

        private InternalLiageEntry(String label, boolean mandatory, Attributes attributes, List<SubsetItemValue> valueList, int rows) {
            this.label = label;
            this.mandatory = mandatory;
            this.attributes = attributes;
            this.rows = rows;
            this.valueList = valueList;
        }

        @Override
        public String getIncludeName() {
            return FichothequeConstants.LIAGE_NAME;
        }

        @Override
        public String getLabel() {
            return label;
        }

        @Override
        public boolean isMandatory() {
            return mandatory;
        }

        @Override
        public Attributes getAttributes() {
            return attributes;
        }

        @Override
        public List<SubsetItemValue> getValueList() {
            return valueList;
        }

        @Override
        public int getRows() {
            return rows;
        }

    }

}
