﻿import React, { Fragment, memo, useEffect, useState, useRef } from 'react';
import { useHistory, withRouter } from 'react-router-dom';

import { farmatearFechaEstandarHora, addDays, farmatearMontos, fechaPrimerDia, fechaUltimoDia, listaRangoNumeros, itemSelect, validarInt } from '../../../components/Util/Util.jsx';
import Config from '../../../components/Util/constantes.js';
import { SiteRutas } from '../../../request/RutasConfig.jsx';

import EstadoAsientoInt from './estadoAsientoInt.jsx';
import BotonArriba from '../../../components/UI/botonArriba/botonArriba.jsx';

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCheck, faReply, } from '@fortawesome/free-solid-svg-icons';

import { useSessionStorage } from '../../../components/Util/Hooks/useSessionStorage.jsx';
import { Notificacion } from '../../../components/Util/Notificacion/Notificacion.jsx';
import ModalSpinner from '../../../components/UI/modalSpinner/modalSpinner.jsx';
import Swal from 'sweetalert2';

import {
    TipoAsiento_Listar_Request, EncabezadoAsiento_ModificarEstado_Request, EncabezadoAsiento_Aplicar_Request
} from '../../../request/MantenimientosRequest.jsx';
import { Empresa_Consulta_Request } from "../../../request/SeguridadRequest.jsx";
import { Obtener_MenuOpciones_Lista_Request, Obtener_MenuNombre_Request } from "../../../request/MenuRequest.jsx";
import ModalSeguridad from "../../Seguridad/ModalSeguridad.jsx";
import optSeg from '../../../components/Util/seg-menu-opciones.js';
import moment from 'moment';

