import { Fragment, memo, useState, useEffect, useRef } from 'react';
import React from 'react';
import { useHistory, withRouter } from 'react-router-dom';
import { faReply, faSync, faPrint } from '@fortawesome/free-solid-svg-icons';
import ConciliacionAuxiliaresInt from './conciliacionAuxiliaresInt.jsx';
import { addDays, fechaPrimerDia, fechaUltimoDia, listaRangoNumeros, farmatearMontos, validarDecimal } from '../../components/Util/Util.jsx';
import Config from '../../components/Util/constantes.js';
import { Notificacion } from '../../components/Util/Notificacion/Notificacion.jsx';
import { Empresa_Consulta_Request } from '../../request/SeguridadRequest.jsx';
import { useSessionStorage } from '../../components/Util/Hooks/useSessionStorage.jsx';
import ModalSpinner from '../../components/UI/modalSpinner/modalSpinner.jsx';
import { ModulosConcilia_Listar_Request, Conciliacion_Busca_Cuentas, Conciliacion_Datos_Concilia, ConsularDatos_Reporte_Request } from '../../request/MantenimientosRequest.jsx';
import { Obtener_MenuNombre_Request, Obtener_MenuOpciones_Lista_Request } from '../../request/MenuRequest.jsx';
import ModalSeguridad from '../Seguridad/ModalSeguridad.jsx';
import optSeg from '../../components/Util/seg-menu-opciones.js';
import { SetParametrosReporte_Request, Get_Description_Report_Request } from '../../request/ReportesRequest.jsx';
import { baseUrl } from '../../request/RutasConfig.jsx';
import { SiteRutas } from '../../request/RutasConfig.jsx';

