/*
 * Arrebol Consultancy copyright.
 *
 * This code belongs to Arrebol Consultancy
 * its use, redistribution or modification are prohibited
 * without written authorization from Arrebol Consultancy.
 */
package com.arrebol.apc.web.beans.catalog;

import com.arrebol.apc.controller.admin.AjustarInventariosController;
import com.arrebol.apc.controller.catalog.LoanTypeController;
import com.arrebol.apc.model.catalog.MovimientosInventario;
import com.arrebol.apc.model.core.Office;
import com.arrebol.apc.model.enums.ActiveStatus;
import com.arrebol.apc.model.enums.DaysInWeekend;
import com.arrebol.apc.model.enums.GenericEnumType;
import com.arrebol.apc.model.loan.LoanType;
import com.arrebol.apc.web.beans.Datatable;
import com.arrebol.apc.web.beans.GenericBean;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.primefaces.event.ReorderEvent;
import org.primefaces.event.RowEditEvent;

/**
 *
 * @author Oscar Armando Vargas Cardenas <oscar.vargas@arrebol.com.mx>
 */
@Named("loanTypeManager")
@ViewScoped
public class LoanTypeBean extends GenericBean implements Serializable, Datatable {

   public List<LoanType> fillDatatableLoanType() {

      return loanTypeCtrl.fillLoanTypeDatatable(getLoggedUser().getOffice().getId());
   }

   @Override
   public void editRow(RowEditEvent event) {
      LoanType loanType = (LoanType) event.getObject();
      if (loanType != null) {
         loanTypeCtrl.updateByLoanTypeId(loanType);
         showMessage(FacesMessage.SEVERITY_INFO, "Registro Editado", "Se hizo el cambio correctamente.");
      }
   }

   @Override
   public void onRowCancel(RowEditEvent event) {
      showMessage(FacesMessage.SEVERITY_INFO, "Edición Cancelada", ((LoanType) event.getObject()).getLoanTypeName());
   }

   @Override
   public void onRowReorder(ReorderEvent event) {
      showMessage(FacesMessage.SEVERITY_INFO, "Registro Movido", "De columna: " + (event.getFromIndex() + 1) + " a columna: " + (event.getToIndex() + 1));
   }

   @Override
   public void addRow() {
      try {
         logger.debug("addRowLoanType");
         getSaveLoanType().setCreatedBy(getLoggedUser().getUser().getId());
         getSaveLoanType().setOffice(new Office(getLoggedUser().getOffice().getId()));
         BigDecimal total = getSaveLoanType().getPaymentDaily().multiply(new BigDecimal(getSaveLoanType().getTotalDays()));
         getSaveLoanType().setPaymentTotal(total);

         if (isMonday() == true) {
            getSaveLoanType().setMonday(DaysInWeekend.MONDAY);
         } else {
            getSaveLoanType().setMonday(null);
         }

         if (isTuesday() == true) {
            getSaveLoanType().setTuesday(DaysInWeekend.TUESDAY);
         } else {
            getSaveLoanType().setTuesday(null);
         }

         if (isWednesday() == true) {
            getSaveLoanType().setWednesday(DaysInWeekend.WEDNESDAY);
         } else {
            getSaveLoanType().setWednesday(null);
         }

         if (isThrusday() == true) {
            getSaveLoanType().setThursday(DaysInWeekend.THURSDAY);
         } else {
            getSaveLoanType().setThursday(null);
         }

         if (isFriday() == true) {
            getSaveLoanType().setFriday(DaysInWeekend.FRIDAY);
         } else {
            getSaveLoanType().setFriday(null);
         }

         if (isSaturday() == true) {
            getSaveLoanType().setSaturday(DaysInWeekend.SATURDAY);
         } else {
            getSaveLoanType().setSaturday(null);
         }

         if (isSunday() == true) {
            getSaveLoanType().setSunday(DaysInWeekend.SUNDAY);
         } else {
            getSaveLoanType().setSunday(null);
         }

         getSaveLoanType().setConvenio(ActiveStatus.DISABLED);

         String messafeFormat = getBundlePropertyFile().getString("message.format.failure");
         FacesMessage.Severity severity = FacesMessage.SEVERITY_WARN;

         if (getLoanTypeCtrl().saveLoanType(getSaveLoanType())) {
            setSaveLoanType(new LoanType());
            messafeFormat = getBundlePropertyFile().getString("message.format.sucess");
            severity = FacesMessage.SEVERITY_INFO;
         }

         Object[] param = {getBundlePropertyFile().getString("loanType"), getBundlePropertyFile().getString("created")};

         buildAndSendMessage(param, messafeFormat, severity, getBundlePropertyFile().getString("loanType"));

      } catch (Exception e) {
         logger.error("saveLoanType", e);
         Object[] param = {getBundlePropertyFile().getString("created")};

         buildAndSendMessage(
                 param,
                 getBundlePropertyFile().getString("message.format.fatal"),
                 FacesMessage.SEVERITY_FATAL,
                 getBundlePropertyFile().getString("loanType")
         );
      }
   }

