package com.fp.frontend.controller.armas.solicitud;

import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;

import com.fp.dto.Request;
import com.fp.dto.Response;
import com.fp.dto.query.DtoQuery;
import com.fp.dto.query.Filter;
import com.fp.dto.save.DtoSave;
import com.fp.frontend.controller.AbstractController;
import com.fp.frontend.controller.ReportController;
import com.fp.frontend.controller.alfresco.AlfrescoController;
import com.fp.frontend.controller.armas.parametros.CentroControlArmasController;
import com.fp.frontend.controller.armas.parametros.TarmCentroControlJurController;
import com.fp.frontend.controller.pcustomer.PersonAddressController;
import com.fp.frontend.controller.pcustomer.PersonDetailController;
import com.fp.frontend.controller.pgeneral.gene.CatalogDetailController;
import com.fp.frontend.controller.pgeneral.gene.ParametersController;
import com.fp.frontend.helper.MessageHelper;
import com.fp.frontend.utility.MsgControlArmas;
import com.fp.frontend.utility.MsgGeneral;
import com.fp.persistence.parmas.param.TarmCentroControl;
import com.fp.persistence.parmas.param.TarmCentroControlJur;
import com.fp.persistence.parmas.soli.TarmDecomisoArma;
import com.fp.persistence.parmas.soli.TarmDecomisoArmaTransaccion;
import com.fp.persistence.parmas.soli.TarmTransaccionArmaBodega;
import com.fp.persistence.pcustomer.gene.TcustPersonAddress;
import com.fp.persistence.pcustomer.gene.TcustPersonDetail;
import com.fp.persistence.pgeneral.gene.TgeneCatalogDetail;
import com.fp.persistence.pgeneral.gene.TgeneParameters;
import com.fp.persistence.pgeneral.safe.TsafeUserDetail;

/**
 * Clase controladora del bean TarmDecomisoArmaTransaccion.
 *
 * @author Jorge Vaca.
 * @version 2.1
 */
@SuppressWarnings("serial")
@ManagedBean
@ViewScoped
public class RecepcionArmasNoEnviadasController extends AbstractController<TarmDecomisoArmaTransaccion> {

    public RecepcionArmasNoEnviadasController() throws Exception {
        super(TarmDecomisoArmaTransaccion.class);
    }

    /**
     * Controlador para generar el reporte
     */
    @ManagedProperty(value = "#{reportController}")
    private ReportController reportController;
    /**
     * Controlador para caragar el archivo al alfresco
     */
    @ManagedProperty(value = "#{alfrescoController}")
    private AlfrescoController alfrescoController;

    /**
     * atributo con los datos del usuario logeado
     */
    private TsafeUserDetail userDetail;

    private String xpathflujo;

    @PostConstruct
    private void postconstruct() {
        this.init();
        // Inicializa autoconsulta
        super.startQuery();
        this.querydatabase();
    }

    private List<TarmDecomisoArma> decomisoArmas;

    /**
     * Incializa el controlador, cuando se esta utilizando una pagina que utliza
     * el controlador.
     */
    private void init() {
        try {
            this.recperpage = 300; // Cambiar al # reg a mirar.
            this.lrecord = new ArrayList<>();
            this.beanalias = "RECEPCIONARMASNOENV";
            userDetail = (TsafeUserDetail) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("TSAFEUSERDETAIL");
            obtenerCentroControl();
        } catch (Exception e) {
            MessageHelper.setMessageError(e);
        }
    }

    /**
     * nombre del centro de control
     */
    private String institucionCentroControl;
    private List<SelectItem> itemUnidadDestino;
    /**
     * nombre del centro de control
     */
    private String instiCentroControlCode;

