/* 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.field;

import fr.exemole.bdfserver.api.ficheform.FicheFormParameters;
import fr.exemole.bdfserver.api.ui.FieldUi;
import fr.exemole.bdfserver.tools.L10nUtils;
import net.fichotheque.corpus.fiche.AmountItem;
import net.fichotheque.corpus.fiche.FicheItem;
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.money.Currencies;
import fr.exemole.bdfserver.api.ficheform.field.AmountPropEntry;


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

    private final CorpusField corpusField;
    private String label = "";
    private boolean mandatory = false;
    private String num = "";
    private String cur = "XXX";
    private boolean unique;
    private Currencies currencies;
    private Attributes attributes = AttributeUtils.EMPTY_ATTRIBUTES;

    public AmountPropEntryBuilder(CorpusField corpusField) {
        this.corpusField = corpusField;
    }

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

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

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

    public AmountPropEntryBuilder setNum(String num) {
        if (num == null) {
            throw new IllegalArgumentException("num is null");
        }
        this.num = num;
        return this;
    }

    public AmountPropEntryBuilder setCur(String cur) {
        if (cur == null) {
            throw new IllegalArgumentException("cur is null");
        }
        if (cur.length() != 3) {
            throw new IllegalArgumentException("wrong cur: " + cur);
        }
        this.cur = cur;
        return this;
    }

    public AmountPropEntryBuilder setUnique(boolean unique) {
        this.unique = unique;
        return this;
    }

    public AmountPropEntryBuilder setCurrencies(Currencies currencies) {
        this.currencies = currencies;
        return this;
    }

    public AmountPropEntry toAmountPropEntry() {
        return new InternalAmountPropEntry(corpusField, label, mandatory, attributes, num, cur, unique, currencies);
    }

    public static AmountPropEntryBuilder check(FichePointeur fichePointeur, FicheFormParameters ficheFormParameters, CorpusField corpusField, FieldUi fieldUi) {
        FicheItem ficheItem = (FicheItem) fichePointeur.getValue(corpusField);
        if ((ficheItem == null) && (fieldUi.isObsolete())) {
            return null;
        }
        return build(ficheFormParameters, corpusField, fieldUi, ficheItem);
    }

    public static AmountPropEntryBuilder build(FicheFormParameters ficheFormParameters, CorpusField corpusField, FieldUi fieldUi, FicheItem defaultFicheItem) {
        FormSyntax.Parameters syntaxParameters = ficheFormParameters.getFicheItemFormSyntaxParameters();
        Currencies currencies = corpusField.getCurrencies();
        String firstCur = currencies.get(0).getCurrencyCode();
        AmountPropEntryBuilder builder = init(corpusField)
                .setCurrencies(currencies)
                .setUnique((currencies.size() == 1));
        if (defaultFicheItem == null) {
            builder.setCur(firstCur);
        } else if (defaultFicheItem instanceof AmountItem) {
            AmountItem amountItem = (AmountItem) defaultFicheItem;
            String curcur = amountItem.getCurrency().getCurrencyCode();
            if (!curcur.equals(firstCur)) {
                builder.setUnique(false);
            }
            builder
                    .setCur(curcur)
                    .setNum(amountItem.getDecimal().toStringWithBlank(syntaxParameters.decimalChar()));
        } else {
            builder
                    .setCur(firstCur)
                    .setNum(FormSyntax.toString(defaultFicheItem, ficheFormParameters.getFichothequeQuestioner(), syntaxParameters));
        }
        return builder
                .setMandatory(fieldUi.isMandatory())
                .setAttributes(fieldUi.getAttributes())
                .setLabel(L10nUtils.toLabelString(ficheFormParameters, corpusField));
    }

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


    private static class InternalAmountPropEntry implements AmountPropEntry {

        private final CorpusField corpusField;
        private final String label;
        private final boolean mandatory;
        private final Attributes attributes;
        private final String num;
        private final String cur;
        private final boolean unique;
        private final Currencies currencies;

        private InternalAmountPropEntry(CorpusField corpusField, String label, boolean mandatory, Attributes attributes, String num, String cur, boolean unique, Currencies currencies) {
            this.corpusField = corpusField;
            this.label = label;
            this.mandatory = mandatory;
            this.attributes = attributes;
            this.num = num;
            this.cur = cur;
            this.unique = unique;
            this.currencies = currencies;
        }

        @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 String getNum() {
            return num;
        }

        @Override
        public String getCur() {
            return cur;
        }

        @Override
        public boolean isUnique() {
            return unique;
        }

        @Override
        public Currencies getCurrencies() {
            return currencies;
        }

    }

}