   public void guardarMoviminento() {
      logger.info("guardarMoviminento()");
      try {

         if (getMovimiento().getTipo() == null) {
            showMessage(FacesMessage.SEVERITY_FATAL, "ERROR", "Debe de seleccionar el tipo de movimiento");
            return;
         }

         // Valores iniciales
         Double cantidadInicial = getSelectedLoanType().getCantidadExistente().doubleValue();
         Double cantidadMovimiento = getMovimiento().getCantidadMovimiento().doubleValue();
         Double cantidadNueva = 0.0;

         // Lógica según el tipo de movimiento
         switch (getMovimiento().getTipo().toString()) {
            case "ENTRADA":
               // Sumar al inventario existente
               cantidadNueva = cantidadInicial + cantidadMovimiento;
               break;
            case "SALIDA":
               // Restar del inventario existente
               if (cantidadMovimiento <= cantidadInicial) {
                  cantidadNueva = cantidadInicial - cantidadMovimiento;
               } else {
                  showMessage(FacesMessage.SEVERITY_ERROR, "ERROR", "La cantidad del movimiento excede el inventario disponible");
                  throw new Exception("La cantidad del movimiento excede el inventario disponible.");
               }
               break;
            case "AJUSTE":
               // Ajustar directamente al valor de cantidadMovimiento
               cantidadNueva = cantidadMovimiento;
               break;
            default:
               showMessage(FacesMessage.SEVERITY_FATAL, "ERROR", "Tipo de movimiento no reconocido");
               logger.error("Tipo de movimiento no reconocido.");
               return;
         }

         // Configuración inicial del movimiento
         getMovimiento().setLoanType(getSelectedLoanType());
         getMovimiento().setCreatedBy(getLoggedUser().getUser().getId());
         getMovimiento().setCreatedOn(new Date());
         getMovimiento().setEstatusActivo(GenericEnumType.ENABLED);
         getMovimiento().setCantidadMovimiento(new BigDecimal(cantidadMovimiento));
         getMovimiento().setInventarioAntiguo(new BigDecimal(cantidadInicial));
         getMovimiento().setInventarioNuevo(new BigDecimal(cantidadNueva));

         // Guardar los cambios en el inventario
         getSelectedLoanType().setCantidadExistente(new BigDecimal(cantidadNueva));
         getSelectedLoanType().setLastUpdatedBy(getLoggedUser().getUser().getId());
         getSelectedLoanType().setLastUpdatedOn(new Date());
         getAjustarInventariosController().addMovimientosInventario(getMovimiento(), getLoggedUser().getUser(), true);
         getLoanTypeCtrl().updateByLoanTypeId(getSelectedLoanType());

         // Limpiar el movimiento
         limpiaMoviminento();
         showMessage(FacesMessage.SEVERITY_INFO, "Movimiento realizado", "El ajuste sé a realizado correctamente");
      } catch (Exception e) {
         logger.error("guardarMoviminento(): " + e);
         showMessage(FacesMessage.SEVERITY_ERROR, "ERROR", "Ocurrió un error al tratar de ajustar el inventario");
      }
   }

