/* BdfServer - Copyright (c) 2009-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.configuration.LangConfiguration;
import fr.exemole.bdfserver.api.ficheform.FicheFormParameters;
import fr.exemole.bdfserver.api.ui.FieldUi;
import fr.exemole.bdfserver.tools.L10nUtils;
import net.fichotheque.SubsetKey;
import net.fichotheque.corpus.fiche.FicheItem;
import net.fichotheque.corpus.fiche.PersonItem;
import net.fichotheque.corpus.metadata.CorpusField;
import net.fichotheque.pointeurs.FichePointeur;
import net.fichotheque.syntax.FormSyntax;
import net.mapeadores.util.attr.AttributeUtils;
import net.mapeadores.util.attr.Attributes;
import net.mapeadores.util.models.PersonCore;
import net.mapeadores.util.models.PersonCoreUtils;
import fr.exemole.bdfserver.api.ficheform.PersonnePropSubfieldsElement;


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

    private final CorpusField corpusField;
    private String label = "";
    private boolean mandatory = false;
    private PersonCore personCore = PersonCoreUtils.EMPTY_PERSONCORE;
    private boolean withNonlatin = false;
    private boolean withoutSurnameFirst = true;
    private Attributes attributes = AttributeUtils.EMPTY_ATTRIBUTES;


    private PersonnePropSubfieldElementBuilder(CorpusField corpusField) {
        this.corpusField = corpusField;
    }

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

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

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

    public PersonnePropSubfieldElementBuilder setPersonneCore(String s) {
        if (s == null) {
            throw new IllegalArgumentException("s is null");
        }
        this.personCore = PersonCoreUtils.toPersonCore(s, "", "", false);
        return this;
    }

    public PersonnePropSubfieldElementBuilder setPersonneCore(PersonCore personCore) {
        this.personCore = PersonCoreUtils.clonePersonCore(personCore);
        return this;
    }

    public PersonnePropSubfieldElementBuilder setWithNonlatin(boolean withNonlatin) {
        this.withNonlatin = withNonlatin;
        return this;
    }

    public PersonnePropSubfieldElementBuilder setWithoutSurnameFirst(boolean withoutSurnameFirst) {
        this.withoutSurnameFirst = withoutSurnameFirst;
        return this;
    }

    public PersonnePropSubfieldsElement toPersonnePropSubfieldsElement() {
        return new InternalPersonnePropSubfieldsElement(corpusField, label, mandatory, attributes, personCore, withNonlatin, withoutSurnameFirst);
    }

    public static PersonnePropSubfieldElementBuilder check(FichePointeur fichePointeur, FicheFormParameters ficheFormParameters, CorpusField corpusField, FieldUi fieldUi) {
        PersonnePropSubfieldElementBuilder builder = init(corpusField);
        LangConfiguration langConfiguration = ficheFormParameters.getBdfServer().getLangConfiguration();
        boolean withoutSurnameFirst = langConfiguration.isWithoutSurnameFirst();
        if (withoutSurnameFirst) {
            if ((ficheFormParameters.getPermissionSummary().isSubsetAdmin(fichePointeur.getSubsetKey()))) {
                withoutSurnameFirst = false;
            }
        }
        FicheItem ficheItem = (FicheItem) fichePointeur.getValue(corpusField);
        if (ficheItem != null) {
            if (ficheItem instanceof PersonItem) {
                PersonItem personItem = (PersonItem) ficheItem;
                if (personItem.getRedacteurGlobalId() != null) {
                    SubsetKey defaultSphereKey = null;
                    builder.setPersonneCore(FormSyntax.toString(personItem, ficheFormParameters.getBdfServer().getFichotheque(), defaultSphereKey));
                } else {
                    builder.setPersonneCore(personItem.getPersonCore());
                }
            } else {
                builder.setPersonneCore(FormSyntax.toString(ficheItem, ficheFormParameters.getBdfServer().getFichotheque(), null));
            }
        } else if (fieldUi.isObsolete()) {
            return null;
        }
        return builder
                .setMandatory(fieldUi.isMandatory())
                .setAttributes(fieldUi.getAttributes())
                .setLabel(L10nUtils.toLabelString(ficheFormParameters, corpusField))
                .setWithNonlatin(langConfiguration.isWithNonlatin())
                .setWithoutSurnameFirst(withoutSurnameFirst);
    }

    public static PersonnePropSubfieldElementBuilder init(CorpusField corpusField) {
        return new PersonnePropSubfieldElementBuilder(corpusField);
    }


    private static class InternalPersonnePropSubfieldsElement implements PersonnePropSubfieldsElement {

        private final CorpusField corpusField;
        private final String label;
        private final boolean mandatory;
        private final Attributes attributes;
        private final PersonCore personCore;
        private final boolean withNonlatin;
        private final boolean withoutSurnameFirst;

        public InternalPersonnePropSubfieldsElement(CorpusField corpusField, String label, boolean mandatory, Attributes attributes, PersonCore personCore, boolean withOriginal, boolean withoutSurnameFirst) {
            this.corpusField = corpusField;
            this.label = label;
            this.mandatory = mandatory;
            this.attributes = attributes;
            this.personCore = personCore;
            this.withNonlatin = withOriginal;
            this.withoutSurnameFirst = withoutSurnameFirst;
        }

        @Override
        public CorpusField getCorpusField() {
            return corpusField;
        }

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

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

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

        @Override
        public PersonCore getPersonCore() {
            return personCore;
        }

        @Override
        public boolean isWithNonlatin() {
            return withNonlatin;
        }

        @Override
        public boolean isWithoutSurnameFirst() {
            return withoutSurnameFirst;
        }

    }

}
