package de.avatic.taricdb.helper.workbook.converters;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collection;

import de.avatic.taricdb.helper.workbook.ExcelTable;
import de.avatic.taricdb.helper.workbook.wrapper.DeclarableCodesWrapper;
import de.avatic.taricdb.helper.workbook.wrapper.NomenclatureDescEnWrapper;
import de.avatic.taricdb.helper.workbook.wrapper.NomenclatureDescFrWrapper;
import de.avatic.taricdb.helper.workbook.wrapper.NomenclatureFootnoteWrapper;
import de.avatic.taricdb.model.Nomenclature;
import de.avatic.taricdb.model.NomenclatureDesc;
import de.avatic.taricdb.service.ReferenceStorageService;

public class NomenclatureDeConverter implements ExcelTableConverter<Nomenclature> {

	private ReferenceStorageService referenceStorageService;

	public NomenclatureDeConverter(ReferenceStorageService referenceStorageService) {
		this.referenceStorageService = referenceStorageService;
	}

	@Override
	public Collection<Nomenclature> convert(ExcelTable table) {
		Collection<Nomenclature> nomenclatures = new ArrayList<>();
		Collection<DeclarableCodesWrapper> declarableCodes = referenceStorageService.getEntites(DeclarableCodesWrapper.class);
		Collection<NomenclatureFootnoteWrapper> nomenclatureFootnoteWrappers = referenceStorageService.getEntites(NomenclatureFootnoteWrapper.class);
		Collection<NomenclatureDescEnWrapper> nomenclatureDescEn = referenceStorageService.getEntites(NomenclatureDescEnWrapper.class);
		Collection<NomenclatureDescFrWrapper> nomenclatureDescFr = referenceStorageService.getEntites(NomenclatureDescFrWrapper.class);

		table.getRows().forEach((row) -> {
			if (row.index() == 0) {
				return;
			}

			String goodsCode = row.getAs("Goods code", String.class);

            if (goodsCode == null || goodsCode.isEmpty()) {
                return;
            }

			String hsCode = goodsCode.substring(0, 10);
			String suffix = goodsCode.substring(11, 13);

			Nomenclature nomenclature = nomenclatures.stream().filter(n -> n.getHscode().equals(hsCode) && n.getSuffix().equals(suffix)).findAny().orElse(null);
			NomenclatureFootnoteWrapper footnoteWrapper = nomenclatureFootnoteWrappers.stream().filter(n -> n.getHsCode().equals(hsCode) && n.getSuffix().equals(suffix)).findFirst().orElse(null);
			NomenclatureDesc descEn = nomenclatureDescEn.stream().filter(n -> n.getHscode().equals(hsCode) && n.getSuffix().equals(suffix)).map(NomenclatureDescEnWrapper::getDesc).findFirst().orElse(null);
			NomenclatureDesc descFr = nomenclatureDescFr.stream().filter(n -> n.getHscode().equals(hsCode) && n.getSuffix().equals(suffix)).map(NomenclatureDescFrWrapper::getDesc).findFirst().orElse(null);
			
			
			
			if (nomenclature == null) {
				String line = row.getAs("Indent", String.class).trim();				
				int indent = line.length() - line.replace("-", "").length();
				
				DeclarableCodesWrapper declarableCode = declarableCodes.stream()
						.filter(d -> d.getHsCode().equals(hsCode)).findAny().orElse(null);

				nomenclature = new Nomenclature(hsCode, suffix, row.getAs("Hier. Pos.", Integer.class), indent,
						row.getAs("Start date", LocalDate.class), row.getAs("End date", LocalDate.class),
                        declarableCode != null && declarableCode.getIsLeaf(),
						declarableCode == null ? null : declarableCode.getDeclStartDate(),
						null, null == footnoteWrapper ? null : footnoteWrapper.getNomenclatureFootnote());
				
				nomenclatures.add(nomenclature);
			}

			nomenclature.addNomenclatureDesc(new NomenclatureDesc(row.getAs("Language", String.class), row.getAs("Description", String.class), row.getAs("Descr. start date", LocalDate.class)));
			nomenclature.addNomenclatureDesc(descEn);
			nomenclature.addNomenclatureDesc(descFr);

		});

		return nomenclatures;
	}

}