    /**
     * M&eacute;todo para obtener el centro de control
     *
     * @throws Exception
     */
    private void obtenerCentroControl() throws Exception {
        PersonAddressController personAddressController = new PersonAddressController();
        TcustPersonAddress tcustPersonAddres = personAddressController.findPrincipal(userDetail.getPk().getPersoncode().toString());
        if (tcustPersonAddres != null && tcustPersonAddres.getProvincecode() != null) {
            TarmCentroControlJur centroControlJur = TarmCentroControlJurController.findxProvincia(tcustPersonAddres.getProvincecode());
            if (centroControlJur != null && centroControlJur.getCcentrocontrol() != null) {
                TarmCentroControl centroControl = CentroControlArmasController.findPorCodigo(centroControlJur.getCcentrocontrol());
                itemUnidadDestino = new ArrayList<SelectItem>();
                institucionCentroControl = CatalogDetailController.findxCodigoCodcatalogo(centroControl.getNombreinstitucion(), centroControl.getNombreinstitucioncodigo()).getDescription();
                //codigo del centro de control de pichincha
                TgeneParameters paramCentroControlDestino = ParametersController.find("CODIGO.CENT.CONTROL.PICHINCHA", "1");//000030//CAPI
                //validamos si la persona que ingreso pertenece al centro de control pichincha para darle al opcion de seleccionar el deparatmento de control para la recepcion
                if (paramCentroControlDestino.getTextvalue().equals(centroControl.getNombreinstitucion())) {
                    itemUnidadDestino.add(new SelectItem(centroControl.getPk(), institucionCentroControl));
                    //codigo del departamento de control
                    TgeneParameters paramDepartamentoControl = ParametersController.find("CODIGO.DEPT.CONTROL", "1");//DPCA
                    TarmCentroControl institCentroControlDestino = CentroControlArmasController.findPorCentroControl(paramDepartamentoControl.getTextvalue());//000077
                    itemUnidadDestino.add(new SelectItem(institCentroControlDestino.getPk(), "" + institCentroControlDestino.getModifiedData().get("desnombreinstitucion")));
                } else {
                    instiCentroControlCode = centroControl.getPk();
                }
            } else {
                MessageHelper.setMessageError(MsgControlArmas.getProperty("msg_error_laprovinciasinccontrol"));
                return;
            }
        } else {
            MessageHelper.setMessageError(MsgControlArmas.getProperty("msg_error_notienedireccionprincipal"));
            return;
        }
    }

    public void executeUnidad() {

        for (SelectItem item : itemUnidadDestino) {
            if (item.getValue().equals(instiCentroControlCode)) {
                institucionCentroControl = item.getLabel();
            }
        }
    }

    /**
     * Crea una instancia de TgeneTransactionProcess y marca el registro como
     * nuevo.
     *
     * @throws Exception
     */
    @Override
    public void create() throws Exception {
        super.create();
    }

    @SuppressWarnings("unchecked")
    @Override
    public void querydatabase() {
        try {
            DtoQuery dto = super.getDtoQuery(true);
            dto.setOrderby("t.pk");
            Filter filtro = new Filter();
            filtro.setSql("estadoflujo='NOENV' and numerotransaccion like '%REC-%' and ccentrocontrol='" + instiCentroControlCode + "'");
            dto.addFiltro(filtro);
            HashMap<String, DtoQuery> mtables = new HashMap<String, DtoQuery>();
            mtables.put(this.beanalias, dto); // permite adicionar mas de una tabla.

            Request request = this.callerhelper.getRequest();
            request.setQueryTables(mtables);
            Response resp = this.callerhelper.executeQuery(request);

            if (resp.getResponseCode().compareTo(Response.RESPONSE_OK) != 0) {
                this.lrecord = new ArrayList<TarmDecomisoArmaTransaccion>();
                MessageHelper.setMessageError(resp);
            } else {
                this.lrecord = (List<TarmDecomisoArmaTransaccion>) resp.get(this.beanalias);
                super.postQuery(this.lrecord);
            }

        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
        }
    }

    @Override
    public void save() {
        try {
            DtoSave dtosave = super.getDtoSave();
            dtosave.setReturnpk(true); // Para que el core devuelva el pk de los registros nuevos.
            HashMap<String, DtoSave> msave = new HashMap<String, DtoSave>();

            Request request = this.callerhelper.getRequest();
            msave.put(this.beanalias, dtosave); // adicionar metadata de mantenimiento para cada tabla.

            request.setSaveTables(msave);
            Response resp = this.callerhelper.executeSave(request);
            if (resp.getResponseCode().compareTo(Response.RESPONSE_OK) == 0) {
                this.postCommit(resp);
                MessageHelper.setMessageInfo(resp);
            } else {
                MessageHelper.setMessageError(resp);
            }
        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
        }
    }

    /**
     *
     * @param codigo
     * @return
     */
    public static TarmDecomisoArmaTransaccion find(String codigo) {
        try {
            RecepcionArmasNoEnviadasController cc = new RecepcionArmasNoEnviadasController();
            cc.init();
            cc.recperpage = 300;
            cc.addFilter("pk", codigo);
            cc.querydatabase();
            if ((cc.lrecord != null) && !cc.lrecord.isEmpty()) {
                return cc.lrecord.get(0);
            }
            return null;
        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
            return null;
        }
    }