   public void limpiaMoviminento() {
      setMovimiento(new MovimientosInventario());
      loanType = fillDatatableLoanType();
   }

   @Override
   public void deleteRow() {
      throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
   }

   public LoanTypeController getLoanTypeCtrl() {
      return loanTypeCtrl;
   }

   public void setLoanTypeCtrl(LoanTypeController loanTypeCtrl) {
      this.loanTypeCtrl = loanTypeCtrl;
   }

   public List<LoanType> getLoanType() {
      return loanType;
   }

   public void setLoanType(List<LoanType> loanType) {
      this.loanType = loanType;
   }

   public LoanType getSelectedLoanType() {
      return selectedLoanType;
   }

   public void setSelectedLoanType(LoanType selectedLoanType) {
      this.selectedLoanType = selectedLoanType;
   }

   public String getId() {
      return id;
   }

   public void setId(String id) {
      this.id = id;
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }

   public LoanType getSaveLoanType() {
      return saveLoanType;
   }

   public void setSaveLoanType(LoanType saveLoanType) {
      this.saveLoanType = saveLoanType;
   }

   public boolean isMonday() {
      return monday;
   }

   public void setMonday(boolean monday) {
      this.monday = monday;
   }

   public boolean isTuesday() {
      return tuesday;
   }

   public void setTuesday(boolean tuesday) {
      this.tuesday = tuesday;
   }

   public boolean isWednesday() {
      return wednesday;
   }

   public void setWednesday(boolean wednesday) {
      this.wednesday = wednesday;
   }

   public boolean isThrusday() {
      return thrusday;
   }

   public void setThrusday(boolean thrusday) {
      this.thrusday = thrusday;
   }

   public boolean isFriday() {
      return friday;
   }

   public void setFriday(boolean friday) {
      this.friday = friday;
   }

   public boolean isSaturday() {
      return saturday;
   }

   public void setSaturday(boolean saturday) {
      this.saturday = saturday;
   }

   public boolean isSunday() {
      return sunday;
   }

   public void setSunday(boolean sunday) {
      this.sunday = sunday;
   }

   public boolean isConvenio() {
      return convenio;
   }

   public void setConvenio(boolean convenio) {
      this.convenio = convenio;
   }

   public MovimientosInventario getMovimiento() {
      return movimiento;
   }

   public void setMovimiento(MovimientosInventario movimiento) {
      this.movimiento = movimiento;
   }

   public AjustarInventariosController getAjustarInventariosController() {
      return ajustarInventariosController;
   }

   public void setAjustarInventariosController(AjustarInventariosController ajustarInventariosController) {
      this.ajustarInventariosController = ajustarInventariosController;
   }

   private LoanTypeController loanTypeCtrl;
   private List<LoanType> loanType;
   private LoanType selectedLoanType;
   private LoanType saveLoanType;
   private String id;
   private String name;

   final Logger logger = LogManager.getLogger(LoanTypeBean.class);

   boolean monday;
   boolean tuesday;
   boolean wednesday;
   boolean thrusday;
   boolean friday;
   boolean saturday;
   boolean sunday;
   boolean convenio;

   private MovimientosInventario movimiento;
   private AjustarInventariosController ajustarInventariosController;

   @PostConstruct
   public void init() {
      loadBundlePropertyFile();
      loanTypeCtrl = new LoanTypeController();
      setSaveLoanType(new LoanType());
      setAjustarInventariosController(new AjustarInventariosController());
      loanType = fillDatatableLoanType();
      monday = false;
      tuesday = false;
      wednesday = false;
      thrusday = false;
      friday = false;
      saturday = false;
      sunday = false;
      convenio = false;
   }

}
