package com.fp.general.rules.save;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import com.fp.common.helper.Constant;
import com.fp.dto.rules.TransactionRule;
import com.fp.dto.save.SaveRequest;
import com.fp.general.db.DataHelper;
import com.fp.general.exception.GeneralException;
import com.fp.persistence.pgeneral.charge.TgeneCharges;

/**
 * Clase que se encarga de verificar traslape en montos de los cargos.
 * 
 * @author Angel Merchan.
 * @version 2.1
 * 
 */
@SuppressWarnings("serial")
public class VerifyOverlapChargesAmount extends TransactionRule {

    @Override
    public SaveRequest normalProcess(SaveRequest pSaveRequest) throws Exception {
        if (pSaveRequest.getSaveBean("TGENECHARGES") != null) {
            this.validateTgeneCharges(pSaveRequest);
        }

        return pSaveRequest;
    }

    private void validateTgeneCharges(SaveRequest pSaveRequest) throws Exception {
        String modulecode = pSaveRequest.get("modulecode").toString();
        List<Object> lChargesModified = pSaveRequest.getSaveBeanModifiedRecords("TGENECHARGES");
        List<Object> lChargesDeleted = pSaveRequest.getSaveBeanDeletedRecords("TGENECHARGES");
        List<TgeneCharges> lChargesDatabase = DataHelper.getInstance().getTgeneChargesByModule(modulecode);

        List<TgeneCharges> lChargesFinal = new ArrayList<TgeneCharges>();

        lChargesFinal = Constant.getFinalList(lChargesDatabase, Constant.convertList(lChargesModified, TgeneCharges.class),
                Constant.convertList(lChargesDeleted, TgeneCharges.class));

        for (int i = 0; i < lChargesFinal.size(); i++) {
            TgeneCharges prodchargesfinal = lChargesFinal.get(i);
            this.validateOverlapCharges(prodchargesfinal, i + 1, lChargesFinal);
        }
    }

    /**
     * Metodo que verifica el traslape de montos de un cargo
     * 
     * @param prodchargesfinal
     * @param index
     * @param listSubProductChargesFinal
     * @throws Exception
     */
    private void validateOverlapCharges(TgeneCharges chargesfinal, int index, List<TgeneCharges> lChargesFinal) throws Exception {
        BigDecimal minamount = chargesfinal.getMinamount();
        BigDecimal maxamount = chargesfinal.getMaxamount();

        if (minamount.compareTo(maxamount) >= 0) {
            throw new GeneralException("GENE-0040", "EL MONTO MÍNIMO DEBE SER MENOR AL MONTO MÁXIMO EN {0}", "[CARGOS GENERALES]");
        }

        for (int i = index; i < lChargesFinal.size(); i++) {
            TgeneCharges prodcharges = lChargesFinal.get(i);

            if (chargesfinal.equalsWithoutSequence(prodcharges)) {

                BigDecimal minamountcmp = prodcharges.getMinamount();
                BigDecimal maxamountcmp = prodcharges.getMaxamount();

                if (((minamount.compareTo(maxamountcmp) <= 0) && (minamount.compareTo(minamountcmp) >= 0))
                        || ((minamount.compareTo(minamountcmp) >= 0) && (maxamount.compareTo(maxamountcmp) <= 0))
                        || ((minamount.compareTo(minamountcmp) <= 0) && (maxamount.compareTo(maxamountcmp) >= 0))
                        || ((maxamount.compareTo(minamountcmp) >= 0) && (maxamount.compareTo(maxamountcmp) <= 0))) {
                    throw new GeneralException("GENE-0041", "LOS VALORES PARA EL TIPO DE BALANCE {0} SE SOBREPONEN EN {1}", chargesfinal.getPk()
                            .getBalancetype(), "[CARGOS GENERALES]");
                }
            }
            prodcharges = null;
        }
    }

    @Override
    public SaveRequest reverseProcess(SaveRequest pSaveRequest) throws Exception {
        return pSaveRequest;
    }

}