    /**
     * lista las armas decomisadas asociadas al numero de transaccion
     *
     * @param decomisoArmaTransaccion
     */
    public void listarArmas(TarmDecomisoArmaTransaccion decomisoArmaTransaccion) {
        record = decomisoArmaTransaccion;
        decomisoArmas = DecomisoArmaController.find(decomisoArmaTransaccion.getPk());
    }

    /**
     * Metodo para generar el acta de recepcion y cargar el archivo en el
     * alfresco
     */
    public void generarActa() {
        Calendar fechaActualCldr = Calendar.getInstance();
        String path = "armas/reports/repo2";
        String filename = "actaRecepciondeArmas";
        String gradoUsuario = "";
        TcustPersonDetail usuario = PersonDetailController.find(this.userDetail.getPk().getPersoncode().toString());
        TgeneCatalogDetail grado = CatalogDetailController.findxCodigoCodcatalogo(usuario.getMilitarygrade(), usuario.getMilitarygradecode());
        if (grado != null) {
            gradoUsuario = grado.getDescription() + " - " + usuario.getName();
        } else {
            gradoUsuario = "Sin Grado - " + usuario.getName();
        }

        // Fija parametros del report.
        HashMap<String, Object> parameters = new HashMap<>();
        parameters.put("pathLogoIzquierda", "repo:/maia/1/image/comandoconjunto");
        parameters.put("pathLogoDerecha", "repo:/maia/1/image/selloarmas");
        try {
            // Usuario logueado en la aplicacion
            String nombreUsuario;
            if (userDetail.getPk().getPersoncode() != null) {
                nombreUsuario = PersonDetailController.find(userDetail.getPk().getPersoncode().toString()).getName();
            } else {
                nombreUsuario = "";
            }
            TarmTransaccionArmaBodega armaBodegas = TransaccionArmaBodegaController.find(record.getPk().toString());
            parameters.put("user", nombreUsuario);
            parameters.put("unidadmilitar", armaBodegas.getModifiedData().get("nombreinstituciondest"));
            parameters.put("codigodec", record.getPk().toString());//este
            parameters.put("fechaCorte", new SimpleDateFormat("dd-MM-yyyy").format(record.getFcorte()));//este
            parameters.put("numtransaccion", record.getNumerotransaccion());
            parameters.put("personcode", userDetail.getPk().getPersoncode());
            parameters.put("nombregrado", gradoUsuario);//este
            // Fecha actual
            StringBuilder fechaActualSB = new StringBuilder();
            fechaActualSB = fechaActualSB.append((fechaActualCldr.get(Calendar.DAY_OF_MONTH)) <= 9 ? "0" + (fechaActualCldr.get(Calendar.DAY_OF_MONTH)) : (fechaActualCldr.get(Calendar.DAY_OF_MONTH)));
            fechaActualSB = fechaActualSB.append("-").append((fechaActualCldr.get(Calendar.MONTH) + 1) <= 9 ? "0" + (fechaActualCldr.get(Calendar.MONTH) + 1) : (fechaActualCldr.get(Calendar.MONTH) + 1));
            fechaActualSB = fechaActualSB.append("-").append(fechaActualCldr.get(Calendar.YEAR));
            fechaActualSB = fechaActualSB.append(" ").append(fechaActualCldr.get(Calendar.HOUR_OF_DAY));
            fechaActualSB = fechaActualSB.append(":").append((fechaActualCldr.get(Calendar.MINUTE)) <= 9 ? "0" + (fechaActualCldr.get(Calendar.MINUTE)) : (fechaActualCldr.get(Calendar.MINUTE)));
            parameters.put("lugarFecha", fechaActualSB.toString());

            parameters.put("orgControl", armaBodegas.getModifiedData().get("nombreinstitucionorig"));

            InputStream file = this.reportController.jaspertoInputstream(path, parameters, "pdf", filename, this.getLoginController());
            xpathflujo = generarXpath(record.getNumerotransaccion());
            if (!alfrescoController.uploadFile(file, record.getNumerotransaccion() + ".pdf", xpathflujo)) {
                xpathflujo = null;
            }
        } catch (Exception ex) {
            MessageHelper.setMessageError(ex);
        }
    }

