package com.ejie.ab39a.control;

import java.util.List;

import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import com.ejie.ab39a.constantes.Constantes;
import com.ejie.ab39a.constantes.TipoEntidadEnum;
import com.ejie.ab39a.exceptions.ErrorField;
import com.ejie.ab39a.exceptions.ErrorGenericoException;
import com.ejie.ab39a.model.Entidades;
import com.ejie.ab39a.model.PlanesEstrategicos;
import com.ejie.ab39a.model.PlanesGestion;
import com.ejie.ab39a.seguridad.UtilSeguridad;
import com.ejie.ab39a.service.PlanesGestionService;
import com.ejie.ab39a.validations.PlanesGestionValidator;
import com.ejie.x38.control.bind.annotation.RequestJsonBody;
import com.ejie.x38.dto.JQGridRequestDto;
import com.ejie.x38.dto.JQGridResponseDto;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * PlanesGestionController.
 * 
 *  
 */

@Controller
@RequestMapping(value = "/planesgestion")

public class PlanesGestionController {

    private static final Logger logger = LoggerFactory.getLogger(PlanesGestionController.class);

    @Autowired
    private PlanesGestionService planesGestionService;

    @Autowired
    private PlanesGestionValidator planesGestionValidator;

    /*
     * OPERACIONES CRUD (Create, Read, Update, Delete)
     * 
     */

    /**
     * Operacion CRUD Read. Devuelve el bean correspondiente al identificador indicado.
     * 
     * @param codplang
     *            Integer código del plan de gestión
     * @return PlanesGestion Objeto correspondiente al identificador indicado.
     */
    @RequestMapping(value = "/{codplang}", method = RequestMethod.GET)
    public @ResponseBody PlanesGestion get(@PathVariable Integer codplang) {
        PlanesGestion planesGestion = new PlanesGestion();
        planesGestion.setCodplang(codplang);
        planesGestion.getPlanesEstrategicos()
                .setCodTecnico(UtilSeguridad.getUsuarioConectado().getTecnicosEntidad().getCodtecnico());
        if (UtilSeguridad.getUsuarioConectado().isTecnicoEntidad()) {
            planesGestion.setUsuarioConectado(Constantes.USUARIO_TEC_ENTIDAD);
        } else {
            planesGestion.setUsuarioConectado(Constantes.USUARIO_HPS);
        }
        planesGestion = this.planesGestionService.find(planesGestion);
        PlanesGestionController.logger.info("[GET - findBy_PK] : Obtener PlanesGestion por PK");
        return planesGestion;
    }

    /**
     * Devuelve una lista de beans correspondientes a los valores de filtrados indicados en el
     * objeto pasado como parametro.
     *
     * @param filterPlanesGestion
     *            PlanesGestion Objeto que contiene los parametros de filtrado utilizados en la
     *            busqueda.
     * @return List<PlanesGestion> Lista de objetos correspondientes a la busqueda realizada.
     */
    @RequestMapping(method = RequestMethod.GET)
    public @ResponseBody List<PlanesGestion> getAll(@ModelAttribute PlanesGestion filterPlanesGestion) {
        PlanesGestionController.logger.info("[GET - find_ALL] : Obtener PlanesGestion por filtro");
        return this.planesGestionService.findAll(filterPlanesGestion, null);
    }

    /**
     * Operacion CRUD Edit. Modificacion del bean indicado.
     *
     * @param planesGestion
     *            PlanesGestion Bean que contiene la informacion a modificar.
     * @return PlanesGestion Bean resultante de la modificacion.
     */
    @RequestMapping(method = RequestMethod.PUT)
    public @ResponseBody PlanesGestion edit(@RequestBody PlanesGestion planesGestion) {
        PlanesGestion planesGestionAux = this.planesGestionService.update(planesGestion);
        PlanesGestionController.logger.info("[PUT] : PlanesGestion actualizado correctamente");
        return planesGestionAux;
    }

