package de.avatic.lcc.service.bulk;

import de.avatic.lcc.dto.bulk.BulkFileType;
import de.avatic.lcc.model.bulk.BulkFileTypes;
import de.avatic.lcc.model.bulk.BulkOperation;
import de.avatic.lcc.model.bulk.HiddenTableType;
import de.avatic.lcc.repositories.rates.ValidityPeriodRepository;
import de.avatic.lcc.service.bulk.helper.HeaderCellStyleProvider;
import de.avatic.lcc.service.excelMapper.*;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.SheetVisibility;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

@Service
public class BulkExportService {

    private final HeaderCellStyleProvider headerCellStyleProvider;
    private final ContainerRateExcelMapper containerRateExcelMapper;
    private final MatrixRateExcelMapper matrixRateExcelMapper;
    private final MaterialExcelMapper materialExcelMapper;
    private final PackagingExcelMapper packagingExcelMapper;
    private final NodeExcelMapper nodeExcelMapper;
    private final HiddenNodeExcelMapper hiddenNodeExcelMapper;
    private final HiddenCountryExcelMapper hiddenCountryExcelMapper;
    private final String sheetPassword;
    private final MaterialFastExcelMapper materialFastExcelMapper;

    public BulkExportService(@Value("${lcc.bulk.sheet_password}") String sheetPassword, HeaderCellStyleProvider headerCellStyleProvider, ContainerRateExcelMapper containerRateExcelMapper, MatrixRateExcelMapper matrixRateExcelMapper, MaterialExcelMapper materialExcelMapper, PackagingExcelMapper packagingExcelMapper, NodeExcelMapper nodeExcelMapper, HiddenNodeExcelMapper hiddenNodeExcelMapper, HiddenCountryExcelMapper hiddenCountryExcelMapper, MaterialFastExcelMapper materialFastExcelMapper) {
        this.headerCellStyleProvider = headerCellStyleProvider;
        this.containerRateExcelMapper = containerRateExcelMapper;
        this.matrixRateExcelMapper = matrixRateExcelMapper;
        this.materialExcelMapper = materialExcelMapper;
        this.packagingExcelMapper = packagingExcelMapper;
        this.nodeExcelMapper = nodeExcelMapper;
        this.hiddenNodeExcelMapper = hiddenNodeExcelMapper;
        this.hiddenCountryExcelMapper = hiddenCountryExcelMapper;
        this.sheetPassword = sheetPassword;
        this.materialFastExcelMapper = materialFastExcelMapper;
    }

    public void processOperation(BulkOperation op) throws IOException {
        var bulkFileType = op.getFileType();

        // Use FastExcel for MATERIAL, Apache POI for others
        if (bulkFileType.equals(BulkFileType.MATERIAL)) {
            byte[] excelData = materialFastExcelMapper.exportToExcel();
            op.setFile(excelData);
        } else {
            processOperationWithApachePOI(op);
        }
    }



    public void processOperationWithApachePOI(BulkOperation op) throws IOException {

        var bulkFileType = op.getFileType();
        var periodId = op.getValidityPeriodId();
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        Workbook workbook = new XSSFWorkbook();
        Sheet worksheet = workbook.createSheet(BulkFileTypes.valueOf(bulkFileType.name()).getSheetName());

        CellStyle style = headerCellStyleProvider.createHeaderCellStyle(workbook);


        if (bulkFileType.equals(BulkFileType.COUNTRY_MATRIX) || bulkFileType.equals(BulkFileType.NODE)) {
            var hiddenCountrySheet = workbook.createSheet(HiddenTableType.COUNTRY_HIDDEN_TABLE.getSheetName());
            hiddenCountryExcelMapper.fillSheet(hiddenCountrySheet, style);
            hiddenCountrySheet.protectSheet(sheetPassword);
            workbook.setSheetVisibility(workbook.getSheetIndex(hiddenCountrySheet), SheetVisibility.HIDDEN);
        } else if (bulkFileType.equals(BulkFileType.CONTAINER_RATE) || bulkFileType.equals(BulkFileType.PACKAGING)) {
            var hiddenNodeSheet = workbook.createSheet(HiddenTableType.NODE_HIDDEN_TABLE.getSheetName());
            hiddenNodeExcelMapper.fillSheet(hiddenNodeSheet, style, BulkFileType.PACKAGING.equals(bulkFileType));
            hiddenNodeSheet.protectSheet(sheetPassword);
            workbook.setSheetVisibility(workbook.getSheetIndex(hiddenNodeSheet), SheetVisibility.HIDDEN);
        }

        // Create headers based on the bulk file type
        switch (bulkFileType) {
            case CONTAINER_RATE:
                containerRateExcelMapper.fillSheet(worksheet, style, periodId);
                containerRateExcelMapper.createConstraints(workbook, worksheet);
                break;
            case COUNTRY_MATRIX:
                matrixRateExcelMapper.fillSheet(worksheet, style, periodId);
                matrixRateExcelMapper.createConstraints(workbook, worksheet);
                break;
//            case MATERIAL:
//                materialExcelMapper.fillSheet(worksheet, style);
//                materialExcelMapper.createConstraints(worksheet);
//                break;
            case PACKAGING:
                packagingExcelMapper.fillSheet(worksheet, style);
                packagingExcelMapper.createConstraints(workbook, worksheet);
                break;
            case NODE:
                nodeExcelMapper.fillSheet(worksheet, style);
                nodeExcelMapper.createConstraints(workbook, worksheet);
                break;
        }

        // Return the Excel file as an InputStreamSource
        workbook.write(outputStream);
        op.setFile(outputStream.toByteArray());

    }
}
