package de.avatic.lcc.service.excelMapper;

import de.avatic.lcc.model.bulk.MaterialHeader;
import de.avatic.lcc.model.materials.Material;
import de.avatic.lcc.repositories.MaterialRepository;
import de.avatic.lcc.service.bulk.helper.ConstraintGenerator;
import de.avatic.lcc.service.bulk.helper.HeaderGenerator;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class MaterialExcelMapper {

    private final HeaderGenerator headerGenerator;
    private final MaterialRepository materialRepository;
    private final ConstraintGenerator constraintGenerator;

    public MaterialExcelMapper(HeaderGenerator headerGenerator, MaterialRepository materialRepository, ConstraintGenerator constraintGenerator) {
        this.headerGenerator = headerGenerator;
        this.materialRepository = materialRepository;
        this.constraintGenerator = constraintGenerator;
    }

    public void fillSheet(Sheet sheet, CellStyle headerStyle) {
        headerGenerator.generateHeader(sheet, MaterialHeader.class, headerStyle);
        materialRepository.listAllMaterials().forEach(material -> mapToRow(material, sheet.createRow(sheet.getLastRowNum()+1)));
    }

    private void mapToRow(Material material, Row row) {
        row.createCell(MaterialHeader.PART_NUMBER.ordinal()).setCellValue(material.getPartNumber());
        row.createCell(MaterialHeader.DESCRIPTION.ordinal()).setCellValue(material.getName());
        row.createCell(MaterialHeader.HS_CODE.ordinal()).setCellValue(material.getHsCode());
    }

    public void createConstraints(Sheet sheet) {
        constraintGenerator.createLengthConstraint(sheet, MaterialHeader.PART_NUMBER.ordinal(), 0, 12);
        constraintGenerator.createLengthConstraint(sheet, MaterialHeader.HS_CODE.ordinal(), 0, 8);
        constraintGenerator.createLengthConstraint(sheet, MaterialHeader.DESCRIPTION.ordinal(), 1, 500);
    }

    public List<Material> extractSheet(Sheet sheet) {
        if(!headerGenerator.validateHeader(sheet, MaterialHeader.class)) return null;

        var materials = new ArrayList<Material>();
        sheet.forEach(row -> materials.add(mapToEntity(row)));
        return materials;

    }

    private Material mapToEntity(Row row) {
        Material entity = new Material();

        entity.setPartNumber(row.getCell(MaterialHeader.PART_NUMBER.ordinal()).getStringCellValue());
        entity.setName(row.getCell(MaterialHeader.DESCRIPTION.ordinal()).getStringCellValue());
        entity.setHsCode(row.getCell(MaterialHeader.HS_CODE.ordinal()).getStringCellValue());
        entity.setNormalizedPartNumber(normalizePartNumber(entity.getPartNumber()));
        entity.setDeprecated(false);

        if(!validateHsCode(entity.getHsCode())) throw new IllegalArgumentException("Invalid HS Code");

        return entity;
    }

    private String normalizePartNumber(String partNumber) {
        if (partNumber.length() > 12) throw new IllegalArgumentException("Part number must be less than 12 characters");
        return "000000000000".concat(partNumber).substring(partNumber.length());
    }

    private boolean validateHsCode(String hsCode) {
        //TODO check via api?!
        return true;
    }

}