    /**
     * Operacion CRUD Create. Creacion de un nuevo registro a partir del bean indicado.
     *
     * @param planesGestion
     *            PlanesGestion Bean que contiene la informacion con la que se va a crear el nuevo
     *            registro.
     * @return PlanesGestion Bean resultante del proceso de creacion.
     */
    @RequestMapping(method = RequestMethod.POST)
    public @ResponseBody PlanesGestion add(@RequestBody PlanesGestion planesGestion) {

        List<ErrorField> errores = this.planesGestionValidator.validate(planesGestion);
        if (!errores.isEmpty()) {
            throw new ErrorGenericoException(errores);
        }

        PlanesGestion planesGestionAux = this.planesGestionService.add(planesGestion);
        PlanesGestionController.logger.info("[POST] : PlanesGestion insertado correctamente");
        return planesGestionAux;
    }

    /**
     * Operacion CRUD Delete. Borrado del registro correspondiente al identificador especificado.
     *
     * @param codplang
     *            Integer Identificador del objeto que se desea eliminar.
     * @return PlanesGestion Bean eliminado.
     */
    @RequestMapping(value = "/{codplang}", method = RequestMethod.DELETE)
    @ResponseStatus(value = HttpStatus.OK)
    public @ResponseBody PlanesGestion remove(@PathVariable Integer codplang) {
        PlanesGestion planesGestion = new PlanesGestion();
        planesGestion.setCodplang(codplang);
        if (planesGestion.getPlanesEstrategicos() == null) {
            planesGestion.setPlanesEstrategicos(new PlanesEstrategicos());
        }
        planesGestion.getPlanesEstrategicos()
                .setCodTecnico(UtilSeguridad.getUsuarioConectado().getTecnicosEntidad().getCodtecnico());
        this.planesGestionService.remove(planesGestion);
        PlanesGestionController.logger.info("[DELETE] : PlanesGestion borrado correctamente");
        return planesGestion;
    }

    /*
     * METODOS COMPONENTE RUP_TABLE
     * 
     */

    /**
     * Metodo de presentacion del RUP_TABLE.
     * 
     * @param model
     *            Model model que se envía
     * @param volver
     *            Integer vovler
     * @param session
     *            HttpSession session
     * @return String jsp a la que se tiene que dirigir
     * @throws JsonProcessingException
     *             excepcion que se lanza
     */
    @RequestMapping(value = "/maint", method = RequestMethod.GET)
    public String getFormEdit(Model model, HttpSession session,
            @RequestParam(value = "volver", required = false) Integer volver) throws JsonProcessingException {
        PlanesGestionController.logger.info("[GET - View] : planesgestion");
        String usuarioConectado = null;
        Integer solicInfor = null;
        Entidades entidad = UtilSeguridad.getUsuarioConectado().getEntidadPrincipal();
        if (UtilSeguridad.getUsuarioConectado().isTecnicoEntidad()) {
            usuarioConectado = Constantes.USUARIO_TEC_ENTIDAD;
            entidad = UtilSeguridad.getUsuarioConectado().getTecnicosEntidad().getEntidadPrincipal();
            Integer tipoEntidad = entidad.getTipoEntidad();
            solicInfor = entidad.getSolicInfor();
            model.addAttribute("entidad", new ObjectMapper().writeValueAsString(entidad));
            model.addAttribute("tipoEntidad", tipoEntidad);
        } else if (UtilSeguridad.getUsuarioConectado().isTecnicoHps()) {
            usuarioConectado = Constantes.USUARIO_HPS;
        }
        model.addAttribute("solicInfor", solicInfor);
        if (volver == null) {
            session.setAttribute("isVolver", 0);
            session.removeAttribute("planEst");
            model.addAttribute("planGes", new PlanesGestion());
        } else {
            session.setAttribute("isVolver", volver);
            model.addAttribute("planGes", session.getAttribute("filtroPlanG"));
        }
        // model.addAttribute("entidad", new
        // ObjectMapper().writeValueAsString(entidad));
        model.addAttribute("usuarioConectado", usuarioConectado);
        return "planesgestion";
    }

