/* FichothequeLib_Tools - Copyright (c) 2013-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 net.fichotheque.tools.format.tokenizers.subfield;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import net.fichotheque.corpus.SubfieldValue;
import net.fichotheque.corpus.fiche.AmountItem;
import net.fichotheque.corpus.fiche.FicheItem;
import net.fichotheque.corpus.fiche.FicheItems;
import net.fichotheque.corpus.metadata.AmountSubfieldKey;
import net.fichotheque.corpus.metadata.CorpusField;
import net.fichotheque.corpus.metadata.SubfieldKey;
import net.fichotheque.format.FormatSource;
import net.fichotheque.format.Tokenizer;
import net.fichotheque.format.Tokens;
import net.fichotheque.format.formatters.SubfieldFormatter;
import net.fichotheque.pointeurs.FichePointeur;
import net.fichotheque.utils.FormatterUtils;
import net.mapeadores.util.exceptions.SwitchException;
import net.mapeadores.util.money.Currencies;
import net.mapeadores.util.money.ExtendedCurrency;


/**
 *
 * @author Vincent Calame
 */
class AmountInfoTokenizer implements Tokenizer {

    private final SubfieldKey subfieldKey;
    private final SubfieldFormatter subfieldFormatter;
    private final Map<ExtendedCurrency, String> listedCurrencyMap = new LinkedHashMap<ExtendedCurrency, String>();

    AmountInfoTokenizer(CorpusField corpusField, SubfieldKey subfieldKey, SubfieldFormatter subfieldFormatter) {
        this.subfieldKey = subfieldKey;
        this.subfieldFormatter = subfieldFormatter;
        Currencies currencies = corpusField.getCurrencies();
        if (currencies != null) {
            int length = currencies.size();
            for (ExtendedCurrency currency : currencies) {
                listedCurrencyMap.put(currency, "");
            }
        }
    }

    @Override
    public Tokens tokenize(FormatSource formatSource) {
        FicheItems ficheItems = (FicheItems) ((FichePointeur) formatSource.getSubsetItemPointeur()).getValue(subfieldKey);
        if (ficheItems == null) {
            return FormatterUtils.EMPTY_TOKENS;
        }
        switch (subfieldKey.getSubtype()) {
            case SubfieldKey.AMOUNT_SUBTYPE:
                AmountItem amountItem = getAmount(ficheItems, ((AmountSubfieldKey) subfieldKey).getCurrency());
                if (amountItem == null) {
                    return FormatterUtils.EMPTY_TOKENS;
                }
                SubfieldValue subfieldValue = FormatterUtils.toSubfieldValue(amountItem);
                String value = subfieldFormatter.formatSubfield(subfieldValue, formatSource);
                return FormatterUtils.toTokens(value);

            case SubfieldKey.OTHERS_SUBTYPE:
                List<String> others = getOthersList(ficheItems, formatSource);
                if (others.isEmpty()) {
                    return FormatterUtils.EMPTY_TOKENS;
                } else {
                    return FormatterUtils.toTokens(others);
                }
            default:
                throw new SwitchException("subfieldType = " + subfieldKey.getSubtype());
        }
    }

    private AmountItem getAmount(FicheItems ficheItems, ExtendedCurrency currency) {
        int ficheCount = ficheItems.size();
        for (int i = 0; i < ficheCount; i++) {
            FicheItem ficheItem = ficheItems.get(i);
            if (ficheItem instanceof AmountItem) {
                ExtendedCurrency currentCur = ((AmountItem) ficheItem).getCurrency();
                if (currentCur.equals(currency)) {
                    return (AmountItem) ficheItem;
                }
            }
        }
        return null;
    }

    private List<String> getOthersList(FicheItems ficheItems, FormatSource formatSource) {
        List<String> result = new ArrayList<String>();
        int ficheCount = ficheItems.size();
        for (int i = 0; i < ficheCount; i++) {
            FicheItem ficheItem = ficheItems.get(i);
            if (ficheItem instanceof AmountItem) {
                AmountItem amountItem = (AmountItem) ficheItem;
                if (!listedCurrencyMap.containsKey(amountItem.getCurrency())) {
                    SubfieldValue subfieldValue = FormatterUtils.toSubfieldValue(ficheItem);
                    String value = subfieldFormatter.formatSubfield(subfieldValue, formatSource);
                    result.add(value);
                }
            }
        }
        return result;
    }

}
