package dev.fyloz.trial.colorrecipesexplorer.xlsx;

import dev.fyloz.trial.colorrecipesexplorer.config.Preferences;
import dev.fyloz.trial.colorrecipesexplorer.model.Mix;
import dev.fyloz.trial.colorrecipesexplorer.model.MixQuantity;
import dev.fyloz.trial.colorrecipesexplorer.model.Recipe;
import dev.fyloz.trial.colorrecipesexplorer.model.RecipeStep;
import dev.fyloz.trial.colorrecipesexplorer.xlsx.component.Catalog;
import dev.fyloz.trial.colorrecipesexplorer.xlsx.component.Document;
import dev.fyloz.trial.colorrecipesexplorer.xlsx.component.Sheet;
import dev.fyloz.trial.colorrecipesexplorer.xlsx.component.Table;
import dev.fyloz.trial.colorrecipesexplorer.xlsx.component.cells.DescriptionCell;
import dev.fyloz.trial.colorrecipesexplorer.xlsx.component.cells.NoteCell;
import dev.fyloz.trial.colorrecipesexplorer.xlsx.component.cells.SectionTitleCell;
import dev.fyloz.trial.colorrecipesexplorer.xlsx.component.cells.TitleCell;
import dev.fyloz.trial.colorrecipesexplorer.xlsx.util.Position;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Collection;

public class XlsxExporter {

    public byte[] generate(Recipe recipe) {
        Preferences.logger.info(String.format("Génération du XLS de la couleur %s (%s)", recipe.getName(), recipe.getId()));

        Document document = new Document(recipe.getName());
        Sheet sheet = document.getSheet();
        registerCells(recipe, sheet);

        document.buildSheet();

        byte[] output;
        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
            document.write(outputStream);
            output = outputStream.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
            return new byte[0];
        }

        return output;
    }

    private void registerCells(Recipe recipe, Sheet sheet) {
        // Header
        sheet.registerCell(new TitleCell(recipe.getName()));
        sheet.registerCell(new DescriptionCell(DescriptionCell.DescriptionCellType.NAME, "Bannière"));
        sheet.registerCell(new DescriptionCell(DescriptionCell.DescriptionCellType.VALUE_STR, recipe.getCompany().getName()));
        sheet.registerCell(new DescriptionCell(DescriptionCell.DescriptionCellType.NAME, "Description"));
        sheet.registerCell(new DescriptionCell(DescriptionCell.DescriptionCellType.VALUE_STR, recipe.getDescription()));
        sheet.registerCell(new DescriptionCell(DescriptionCell.DescriptionCellType.NAME, "Échantillon"));
        sheet.registerCell(new DescriptionCell(DescriptionCell.DescriptionCellType.VALUE_NUM, recipe.getSample()));
        sheet.registerCell(new DescriptionCell(DescriptionCell.DescriptionCellType.NAME, "Date d'approbation"));
        sheet.registerCell(new DescriptionCell(DescriptionCell.DescriptionCellType.VALUE_STR, recipe.getApprobationDate()));
        sheet.registerCell(new DescriptionCell(DescriptionCell.DescriptionCellType.NAME, "Remarque"));
        sheet.registerCell(new DescriptionCell(DescriptionCell.DescriptionCellType.VALUE_STR, recipe.getRemark()));

        // Mélanges
        Collection<Mix> recipeMixes = recipe.getMixes();
        if (recipeMixes.size() > 0) {
            sheet.registerCell(new SectionTitleCell("Recette"));

            for (Mix mix : recipeMixes) {
                Table mixTable = new Table(4, mix.getMixQuantities().size() + 1, mix.getMixType().getName());
                mixTable.setColumnName(0, "Quantité");
                mixTable.setColumnName(2, "Unités");

                int row = 0;
                for (MixQuantity mixQuantity : mix.getMixQuantities()) {
                    mixTable.setRowName(row, mixQuantity.getMaterial().getName());
                    mixTable.setContent(new Position(1, row + 1), mixQuantity.getQuantity());
                    mixTable.setContent(new Position(3, row + 1), mixQuantity.getMaterial().getMaterialType().getUsePercentages() ? "%" : "mL");

                    row++;
                }

                sheet.registerAllCells(mixTable.getCells());
            }
        }

        // Étapes
        Collection<RecipeStep> steps = recipe.getRecipeSteps();
        if (steps.size() > 0) {
            sheet.registerCell(new SectionTitleCell("Étapes"));
            Catalog stepsCatalog = new Catalog();

            for (RecipeStep step : recipe.getRecipeSteps()) stepsCatalog.addContent(step.getMessage());

            sheet.registerAllCells(stepsCatalog.getCells());
        }

        // Note
        String note = recipe.getNote();
        if (note != null) {
            sheet.registerCell(new SectionTitleCell("Note"));
            sheet.registerCell(new NoteCell(recipe.getNote()));
        }
    }

}