    /**
     * Operacion de filtrado del componente RUP_TABLE.
     * 
     * @param filterPlanesGestion
     *            PlanesGestion Bean que contiene los parametros de filtrado a emplear.
     * @param session
     *            HttpSession session
     * @param jqGridRequestDto
     *            Dto que contiene los parametros de configuracion propios del RUP_TABLE a aplicar
     *            en el filtrado.
     * @return JQGridResponseDto<PlanesGestion> Dto que contiene el resultado del filtrado realizado
     *         por el componente RUP_TABLE.
     */
    @RequestMapping(value = "/filter", method = RequestMethod.POST)
    public @ResponseBody JQGridResponseDto<PlanesGestion> filter(
            @RequestJsonBody(param = "filter") PlanesGestion filterPlanesGestion, HttpSession session,
            @RequestJsonBody JQGridRequestDto jqGridRequestDto) {
        String usuarioConectado = null;
        if (UtilSeguridad.getUsuarioConectado().isTecnicoEntidad()) {
            usuarioConectado = Constantes.USUARIO_TEC_ENTIDAD;
            Entidades entidad = UtilSeguridad.getUsuarioConectado().getTecnicosEntidad().getEntidadPrincipal();
            // Integer tipoEntidad = entidad.getTipoEntidad();
            // filterPlanesGestion =
            // this.incluirTipoEntidad(filterPlanesGestion, tipoEntidad);
            if (filterPlanesGestion.getPlanesEstrategicos() == null) {
                filterPlanesGestion.setPlanesEstrategicos(new PlanesEstrategicos());
            }
            filterPlanesGestion.getPlanesEstrategicos()
                    .setCodTecnico(UtilSeguridad.getUsuarioConectado().getTecnicosEntidad().getCodtecnico());
            filterPlanesGestion.getPlanesEstrategicos().setEntidad(entidad);

        } else if (UtilSeguridad.getUsuarioConectado().isTecnicoHps()) {
            usuarioConectado = Constantes.USUARIO_HPS;
        }
        filterPlanesGestion.setUsuarioConectado(usuarioConectado);
        PlanesGestionController.logger.info("[POST - filter] : Obtener PlanesGestions");

        Integer isVolver = (Integer) session.getAttribute("isVolver");
        if (isVolver == 1) {
            session.setAttribute("isVolver", 0);
        } else {
            session.setAttribute("filtroPlanG", filterPlanesGestion);
            session.setAttribute("filtrojqGridG", jqGridRequestDto);
        }

        return this.planesGestionService.filter(
                isVolver == 1 ? (PlanesGestion) session.getAttribute("filtroPlanG") : filterPlanesGestion,
                isVolver == 1 ? (JQGridRequestDto) session.getAttribute("filtrojqGridG") : jqGridRequestDto, false);

    }

    // private PlanesGestion incluirTipoEntidad(PlanesGestion planesGestion,
    // Integer tipoEntidad) {
    // if (planesGestion != null) {
    // if (planesGestion.getPlanesEstrategicos() != null) {
    // if (planesGestion.getPlanesEstrategicos().getEntidad() != null) {
    // planesGestion.getPlanesEstrategicos().getEntidad().setTipoEntidad(tipoEntidad);
    // } else {
    // planesGestion.getPlanesEstrategicos().setEntidad(new Entidades());
    // planesGestion.getPlanesEstrategicos().getEntidad().setTipoEntidad(tipoEntidad);
    // }
    // } else {
    // planesGestion.setPlanesEstrategicos(new PlanesEstrategicos());
    // planesGestion.getPlanesEstrategicos().setEntidad(new Entidades());
    // planesGestion.getPlanesEstrategicos().getEntidad().setTipoEntidad(tipoEntidad);
    // }
    // } else {
    // planesGestion = new PlanesGestion();
    // planesGestion.setPlanesEstrategicos(new PlanesEstrategicos());
    // planesGestion.getPlanesEstrategicos().setEntidad(new Entidades());
    // planesGestion.getPlanesEstrategicos().getEntidad().setTipoEntidad(tipoEntidad);
    // }
    // return planesGestion;
    // }