function EstadoAsiento(props) {

    let historyMenu = useHistory();
    const [empresa, setEmpresa] = useSessionStorage('empresaCON', 0);
    const [datosEmpresa, setDatosEmpresa] = useState(undefined);
    const [token, setToken] = useSessionStorage('tokenCON', '');
    const [usuario, setUsuario] = useSessionStorage('usuarioCON');
    const _AnnoActual = new Date().getFullYear();
    const _ListaAnnos = listaRangoNumeros(Config.anoAntiguedad, _AnnoActual);

    const [Datos, setDatos] = useState({
        EstadoAnt: { value: '', attributes: { readOnly: false, focus: false, label: 'Cambiar Estado De', hidden: 'unset' } },
        Estado: { value: '', attributes: { readOnly: true, focus: false, label: 'A', hidden: 'unset' } },
        fecMesAno: { value: addDays(new Date(), -30), attributes: { readOnly: false, focus: false, label: 'Período', hidden: 'unset', minDate: fechaPrimerDia(new Date(Config.anoAntiguedad, 0, 1)), maxDate: fechaUltimoDia(new Date(_AnnoActual, 11, 1)), ListaAnnos: _ListaAnnos, formatDate: Config.formatoMesAno } },
        Filtro: { value: '', attributes: { readOnly: false, focus: false, label: 'Filtrado Por', hidden: 'unset' } },
        TipoAsiento: { value: '', attributes: { readOnly: true, focus: false, label: 'Número', hidden: 'unset' } },
        Numero: { value: 0, attributes: { readOnly: true, focus: false, label: 'Entre', hidden: 'unset' } },
        NumeroHasta: { value: 0, attributes: { readOnly: true, focus: false, label: 'Y', hidden: 'unset' } },
        FechaInicio: { value: new Date(), attributes: { readOnly: true, label: "Desde", hidden: "unset" }, },
        FechaFinal: { value: new Date(), attributes: { readOnly: true, label: "Hasta", hidden: "unset" }, },
    });
    const [spinnerModal, setSpinnerModal] = useState(undefined);
    const [spinnerLabel, setSpinnerLabel] = useState('');
    const [spinnerTipo, setSpinnerTipo] = useState(1);

    //Seguridad
    const [usuarioS, setUsuarioS] = useSessionStorage('UsuarioSCON');
    const [menuId, setMenuId] = useState(0);
    const [menuOpciones, setMenuOpciones] = useState([]);
    const [showModalSeguridad, setShowModalSeguridad] = useState(false);
    const [opcionValidar, setOpcionValidar] = useState(0);
    const [opcionValidarNombre, setOpcionValidarNombre] = useState('');

    //Datos del formulario

    const [selectedEstado, setSelectedEstado] = useState(null);
    const [listaEstadoAnt, setListaEstadoAnt] = useState([]);
    const [selectedEstadoAnt, setSelectedEstadoAnt] = useState(null);
    const listaEstado = Config.listaEstadoAsientos;
    const [listaFiltros, setListaFiltros] = useState([{ value: 'P', text: 'Período' }, { value: 'N', text: 'Número' }, { value: 'D', text: 'Digitado' }]);
    const [selectedFiltro, setSelectedFiltro] = useState(listaFiltros[0].value);
    const [listaTipoAsiento, setListaTipoAsiento] = useState([]);
    const [selectedTipoAsiento, setSelectedTipoAsiento] = useState(null);
    const [id, setId] = useState(0);

    const botones = [
        {
            name: "btnHomeC",
            clase: "btn btn-sm pull-right flipInX animated",
            evento: () => volverAtras(),
            leyenda: "",
            iclase: faReply,
            tooltip: "Volver"
        },
        {
            name: "btnAceptar",
            clase: "btn btn-sm pull-right flipInX animated",
            evento: () => handleAceptar(),
            leyenda: "",
            iclase: faCheck,
            tooltip: "Aceptar"
        }
    ];

    const spinnerModalMostrar = (pSpinnerModal, pSpinnerLabel, pSpinnerTipo) => {
        setSpinnerModal(pSpinnerModal);
        setSpinnerLabel(pSpinnerLabel);
        setSpinnerTipo(pSpinnerTipo);
    };

    //Seguridad
    const cargarMenuOpciones = async (pModuloId, pUsuarioId, pMenuId) => {
        try {

            let listMO = await Obtener_MenuOpciones_Lista_Request(token, pModuloId, pUsuarioId, pMenuId);
            if (listMO.Exitoso === false) {
                return null;
            }
            return listMO.Datos;
        }
        catch (err) {
            Notificacion.error(`Error: cargarMenuOpciones.`);
        }
    };

    const cargarMenuNombre = async (pModulo, pMenuNombre) => {
        try {
            let listMON = await Obtener_MenuNombre_Request(token, pModulo, pMenuNombre);
            if (listMON.Exitoso == false) {
                return null;
            }
            return listMON.Datos;
        }
        catch (err) {
            Notificacion.error(`Error: cargarMenuNombre.`);
        }
    };

    const validarMenuOpcion = (pOpcion) => {
        let validar = false;
        let _menuOpciones = menuOpciones;
        const optSegopt = optSeg.TOpciones_Menu;
        let resultado = _menuOpciones.filter((item) => item.Opcion_Nombre == pOpcion);
        if (resultado.length > 0) {
            if (resultado[0].Opcion_Validar) {
                setShowModalSeguridad(true); setOpcionValidar(resultado[0].Opcion_Id); setOpcionValidarNombre(pOpcion);
                validar = true;
            }
        } else {
            setShowModalSeguridad(true); setOpcionValidar(resultado[0].Opcion_Id); setOpcionValidarNombre(pOpcion);
            validar = true;
        }
        return validar;
    };

    const handleCerrarModal = () => setShowModalSeguridad(false);

    const onActionResultModal = (pValido) => {
        if (pValido) {
            let _OpcionNom = opcionValidarNombre;
            setShowModalSeguridad(false); setOpcionValidar(0); setOpcionValidarNombre('');
            const _optSegopt = optSeg.TOpciones_Menu;

            switch (_OpcionNom) {
                case _optSegopt.Aprobar.value:
                case _optSegopt.Anular.value:
                case _optSegopt.Digitar.value:
                    handleAceptarSel();
                    break;
                case _optSegopt.Aplicar.value:
                    handleAplicarSel();
                    break;
                default:
                    break;
            }
        }
    };

    useEffect(() => {

        const carga = async () => {
            await cargarDatos();
        }
        carga();

    }, []);

    const cargarDatos = async () => {

        try {
            let spinnerLabel = 'Cargando datos...';
            spinnerModalMostrar(true, spinnerLabel, 3);

            const _id = parseInt(props.match.params.id);

            setId(_id);

            cargarListaEstadoAnt(_id);

            setSelectedEstado(itemSelect(_id, listaEstado));

            await cargarTiposAsiento();

            let _Empresa = null;

            _Empresa = await cargarEmpresa();
            let _Datos = { ...Datos };
            _Datos.fecMesAno.value = new Date(_Empresa.Periodo);

            if (_id === Config.eaAplicado) {
                setListaFiltros([{ value: 'P', text: 'Todos los asientos del período' }, { value: 'N', text: 'Rango de números' }]);
                _Datos.FechaInicio.attributes.hidden = 'none';
                _Datos.FechaFinal.attributes.hidden = 'none';
                _Datos.Estado.attributes.hidden = 'none';
                _Datos.EstadoAnt.attributes.hidden = 'none';
                _Datos.Numero.attributes.label = 'Del';
                _Datos.NumeroHasta.attributes.label = 'Al';
            }

            setDatosEmpresa(_Empresa);
            setDatos(_Datos);

            const _MenuNomb = await cargarMenuNombre(Config.Modulo, optSeg.TMenuSistema.Asientos.value);
            let _menuId = 0;

            if (_MenuNomb.ID != undefined) {
                _menuId = _MenuNomb.ID;
            }

            const _UsuarioS = usuarioS;
            let _menuOpciones = null;
            if (_menuId > 0) {
                _menuOpciones = await cargarMenuOpciones(Config.Modulo, _UsuarioS, _menuId);
            }
            setMenuId(_menuId), setMenuOpciones(_menuOpciones)
        } catch (e) {
            Notificacion.error(e.Message);
        }
        finally {
            spinnerModalMostrar(false, '', 3);
        }
    };

    const cargarListaEstadoAnt = (_id) => {
        let _listaEstados = [];

        switch (_id) {
            case Config.eaAprobado:
                _listaEstados.push(itemSelect(Config.eaDigitado, listaEstado));
                break;
            case Config.eaDigitado:
                _listaEstados.push(itemSelect(Config.eaAprobado, listaEstado));
                break;
            case Config.eaAplicado:
                _listaEstados.push(itemSelect(Config.eaAprobado, listaEstado));
                break;
            case Config.eaAnulado:
                _listaEstados.push(itemSelect(Config.eaDigitado, listaEstado));
                _listaEstados.push(itemSelect(Config.eaAprobado, listaEstado));
                break;
            default:
                break;
        }

        setListaEstadoAnt(_listaEstados);
        setSelectedEstadoAnt(_listaEstados[0]);

    }

    const cargarEmpresa = async () => {
        let response = await Empresa_Consulta_Request(token, empresa);

        if (response.Exitoso) {
            return (response.Datos);
        } else {
            Notificacion.error(response.Mensaje);
            volverAtras();
        }
        return [];
    };

    const cargarTiposAsiento = async () => {

        const response = await TipoAsiento_Listar_Request(token, empresa);
        let lista = [];
        if (response.Exitoso) {
            if (Array.isArray(response.Datos) && response.Datos.length > 0) {
                lista = [...response.Datos].map(x => ({ value: x.ID, label: x.Nombre, mensual: x.Mensual }));

                setListaTipoAsiento(lista);
                setSelectedTipoAsiento(lista[0]);

            } else {
                Notificacion.error("No se encontraron datos para: Tipo de Asiento.");
                volverAtras();
            }
        }
        else {
            Notificacion.error(response.Mensaje);
            volverAtras();
        }

        return lista;

    };

    const volverAtras = () => {
        historyMenu.push(SiteRutas.Asientos);
    };

    const handleAceptar = () => {

        if (validarDatos()) {
            const optSegopt = optSeg.TOpciones_Menu;
            let opcionValidar = '';

            switch (id) {
                case Config.eaDigitado:
                    opcionValidar = optSegopt.Digitar.value
                    break;
                case Config.eaAprobado:
                    opcionValidar = optSegopt.Aprobar.value
                    break;
                case Config.eaAplicado:
                    opcionValidar = optSegopt.Aplicar.value
                    break;
                case Config.eaAnulado:
                    opcionValidar = optSegopt.Anular.value
                    break;
                default:
                    break;
            }

            let validar = validarMenuOpcion(opcionValidar);

            if (!validar) {
                if (id === Config.eaAplicado) {
                    handleAplicarSel()
                } else {
                    handleAceptarSel();
                }
            }
        }
    }

    const handleAplicarSel = () => {

        let resultado = false;

        Swal.fire({
            title: 'Aplicar',
            html: '<h4>¿Está seguro de Aplicar los asientos que cumplan con los criterios seleccionados?',
            type: 'question',
            showCancelButton: true,
            confirmButtonColor: '#10a599',
            cancelButtonColor: '#d33',
            confirmButtonText: '<h5><i class="fa fa-check fa-fw"></i> Sí</h5>',
            cancelButtonText: '<h5><i class="fa fa-remove fa-fw"></i> No</h5>',
            reverseButtons: true,
            allowOutsideClick: false,
        }).then((result) => {
            if (result.value) {
                resultado = true;
                Aplicar();
            } else if (result.dismiss === Swal.DismissReason.cancel) {
                resultado = false;
            }
        });

    }

    const validarDatos = () => {
        if (selectedFiltro === "N") {
            if (Datos.Numero.value <= 0 || Datos.NumeroHasta.value <= 0) {
                Notificacion.warning("Debe ingresar un Número válido.");
                return false;
            }

            if (Datos.NumeroHasta.value < Datos.Numero.value) {
                Notificacion.warning("Debe ingresar un rango de números válido.");
                return false;
            }
        }

        return true;
    };

    const handleAceptarSel = async () => {

        let resultado = false;

        Swal.fire({
            title: 'Cambiar Estado',
            html: '<h4>¿Está seguro de cambiar el estado a los asientos que cumplan con las especificaciones  descritas?',
            type: 'question',
            showCancelButton: true,
            confirmButtonColor: '#10a599',
            cancelButtonColor: '#d33',
            confirmButtonText: '<h5><i class="fa fa-check fa-fw"></i> Sí</h5>',
            cancelButtonText: '<h5><i class="fa fa-remove fa-fw"></i> No</h5>',
            reverseButtons: true,
            allowOutsideClick: false,
        }).then((result) => {
            if (result.value) {
                resultado = true;
                cambiarEstado();
            } else if (result.dismiss === Swal.DismissReason.cancel) {
                resultado = false;
            }
        });

    }

    const cambiarEstado = async () => {

        let pDatos = {}

        pDatos.Empresa = empresa;
        pDatos.Estado = selectedEstadoAnt.value;
        pDatos.Tipo = selectedTipoAsiento.value;

        if (id === Config.eaAprobado) {
            pDatos.AprobadoX = usuario;
        }

        pDatos.Modificado = usuario;

        if (id === Config.eaDigitado) {
            pDatos.DigitadoX = usuario;
        }

        if (id === Config.eaAnulado) {
            pDatos.AnuladoX = usuario;
        }

        pDatos.Usuario_Modifica = usuario;
        pDatos.Fecha = Datos.fecMesAno.value;
        const _Estado = itemSelect(id, listaEstado);
        const porPeriodo = selectedFiltro === listaFiltros[0].value;
        const porNumero = selectedFiltro === listaFiltros[1].value;
        const porFechaDigitado = selectedFiltro === listaFiltros[2].value;

        spinnerModalMostrar(true, `Cambiando Estado a: ${_Estado.label}`, 3);
        const response = await EncabezadoAsiento_ModificarEstado_Request(token, pDatos, id, porPeriodo, porNumero, porFechaDigitado, Datos.Numero.value, Datos.NumeroHasta.value, Datos.FechaInicio.value, Datos.FechaFinal.value);
        spinnerModalMostrar(false, '', 3);

        if (response.Exitoso) {
            Notificacion.success(`El Estado fue actualizado correctamente a ${_Estado.label}.`);
            volverAtras();
        } else {
            Notificacion.error(`Error: ${response.Mensaje}`);
        }

    }

    const Aplicar = async () => {

        const porPeriodo = selectedFiltro === listaFiltros[0].value;
        const porRangoNumeros = selectedFiltro === listaFiltros[1].value;

        spinnerModalMostrar(true, `Aplicando asientos que cumplen con los criterios seleccionados`, 3);
        const response = await EncabezadoAsiento_Aplicar_Request(token, empresa, 0, false, porPeriodo, porRangoNumeros, Datos.fecMesAno.value, Datos.Numero.value, Datos.NumeroHasta.value, selectedTipoAsiento.value, usuario);
        spinnerModalMostrar(false, '', 3);

        if (response.Exitoso) {
            Notificacion.success(`Proceso realizado satisfactoriamente.`);
            volverAtras();
        } else {
            Notificacion.error(`Error: ${response.Mensaje}`);
        }

    }

    const handleSelectEstado = (selEstado) => {

        setSelectedEstado(selEstado);

    }

    const handleSelectEstadoAnt = (selEstado) => {

        setSelectedEstadoAnt(selEstado);

    }

    const handleRadioButton = (e, id) => {
        const name = id;
        const valor = e.target.value;
        let _Datos = { ...Datos };
        switch (name) {
            case "selectedFiltro":
                setSelectedFiltro(valor);

                //por periodo
                if (valor === listaFiltros[0].value) {
                    _Datos.TipoAsiento.attributes.readOnly = true;
                    _Datos.Numero.attributes.readOnly = true;
                    _Datos.NumeroHasta.attributes.readOnly = true;
                    _Datos.FechaInicio.attributes.readOnly = true;
                    _Datos.FechaFinal.attributes.readOnly = true;
                    _Datos.fecMesAno.attributes.readOnly = false;
                    //por Numero               
                } else if (valor === listaFiltros[1].value) {
                    _Datos.TipoAsiento.attributes.readOnly = false;
                    _Datos.Numero.attributes.readOnly = false;
                    _Datos.NumeroHasta.attributes.readOnly = false;
                    _Datos.FechaInicio.attributes.readOnly = true;
                    _Datos.FechaFinal.attributes.readOnly = true;
                    _Datos.fecMesAno.attributes.readOnly = true;
                    //por fecha digitado    
                } else if (valor === listaFiltros[2].value) {
                    _Datos.TipoAsiento.attributes.readOnly = true;
                    _Datos.Numero.attributes.readOnly = true;
                    _Datos.NumeroHasta.attributes.readOnly = true;
                    _Datos.FechaInicio.attributes.readOnly = false;
                    _Datos.FechaFinal.attributes.readOnly = false;
                    _Datos.fecMesAno.attributes.readOnly = true;
                }

                break;
        }

    };

    const onhandleChangeDate = async (date, id) => {
        const name = id;
        const value = date;
        let newAttributes = Datos[name].attributes;

        const _Datos = Object.assign({}, Datos, { [name]: { value: value, attributes: newAttributes } });

        setDatos(_Datos);

    }

    const onChangeInput = (e) => {
        const name = e.target.name;
        const value = e.target.value;

        const valido = validarInt(value);

        if (valido) {
            let newAttributes = Datos[name].attributes;
            let _Datos = Object.assign({}, Datos, {
                [name]: { value: value, attributes: newAttributes },
            });

            setDatos(_Datos);
        }
    };

    const handleSelectTipoAsiento = (selTipoAsiento) => {

        setSelectedTipoAsiento(selTipoAsiento);

    };

    return (
        <Fragment>
            <EstadoAsientoInt
                titulo={id === Config.eaAplicado ? "Aplicar asientos" : "Estado de Asientos"}
                Datos={Datos}
                botones={botones}
                handleSelectEstado={handleSelectEstado}
                listaEstado={listaEstado}
                selectedEstado={selectedEstado}
                listaFiltros={listaFiltros}
                selectedFiltro={selectedFiltro}
                handleRadioButton={handleRadioButton}
                onhandleChangeDate={onhandleChangeDate}
                listaTipoAsiento={listaTipoAsiento}
                selectedTipoAsiento={selectedTipoAsiento}
                onChangeInput={onChangeInput}
                handleSelectTipoAsiento={handleSelectTipoAsiento}
                handleSelectEstadoAnt={handleSelectEstadoAnt}
                selectedEstadoAnt={selectedEstadoAnt}
                listaEstadoAnt={listaEstadoAnt}
            />
            <ModalSpinner
                selectedModal={spinnerModal}
                contentLabel={'spinnerModalProgress'}
                label={spinnerLabel}
                tipoSpinner={spinnerTipo}
            />
            <ModalSeguridad
                modalTitle={'Requiere Permisos'}
                menuId={menuId}
                opcionId={opcionValidar}
                show={showModalSeguridad}
                onActionResult={onActionResultModal}
                onHide={handleCerrarModal}
            />
            <BotonArriba Delay={10} Visible={100} />
        </Fragment>

    );
}

export default withRouter(memo(EstadoAsiento));