package com.capgemini.reports.definition.r11report;

import com.capgemini.framework.common.SettingsHelper;
import com.capgemini.framework.common.TeamcenterDateFormatter;
import com.capgemini.framework.teamcenter.policies.PolicyLocation;
import com.capgemini.reports.JasperTemplate;
import com.capgemini.reports.ReportEnum;
import com.capgemini.reports.ReportLaunchTypeEnum;
import com.capgemini.reports.bomlineholder.BOMLineHolder;
import com.capgemini.reports.builder.R11Builder;
import com.capgemini.reports.builder.ReportBuilder;
import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum;
import com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue;
import com.capgemini.reports.definition.r11report.checker.R11GenericExistenceChecker;
import com.capgemini.reports.execution.AbstractExecutionReport;
import com.capgemini.reports.execution.IDataReportPreparator;
import com.capgemini.reports.printing.Printer.PrintFormat;
import com.capgemini.reports.reports.parameters.*;
import com.capgemini.reports.reports.parameters.Generics.GenericType;
import com.capgemini.reports.reports.parameters.checker.EffectivityChecker;
import com.capgemini.reports.reports.parameters.checker.ProductChecker;
import com.capgemini.reports.reports.parameters.checker.ProductUnitChecker;
import lombok.EqualsAndHashCode;
import lombok.Getter;

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

/**
 * Class which manage the execution of a R11 report.
 */
@Getter
@EqualsAndHashCode(callSuper = true)
public class ExecutionR11 extends AbstractExecutionReport<ExecutionR11, BOMLineHolder> {
    private static final long serialVersionUID = 2431051269754641192L;

    private static final String SEPARATOR = "-";
    private static final String MODEL_DATE = "dd-MM-yyyy";
    // Policies parameters
    private static final PolicyLocation R11_POLICY_XML_LIGHT = PolicyLocation.make("R11_policy_light", "/xml/policies/r11report/R11_policy_light.xml");
    private static final PolicyLocation R11_POLICY_XML_FULL = PolicyLocation.make("R11_policy_full", "/xml/policies/r11report/R11_policy_full.xml");
    // Launch type parameter
    private static final ReportLaunchTypeEnum REPORT_LAUNCH_TYPE = ReportLaunchTypeEnum.getReportLaunchType("common.launch.launchType.REPORT_R11");
    // Revision rule parameter
    private static final String REPORT_REVISION_RULE = SettingsHelper.getPropertyWithDefaultValue("common.bom.revisionRule.REPORT_R11", DEFAULT_REVISION_RULE);
    // Priority parameter
    private static final int REPORT_PRIORITY = SettingsHelper.getPriority(ReportEnum.REPORT_R11);
    private final Generics generic;
    private final MonoMulti monoMulti;
    private final EffectivityDate effectivity;

    /**
     * Constructor.
     *
     * @param generic       {@link Generics} - the generic configuration with his product unit
     * @param aMonoMulti    {@link MonoMulti} - the level of the resolution structure
     * @param anEffectivity {@link EffectivityDate} - the effectivity date
     */
    public ExecutionR11(final Generics generic, final MonoMulti aMonoMulti, final EffectivityDate anEffectivity) {
        super(REPORT_PRIORITY, REPORT_REVISION_RULE, REPORT_LAUNCH_TYPE);
        this.generic = generic;
        this.monoMulti = aMonoMulti;
        this.effectivity = anEffectivity;
    }

    @Override
    public List<IChecker> getQuickChecks() {
        List<IChecker> quickChecks = new ArrayList<>();
        ProductUnit productUnit = generic.getProductUnit();
        quickChecks.add(new ProductChecker(productUnit.getProductID()));
        quickChecks.add(new ProductUnitChecker(productUnit));
        quickChecks.add(new R11GenericExistenceChecker(generic));
        quickChecks.add(new EffectivityChecker(effectivity));
        return quickChecks;
    }

    @Override
    public PolicyLocation getPropertyPolicyForLongChecks() {
        return R11_POLICY_XML_LIGHT;
    }

    @Override
    public PolicyLocation getFullPolicy() {
        return R11_POLICY_XML_FULL;
    }

    @Override
    public List<IChecker> getLongChecks() {
        return new ArrayList<>();
    }

    @Override
    public String getTemplateLocation() {
        return JasperTemplate.TEMPLATE_R11.getFilepath();
    }

    @Override
    public ReportEnum getReportIdentifier() {
        return ReportEnum.REPORT_R11;
    }

    @Override
    public String getSpecifiedFileName() {
        String dateSystem = TeamcenterDateFormatter.formatCalendarToPattern(Calendar.getInstance(), MODEL_DATE);
        StringBuilder builder = new StringBuilder("R11-");
        if (generic.getType() == GenericType.GENERIC) {
            builder.append(generic.getID()).append(SEPARATOR);
        } else if (generic.getType() == GenericType.GENERIC_ASSEMB) {
            builder.append(generic.getID()).append(SEPARATOR);
        }
        builder.append(generic.getProductUnit().getProductID()).append(SEPARATOR);
        builder.append(generic.getProductUnit().getUnitStr()).append(SEPARATOR);
        builder.append((MonoMulti.MONO.equals(monoMulti)) ? "Mono" : "Multi").append(SEPARATOR);
        builder.append(effectivity.getDateTime() != null ? effectivity.formatAsInputCriteria() : dateSystem);
        return builder.toString();
    }

    @Override
    public PrintFormat getPrintingFormat() {
        return PrintFormat.XLSX;
    }

    @Override
    public List<CriteriaValue> getLaunchData() {
        List<CriteriaValue> theCriteria = new ArrayList<>();
        theCriteria.add(new CriteriaValue(ReportCriteriaEnum.PRODUCT, generic.getProductUnit().getProductID()));
        theCriteria.add(new CriteriaValue(ReportCriteriaEnum.UNIT, generic.getProductUnit().getUnitStr()));
        if (generic.getType() == GenericType.GENERIC) {
            theCriteria.add(new CriteriaValue(ReportCriteriaEnum.GENERIC, generic.getID()));
        }
        if (generic.getType() == GenericType.GENERIC_ASSEMB) {
            theCriteria.add(new CriteriaValue(ReportCriteriaEnum.GENERIC_ASSEMB, generic.getID()));
        }
        theCriteria.add(new CriteriaValue(ReportCriteriaEnum.MONO_MULTI, monoMulti.toString()));
        theCriteria.add(new CriteriaValue(ReportCriteriaEnum.EFFECTIVITY_DATE, effectivity.formatAsInputCriteria()));
        return theCriteria;
    }

    @Override
    public IDataReportPreparator<ExecutionR11> getDataPreparator() {
        return new DataReportPreparatorR11();
    }

    @Override
    public AbstractExecutionReport<?, ?> cloneTemplateToExecution() {
        return new ExecutionR11(generic, monoMulti, effectivity);
    }

    @Override
    public Class<? extends ReportBuilder> getReportBuilderClass() {
        return R11Builder.class;
    }
}