    /**
     * Borrado multiple de registros
     * 
     * @param filterPlanesGestion
     *            PlanesGestion Bean que contiene los parametros de filtrado a emplear.
     * @param jqGridRequestDto
     *            Dto que contiene los parametros de configuracion propios del RUP_TABLE a aplicar
     *            en la busqueda.
     * @return List<String> Lista de los identificadores de los registros eliminados.
     * 
     */
    @RequestMapping(value = "/deleteAll", method = RequestMethod.POST)
    @ResponseStatus(value = HttpStatus.OK)
    public @ResponseBody List<String> removeMultiple(
            @RequestJsonBody(param = "filter") PlanesGestion filterPlanesGestion,
            @RequestJsonBody JQGridRequestDto jqGridRequestDto) {
        PlanesGestionController.logger
                .info("[POST - search] : [POST - removeMultiple] : Eliminar multiples PlanesGestions");
        this.planesGestionService.removeMultiple(filterPlanesGestion, jqGridRequestDto, false);
        PlanesGestionController.logger.info("All entities correctly deleted!");

        return jqGridRequestDto.getMultiselection().getSelectedIds();
    }

    /**
     * copiar plan gestion
     * 
     * @param model
     *            Model model
     * @return String String
     * @throws JsonProcessingException
     *             exception e
     */
    @RequestMapping(value = "/copiarplang", method = RequestMethod.GET)
    public String copiarPlanG(Model model) throws JsonProcessingException {
        PlanesGestionController.logger.info("[GET - View] : planesgestion");

        model.addAttribute("usuarioConectado", obtenetUsuarioConectado(model));
        model.addAttribute("herri_administrazioa_id", TipoEntidadEnum.HERRI_ADMINISTRAZIOA.getId());

        return "copiarplangDialog";
    }

    /**
     * filtro copiar plan gestion
     * 
     * @param filterPlanesGestion
     *            PlanesGestion filterPlanesGestion
     * @param jqGridRequestDto
     *            JQGridRequestDto jqGridRequestDto
     * @return JQGridResponseDto<PlanesGestion> JQGridResponseDto
     */
    @RequestMapping(value = "/copiarplang/filter", method = RequestMethod.POST)
    public @ResponseBody JQGridResponseDto<PlanesGestion> filterCopiarPlanG(
            @RequestJsonBody(param = "filter") PlanesGestion filterPlanesGestion,
            @RequestJsonBody JQGridRequestDto jqGridRequestDto) {

        List<Entidades> listaEntidadesTecnico = UtilSeguridad.getUsuarioConectado().getTecnicosEntidad()
                .getEntidadeses();
        PlanesEstrategicos planesEstrategicos;
        if (filterPlanesGestion.getPlanesEstrategicos() == null) {
            planesEstrategicos = new PlanesEstrategicos();
            filterPlanesGestion.setPlanesEstrategicos(planesEstrategicos);
        }

        if (listaEntidadesTecnico != null && !listaEntidadesTecnico.isEmpty()) {
            filterPlanesGestion.getPlanesEstrategicos().setEntidades(listaEntidadesTecnico);
        }

        if (filterPlanesGestion.getPlanesEstrategicos().getEntidad() == null) {
            filterPlanesGestion.getPlanesEstrategicos().setEntidad(new Entidades());
        }
        filterPlanesGestion.getPlanesEstrategicos().getEntidad()
                .setTipoEntidad(UtilSeguridad.getUsuarioConectado().getEntidadPrincipal().getTipoEntidad());

        String usuarioConectado = "";
        if (UtilSeguridad.getUsuarioConectado().isTecnicoEntidad()) {
            usuarioConectado = Constantes.USUARIO_TEC_ENTIDAD;
            filterPlanesGestion.getPlanesEstrategicos()
                    .setCodTecnico(UtilSeguridad.getUsuarioConectado().getTecnicosEntidad().getCodtecnico());
        } else if (UtilSeguridad.getUsuarioConectado().isTecnicoHps()) {
            usuarioConectado = Constantes.USUARIO_HPS;
        }
        filterPlanesGestion.setUsuarioConectado(usuarioConectado);

        PlanesGestionController.logger.info("[POST - filter] : Obtener PlanesGestion");
        return this.planesGestionService.filterCopiar(filterPlanesGestion, jqGridRequestDto, false);
    }