    /**
     * Metodo para generar la ruta donde se carga el archivo
     *
     * @param numeroTransaccionRecepcion
     * @return
     */
    public String generarXpath(String numeroTransaccionRecepcion) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        StringBuilder ruta = new StringBuilder("cm:Decomiso");
        ruta = ruta.append("/cm:A-").append(calendar.get(Calendar.YEAR));
        ruta = ruta.append("/cm:M-").append((calendar.get(Calendar.MONTH) + 1) <= 9 ? "0" + (calendar.get(Calendar.MONTH) + 1) : (calendar.get(Calendar.MONTH) + 1));
        ruta = ruta.append("/cm:" + numeroTransaccionRecepcion);
        return ruta.toString();
    }

    public List<TarmDecomisoArma> getDecomisoArmas() {
        return decomisoArmas;
    }

    public void setDecomisoArmas(List<TarmDecomisoArma> decomisoArmas) {
        this.decomisoArmas = decomisoArmas;
    }

    public void iniciarFlujo() {
        try {

            if (xpathflujo == null) {
                MessageHelper.setMessageError(MsgControlArmas.getProperty("msg_error_generereporte"));
                return;
            }
            TarmTransaccionArmaBodega armaBodegas = TransaccionArmaBodegaController.find(record.getPk().toString());

            if (armaBodegas.getModifiedData().get("provincecodeorig") == null || armaBodegas.getModifiedData().get("provincecodeorig").toString().length() == 0) {
                MessageHelper.setMessageError(MsgControlArmas.getProperty("msg_error_sinprovincia"));
                return;
            }

            //instiCentroControlCode
            TarmCentroControl centroControl = CentroControlArmasController.findPorCodigo(instiCentroControlCode);
            String cprovincia = centroControl.getProvincecode();//armaBodegas.getModifiedData().get("provincecodeorig").toString();
            TgeneParameters paramDepartamentoControl = ParametersController.find("CODIGO.DEPT.CONTROL", "1");//DPCA
            if (armaBodegas.getModifiedData().get("nombreinstitucion").equals(paramDepartamentoControl.getTextvalue())) {
                cprovincia = paramDepartamentoControl.getTextvalue();
            }
            //itemUnidadDestino

            String xpath = xpathflujo + "/cm:" + record.getNumerotransaccion() + ".pdf";
            Request request = callerhelper.getRequest();
            super.cleanRequest(request);
            //codigo de la tabla TarmDecomisoArmaTransaccion
            request.modifiedData().put("numerotransaccion", record.getPk());
            request.modifiedData().put("cprovincia", cprovincia);
            request.modifiedData().put("numerosolicitud", record.getNumerotransaccion());
            //ruta del archivo para la firma
            //TODO Falta crear la variable en maia 2-8
            request.modifiedData().put("xpath", xpath);
            request.modifiedData().put("isnew", "Y");
            request.setLogsolicitude(record.getNumerotransaccion());
            Response resp = callerhelper.executeSave(request);
            if (resp.getResponseCode().compareTo(Response.RESPONSE_OK) == 0) {
                this.setShowRow(true);
                MessageHelper.setMessageInfo(resp, MsgGeneral.getProperty("msg_initFlow") + " TRANSACCION: " + record.getNumerotransaccion());
                xpathflujo = null;
                //quita de la lista
                lrecord.remove(record);
            } else {
                MessageHelper.setMessageError(resp);
            }
        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
        }
    }

    public ReportController getReportController() {
        return reportController;
    }

    public void setReportController(ReportController reportController) {
        this.reportController = reportController;
    }

    public AlfrescoController getAlfrescoController() {
        return alfrescoController;
    }

    public void setAlfrescoController(AlfrescoController alfrescoController) {
        this.alfrescoController = alfrescoController;
    }

    public TsafeUserDetail getUserDetail() {
        return userDetail;
    }

    public void setUserDetail(TsafeUserDetail userDetail) {
        this.userDetail = userDetail;
    }

    public String getXpathflujo() {
        return xpathflujo;
    }

    public void setXpathflujo(String xpathflujo) {
        this.xpathflujo = xpathflujo;
    }

    public String getInstitucionCentroControl() {
        return institucionCentroControl;
    }

    public void setInstitucionCentroControl(String institucionCentroControl) {
        this.institucionCentroControl = institucionCentroControl;
    }

    public List<SelectItem> getItemUnidadDestino() {
        return itemUnidadDestino;
    }

    public void setItemUnidadDestino(List<SelectItem> itemUnidadDestino) {
        this.itemUnidadDestino = itemUnidadDestino;
    }

    public String getInstiCentroControlCode() {
        return instiCentroControlCode;
    }

    public void setInstiCentroControlCode(String instiCentroControlCode) {
        this.instiCentroControlCode = instiCentroControlCode;
    }

}