export function ConciliacionAuxiliares() {

    let historyMenu = useHistory();

    const _AnnoActual = new Date().getFullYear();
    const _ListaAnnos = listaRangoNumeros(Config.anoAntiguedad, _AnnoActual);

    const datosConst = {
        Modulo: { value: '', attributes: { readOnly: false, focus: false, label: 'Módulo', hidden: 'unset' } },
        fecMesAno: { value: addDays(new Date(), -30), attributes: { readOnly: false, focus: false, label: 'Desde', hidden: 'unset', minDate: fechaPrimerDia(new Date(Config.anoAntiguedad, 0, 1)), maxDate: fechaUltimoDia(new Date(_AnnoActual, 11, 1)), ListaAnnos: _ListaAnnos, formatDate: Config.formatoMesAno } },
    }

    const selectRowDesc = {
        mode: 'checkbox', hideSelectColumn: false, bgColor: '#d73220',
        style: { color: '#ffffff' }, clickToSelect: true,
        onSelect: (row, isSelected) => onRowSelectDet(row, isSelected),
        onSelectAll: (isSelect, rows) => handleOnSelectAllDet(isSelect, rows)
    };

    const selectRowDoc = {
        mode: 'radio', clickToSelect: true, hideSelectColumn: true, onSelect: (row, isSelect, rowIndex, e) => {
            onRowSelectDoc(row);
        }, clickToEdit: true, bgColor: '#d73220', style: { color: '#ffffff' }
    };

    const columnasDesc = [
        { dataField: 'Descripcion', text: 'Descripción', csvText: 'Descripción', hidden: false, sort: true, editable: false },
        { dataField: 'Cuenta', text: 'Cuenta', csvText: 'Cuenta', hidden: false, sort: true, editable: false },
        { dataField: 'Nombre', text: 'Nombre', csvText: 'Nombre', hidden: false, sort: true, editable: false },
    ];

    const columnasDoc = [
        {
            dataField: 'Documento', text: 'Documento', csvText: 'Documento', sort: false, editable: false, hidden: false,
            formatter: (e, column, columnIndex, row, rowIndex) => {
                const campo =
                    <b>{column.Documento}</b>
                return campo;
            }

        },
        {
            dataField: 'Saldo_Contabilidad', text: 'Contabilidad', csvText: 'Contabilidad', hidden: false, align: 'right',
            sort: false, editable: false, validator: (newValue, row, column) => {
                const valido = validaMonto(newValue, row, column);
                return valido;
            },
        },
        { dataField: 'Saldo_Auxiliar', text: 'Auxiliar', csvText: 'Auxiliar', hidden: false, sort: false, editable: false, align: 'right' },
        { dataField: 'Diferencia', text: 'Diferencia', csvText: 'Diferencia', hidden: false, sort: false, editable: false, align: 'right' },
        /*{
            dataField: 'Tiene_Detalle', text: 'Detalle', csvText: 'Detalle', hidden: false, sort: true, editable: false,
            formatter: (e, column, columnIndex, row, rowIndex) => {
                const campo =
                    <table style={tablest}>
                        <tbody>
                            <tr style={tablest}>
                                <td style={cuentacenter} > <a type="button" onClick={() => { reportesOpcion(column) }} ><i className="fa fa-file-text-o"></i></a></td>
                            </tr>
                        </tbody>
                    </table>
                return campo;
            }
        },*/
    ];

    const cellEdit = { mode: "click", autoSelectText: true, blurToSave: true };

    const reportesOpcion = async () => {

        if (JSON.stringify(filaSeleccionadaDoc) === '{}') {
            Notificacion.warning("Debe seleccionar un registro para continuar.");
            return;
        }

        if (filaSeleccionadaDoc.Tiene_Detalle) {

            let spinnerLabel = "Cargando datos...";
            spinnerModalMostrar(true, spinnerLabel, 3);

            let NombreEmpresa = datosEmpresa.Nombre, Empresa = datosEmpresa.Id;

            let moduloSeleccionado = selectedModulo, Periodo = datos.fecMesAno.value, tipo = filaSeleccionadaDoc.Tipo, Cuentas = cuentas;

            let consultaDatos = await ConsularDatos_Reporte_Request(token, Empresa, moduloSeleccionado.value, Periodo, Cuentas, tipo)

            if (consultaDatos.Exitoso) {
                await cargarReporteConciliacion(Empresa, NombreEmpresa, moduloSeleccionado, Cuentas, filaSeleccionadaDoc, Periodo);
            } else {
                Notificacion.error("No hay datos por mostrar.");
            }

            spinnerModalMostrar(false, "", 3);

        } else {
            Notificacion.info("No tiene detalle.");
        }

    };

    const reportesOpcion_bak = async (column) => {

        if (column.Tiene_Detalle) {

            let spinnerLabel = "Cargando datos...";
            spinnerModalMostrar(true, spinnerLabel, 3);

            let NombreEmpresa = datosEmpresa.Nombre, Empresa = datosEmpresa.Id;

            let moduloSeleccionado = selectedModulo, Periodo = datos.fecMesAno.value, tipo = column.Tipo, Cuentas = cuentas;

            let consultaDatos = await ConsularDatos_Reporte_Request(token, Empresa, moduloSeleccionado.value, Periodo, Cuentas, tipo)

            if (consultaDatos.Exitoso) {
                await cargarReporteConciliacion(Empresa, NombreEmpresa, moduloSeleccionado, Cuentas, column, Periodo);
            } else {
                Notificacion.error("No hay datos por mostrar.");
            }

            spinnerModalMostrar(false, "", 3);

        } else {
            Notificacion.info("No tiene detalle.");
        }

    };

    const cargarReporteConciliacion = async (pEmpresa, pNombreEmpresa, pModulo, pCuentas, pColumn, pPeriodo) => {

        let vFecha = (new Date(pPeriodo).toLocaleDateString('es-cr', { year: "numeric", month: "long" })).toString().replace("de ", "");

        let datosReporte = await Get_Description_Report_Request(token, Config.Reportes.ConciliacionAux);

        if (datosReporte.Exitoso) {

            const _parametros = {
                Reporte: Config.Reportes.ConciliacionAux,
                ReportNombre: `${datosReporte.Datos.ReportTitulo} - ${pModulo.label}`,
                NombreEmpresa: pNombreEmpresa,
                Empresa: pEmpresa,
                Periodo: vFecha,
                Modulo: pModulo.value,
                Cuentas: pCuentas,
                Tipo: pColumn.Tipo,
                Descripcion: pColumn.Documento,
                Fecha: pPeriodo
            };

            let data = await SetParametrosReporte_Request(token, _parametros);

            if (data.hasOwnProperty("Error")) {
                Notificacion.error(`${data.Error}`);
            } else {
                const myWindow = window.open();

                setTimeout(() => {
                    myWindow.location.replace(
                        `${baseUrl}ReportesSSR/MuestraReporte.aspx?ReporteId=${Config.Reportes.ConciliacionAux}&Empresa=${empresa}&Pais=${Pais}`
                    );
                }, 1);

            }
        } else {
            Notificacion.error("Sucedió un error al consultar los datos del reporte.");
        }

    }

    const onRowSelectDoc = (row, isSelect) => {
        setFilaSeleccionadaDoc(row);
    };

    const onRowSelectDet = (row, isSelect) => {

        let lista = [...filaSeleccionada];

        if (isSelect) {
            lista.push(row.ID);
        } else {
            lista = lista.filter(x => x !== row.ID);
        }

        setFilaSeleccionada(lista);
        return true;
    };

    const onRowSelectCuent = (event, row) => {

        const checked = event.target.checked;

        let lista = [...filaSeleccionada];

        if (checked) {
            lista.push(row.ID);

            if (lista.length === listaDatosDesc.length) {
                setCheckAl(true);
            }

        } else {
            lista = lista.filter(x => x != row.ID);
            setCheckAl(false);
        }

        setFilaSeleccionada(lista);
        return true;
    };

    const onRowSelectAllCuent = (event) => {

        const checked = event.target.checked;

        let lista = listaDatosDesc;

        if (checked) {
            setCheckAl(true);
            setFilaSeleccionada(lista.map(x => x.ID));
        } else {
            setFilaSeleccionada([]);
            setCheckAl(false);
        }

        return true;
    };

    const handleOnSelectAllDet = (isSelect, rows) => {
        if (isSelect) {
            setFilaSeleccionada(rows.map(x => x.ID));
            return rows.map(x => x.ID);
        } else {
            setFilaSeleccionada([]);
            return [];
        }
    };

    const botones = [
        {
            name: "btnHomeC",
            clase: "btn btn-sm pull-right flipInX animated",
            evento: () => volverAtras(),
            leyenda: "",
            iclase: faReply,
            tooltip: "Volver"
        },
        {
            name: "btnRefrescarC",
            clase: "btn btn-sm pull-right flipInX animated",
            evento: () => validarRefrescar(),
            leyenda: "",
            iclase: faSync,
            tooltip: "Refrescar"
        },
        {
            name: "btnRefrescarC",
            clase: "btn btn-sm pull-right flipInX animated",
            evento: () => reportesOpcion(),
            leyenda: "",
            iclase: faPrint,
            tooltip: "Reporte"
        },
    ];

    const mounted = useRef();
    const [menuId, setMenuId] = useState(0);
    const [datos, setDatos] = useState(datosConst);
    const [menuOpciones, setMenuOpciones] = useState([]);
    const [cuentas, setCuentas] = useState("");
    const [listaDatosDoc, setListaDatosDoc] = useState([]);
    const [listaDatosDesc, setListaDatosDesc] = useState([]);
    const [opcionValidar, setOpcionValidar] = useState(0);
    const [datosEmpresa, setDatosEmpresa] = useState(undefined);
    const [Pais, setPais] = useSessionStorage('paisCON');
    const [token, setToken] = useSessionStorage('tokenCON', '');
    const [empresa, setEmpresa] = useSessionStorage('empresaCON', 0);
    const [usuarioS, setUsuarioS] = useSessionStorage('UsuarioSCON');
    const [opcionValidarNombre, setOpcionValidarNombre] = useState('');
    const [showModalSeguridad, setShowModalSeguridad] = useState(false);
    const [checkAl, setCheckAl] = useState(false);

    const [listaModulos, setListaModulos] = useState(null);
    const [selectedModulo, setSelectedModulo] = useState(null);

    const [spinnerTipo, setSpinnerTipo] = useState(1);
    const [spinnerLabel, setSpinnerLabel] = useState('');
    const [spinnerModal, setSpinnerModal] = useState(undefined);
    const [filaSeleccionada, setFilaSeleccionada] = useState([]);
    const [filaSeleccionadaDoc, setFilaSeleccionadaDoc] = useState({});

    const volverAtras = () => {
        historyMenu.push(SiteRutas.Asientos);
    };

    const onFormato = (valor) => {
        return farmatearMontos(valor);
    };

    const validaMonto = (newValue, row, column) => {

        newValue = newValue.toString().replace(/,/g, "");

        if (newValue.toString().trim().length === 0) {
            return {
                valid: false,
                message: "Debe ingresar un dato válido",
            };
        }
        if (isNaN(newValue)) {
            return {
                valid: false,
                message: "Debe ingresar un dato válido",
            };
        }

        let isValid = true;
        isValid = validarDecimal(newValue);
        if (!isValid) {
            return {
                valid: false,
                message: "Debe ingresar un dato válidoaa",
            };
        }

        return { valid: true, mensaje: "" };
    };

    const handleRefrescar = async () => {

        let array = selectedModulo;

        if (array.value !== -1) {

            let spinnerLabel = "Buscando Saldos...";
            let cuentas = "0";
            spinnerModalMostrar(true, spinnerLabel, 3);

            if (filaSeleccionada.length > 0) {
                cuentas = (JSON.stringify(filaSeleccionada)).replace("[", "").replace("]", "")
                if (filaSeleccionada.length > 1) {
                    cuentas = cuentas.replace(/,/g, ", ");
                }
            }

            setCuentas(cuentas);

            let response = await Conciliacion_Datos_Concilia(token, empresa, array.value, datos.fecMesAno.value, cuentas);

            if (response.Exitoso) {

                let datosResponse = response.Datos;

                for (let i in datosResponse) {
                    for (let j in datosResponse[i]) {
                        if (j.toString().startsWith("Saldo") || j.toString().startsWith("Diferencia")) {
                            let numeroFormato = onFormato(datosResponse[i][j]);
                            datosResponse[i][j] = numeroFormato;
                        }
                    }
                }


                console.log(datosResponse);
                setListaDatosDoc(datosResponse);

            } else {
                Notificacion.error("Sucedió un error al buscar los datos de la conciliación.");
            }

            spinnerModalMostrar(false, "", 3);

        } else {
            Notificacion.error("Debe seleccionar el módulo.");
        }

    };

    const spinnerModalMostrar = (pSpinnerModal, pSpinnerLabel, pSpinnerTipo) => {
        setSpinnerModal(pSpinnerModal);
        setSpinnerLabel(pSpinnerLabel);
        setSpinnerTipo(pSpinnerTipo);
    };

    const validarRefrescar = async () => {
        const optSegopt = optSeg.TOpciones_Menu;
        const _value = optSegopt.Refrescar.value;

        let validar = validarMenuOpcion(_value);

        if (!validar) {
            await handleRefrescar();
        }
    };

    useEffect(() => {

        if (!mounted.current) {
            const carga = async () => {
                await cargarDatos()
            }
            carga();

            mounted.current = true;
        }

    }, []);

    const onhandleSelectedModulo = async (selSeccion) => {

        if (selSeccion.value !== selectedModulo.value) {
            let spinnerLabel = "Cargando datos...";
            spinnerModalMostrar(true, spinnerLabel, 3);

            setSelectedModulo(selSeccion);

            let response = await Conciliacion_Busca_Cuentas(token, empresa, selSeccion.value);

            if (response.Exitoso) {
                setCuentas("");
                setListaDatosDoc([]);
                setListaDatosDesc([]);
                setFilaSeleccionada([]);

                for (let i in response.Datos) {
                    response.Datos[i].Nombre = capitalize(response.Datos[i].Nombre);
                }

                setListaDatosDesc(response.Datos);

            } else {
                Notificacion.error("Sucedió un error al buscar las cuentas.");
            }


            spinnerModalMostrar(false, "", 3);
        }

    };

    const capitalize = (word) => {
        word = word.toLowerCase();
        const result = word[0].toUpperCase() + word.slice(1);
        return result;
    }

    const onhandleChangeDate = async (date, id) => {
        const name = id;
        const value = date;
        let array = listaDatosDoc;
        let newAttributes = datos[name].attributes;

        const _Datos = Object.assign({}, datos, { [name]: { value: value, attributes: newAttributes } });

        setDatos(_Datos);

        if (array.length > 0) {
            setCuentas("");
            setListaDatosDoc([]);
        }

        /* if (id !== "pFecha") {
             setListaGralAs([]);
         }*/
    };

    const cargarDatos = async () => {

        let spinnerLabel = 'Cargando datos...';
        spinnerModalMostrar(true, spinnerLabel, 3)

        let _Empresa = [];

        _Empresa = await cargarEmpresa();
        await cargarSeguridad();

        let _Datos = { ...datos }
        _Datos.fecMesAno.value = new Date(_Empresa.Periodo);

        await cargarModulosConcilia();

        //let _Datos = { ...datos }
        //_Datos.fecMesAno.value = new Date(_Empresa.Periodo);
        setDatosEmpresa(_Empresa);
        // setDatos(_Datos);

        spinnerModalMostrar(false, '', 3)
    };

    const cargarModulosConcilia = async () => {
        let response = await ModulosConcilia_Listar_Request(token, "", 0);
        let lista = [];
        if (response.Exitoso) {
            if (Array.isArray(response.Datos) && response.Datos.length > 0) {
                response.Datos.map(x => (lista.push({ value: x.Modulo_Constante, label: x.Modulo_Despliegue, Modulo_Nombre: x.Modulo_Nombre })));
                lista.sort((a, b) => (a.label > b.label ? 1 : -1))
                setListaModulos(lista);
                setSelectedModulo({ value: -1, label: "", Modulo_Nombre: "" });

            } else {
                volverAtras();
            }

        }
        else {
            Notificacion.error(response.Mensaje);
            volverAtras();
        }
    };

    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 cargarSeguridad = async () => {
        const _MenuNomb = await cargarMenuNombre(Config.Modulo, optSeg.TMenuSistema.ConciliaciondeAuxiliares.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);
    };

    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;
        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 onActionResultModal = (pValido) => {
        if (pValido) {
            let _OpcionNom = opcionValidarNombre;
            setShowModalSeguridad(false); setOpcionValidar(0); setOpcionValidarNombre('');
            const _optSegopt = optSeg.TOpciones_Menu;
            switch (_OpcionNom) {
                case _optSegopt.Refrescar.value:
                    handleRefrescar();
                    break;
                default:
                    break;
            }
        }
    }

    const handleCerrarModal = () => setShowModalSeguridad(false);

    return (
        <Fragment>

            <ConciliacionAuxiliaresInt
                Datos={datos}
                titulo={"Conciliación de Módulos Auxiliares"}
                botones={botones}
                selectedModulo={selectedModulo}
                listaModulos={listaModulos}
                onhandleSelectedModulo={onhandleSelectedModulo}
                columnasDesc={columnasDesc}
                listaDatosDesc={listaDatosDesc}
                selectRowDesc={selectRowDesc}
                columnasDoc={columnasDoc}
                listaDatosDoc={listaDatosDoc}
                selectRowDoc={selectRowDoc}
                onhandleChangeDate={onhandleChangeDate}
                cellEdit={cellEdit}
                filaSeleccionada={filaSeleccionada}
                onRowSelectCuent={onRowSelectCuent}
                onRowSelectAllCuent={onRowSelectAllCuent}
                checkAl={checkAl}
            />

            <ModalSpinner
                selectedModal={spinnerModal}
                contentLabel={'spinnerModalProgress'}
                label={spinnerLabel}
                tipoSpinner={spinnerTipo}
            />

            <ModalSeguridad
                modalTitle={'Requiere Permisos'}
                menuId={menuId}
                opcionId={opcionValidar}
                show={showModalSeguridad}
                onActionResult={onActionResultModal}
                onHide={handleCerrarModal}
            />

        </Fragment>
    );
};
export default withRouter(memo(ConciliacionAuxiliares))