    /**
     * cargar detalle plan gestion
     * 
     * @param model
     *            Model model
     * @param codplang
     *            Integer codplang
     * @return String String
     * @throws JsonProcessingException
     *             exception e
     */
    @RequestMapping(value = "/cargardetalleplang/{codplang}", method = RequestMethod.GET)
    public String cargarDetallePlanG(Model model, @PathVariable Integer codplang) throws JsonProcessingException {
        PlanesGestionController.logger.info("[GET - View] : cargarDetallePlanG");

        model.addAttribute("usuarioConectado", obtenetUsuarioConectado(model));
        model.addAttribute("herri_administrazioa_id", TipoEntidadEnum.HERRI_ADMINISTRAZIOA.getId());

        model.addAttribute("codplangestion", codplang);

        Integer solicInfor = null;
        Entidades entidad = UtilSeguridad.getUsuarioConectado().getEntidadPrincipal();
        if (UtilSeguridad.getUsuarioConectado().isTecnicoEntidad()) {
            entidad = UtilSeguridad.getUsuarioConectado().getTecnicosEntidad().getEntidadPrincipal();
            solicInfor = entidad.getSolicInfor();
        }
        model.addAttribute("solicInfor", solicInfor);

        return "copiaraltaplangDialog";
    }

    /**
     * crear copia plan gestion
     * 
     * @param planesGestion
     *            PlanesGestion planesGestion
     * @return PlanesGestion PlanesGestion
     */
    @RequestMapping(value = { "/crearcopiaplang" }, method = RequestMethod.POST)
    public @ResponseBody PlanesGestion crearCopiaPlanGestion(@RequestBody PlanesGestion planesGestion) {

        List<ErrorField> errores = this.planesGestionValidator.validate(planesGestion);
        if (!errores.isEmpty()) {
            throw new ErrorGenericoException(errores);
        }

        PlanesGestion planGestion2 = this.planesGestionService.crearCopiaPlanGestion(planesGestion);

        PlanesGestionController.logger.info("[POST - crearCopiaPlanGestion] : Crea una copia del plan de gestión");
        return planGestion2;
    }

    /**
     * Obtenber el usuario conectado
     * 
     * @param model
     *            Model model
     * @return String String
     */
    private String obtenetUsuarioConectado(Model model) throws JsonProcessingException {
        String usuarioConectado = null;
        Entidades entidad = new Entidades();
        Integer tipoEntidad = null;
        if (UtilSeguridad.getUsuarioConectado().isTecnicoEntidad()) {
            usuarioConectado = Constantes.USUARIO_TEC_ENTIDAD;
            entidad = UtilSeguridad.getUsuarioConectado().getEntidadPrincipal();
            tipoEntidad = entidad.getTipoEntidad();
            model.addAttribute("entidad", new ObjectMapper().writeValueAsString(entidad));
            model.addAttribute("tipoEntidad", tipoEntidad);
        } else if (UtilSeguridad.getUsuarioConectado().isTecnicoHps()) {
            usuarioConectado = Constantes.USUARIO_HPS;
        }

        return usuarioConectado;
    }

}
