﻿import React, { Fragment, memo, useState, useEffect, } from 'react';
import { useHistory, withRouter } from 'react-router-dom';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faReply, faSave, faSearch, faFileWord, faList, faFolderPlus, faCalculator, faClipboardList } from '@fortawesome/free-solid-svg-icons';

import { SiteRutas } from '../../../request/RutasConfig.jsx';

import Config from '../../../components/Util/constantes.js';
import { Notificacion } from '../../../components/Util/Notificacion/Notificacion.jsx';
import ModalSpinner from '../../../components/UI/modalSpinner/modalSpinner.jsx';
import BotonArriba from '../../../components/UI/botonArriba/botonArriba.jsx';
import ModalBusqueda from '../../../components/UI/modalBusqueda/modalBusqueda.jsx';
import ModalBusquedaTree from '../../../components/UI/modalBusqueda/modalBusquedaTree.jsx';

import {
    farmatearMontos, validarDecimal, Round, farmatearFechaEstandar,
    itemSelect, validarIntVig, validaCuenta, datosArbol, validaCCosto
} from '../../../components/Util/Util.jsx';
import { useSessionStorage } from '../../../components/Util/Hooks/useSessionStorage.jsx';
import Swal from 'sweetalert2';
import { Type } from 'react-bootstrap-table2-editor';
import moment from 'moment';

//Seguridad
import Session from '../../../components/Util/session/index.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 {
    TipoAsiento_Listar_Request,
    DetallePlantillas_Listar_Request, EncaPlantillas_Guardar_Request, EncaPlantillas_Listar_Request,
    EncaPlantillas_Modificar_Request, EncaPlantillas_Consultar_Request
} from '../../../request/MantenimientosRequest.jsx';

import {
    Catalogo_Lista_Request, CentroCosto_Lista_CCC_Request, CentroCosto_Lista_CXCC_Request,
    CentroCosto_Lista_CXCCEmpresa_Request, CentroCostos_CentroDefault_Request
} from '../../../request/ServicioRequest.jsx';
import { Empresa_Consulta_Request } from "../../../request/SeguridadRequest.jsx";

import MantPlantillasInt from './MantPlantillasInt.jsx';

function MantPlantillas(props) {
    const pDatos = {
        Estado: { value: "", attributes: { readOnly: false, focus: false, label: 'Estado', hidden: "unset" } },
        Tipo: { value: "", attributes: { readOnly: false, focus: false, label: 'Tipo', hidden: "unset" } },
        Nombre: { value: "", attributes: { readOnly: false, focus: false, label: 'Nombre', hidden: "unset", maxLength: 25 } },
        Descripcion: { value: "", attributes: { readOnly: false, focus: false, label: 'Descripción', hidden: "unset", maxLength: 255 } },
        Comentario: { value: "", attributes: { readOnly: false, focus: false, label: 'Comentario', hidden: "unset", maxLength: 255 } },
        FechaInicial: { value: new Date(), attributes: { readOnly: true, focus: false, label: 'Fecha Inicial', hidden: "unset" } },
        FechaFinal: { value: new Date(), attributes: { readOnly: true, focus: false, label: 'Fecha Final', hidden: "unset" } },
        Recurrente: { value: true, attributes: { readOnly: false, focus: false, label: 'Recurrente', hidden: "unset" } },
        TipoValor: { value: "", attributes: { readOnly: false, focus: false, label: 'Valor', hidden: "unset" } },
    };
    const spinner = { mostrar: false, texto: '', tipo: 3 };
    const [Datos, setDatos] = useState(pDatos);
    const [SpinnerModal, setSpinnerModal] = useState(spinner);
    const [empresa, setEmpresa] = useSessionStorage('empresaCON');
    const [empresaNombre, setEmpresaNombre] = useSessionStorage('empresaNombreCON');

    const [token, setToken] = useSessionStorage('tokenCON', '');
    const [usuario, setUsuario] = useSessionStorage('usuarioCON');
    const [usuarioS, setUsuarioS] = useSessionStorage('UsuarioSCON', '');
    const [Pais, setPais] = useSessionStorage('paisCON');
    const [id, setId] = useState(0);
    let historyMenu = useHistory();

    //Seguridad
    const [menuId, setMenuId] = useState(0);
    const [menuOpciones, setMenuOpciones] = useState([]);
    const [showModalSeguridad, setShowModalSeguridad] = useState(false);
    const [opcionValidar, setOpcionValidar] = useState(0);
    const [opcionValidarNombre, setOpcionValidarNombre] = useState('');

    //Datos formulario
    const [selectModalTree, setSelectModalTree] = useState(false);
    const [pColumn, setPColumn] = useState(undefined);
    const [pColumnIndex, setPColumnIndex] = useState(undefined);
    const [pRow, setPRow] = useState(undefined);
    const [pRowIndex, setPRowIndex] = useState(undefined);
    const [idCtaObj, setIdCtaObj] = useState(undefined);
    const [selectModal, setSelectModal] = useState(undefined);
    const [rowsSelected, setRowSelected] = useState(undefined);
    const [listaArbolCuenta, setListaArbolCuenta] = useState([]);
    const [listCentroCosto, setListCentroCosto] = useState([]);
    const [listCentroCostoFiltro, setListCentroCostoFiltro] = useState([]);
    const [indexCost, setIndexCost] = useState(undefined);
    const [idCCObj, setIdCCObj] = useState(undefined);
    const [selectedCuenta, setSelectedCuenta] = useState(undefined);
    const [indexC, setIndexC] = useState(undefined);
    const [actTabla, setActTabla] = useState(false);
    const [listCuentasCont, setListCuentasCont] = useState([]);
    const [listCuentas, setListCuentas] = useState([]);
    const [listCCosto, setListCCosto] = useState([]);
    const [listCXCC, setListCXCC] = useState([]);
    const [selectedCentroCosto, setSelectedCentroCosto] = useState(undefined);
    const tipoCreacion = [{ id: 1, value: 'Normal' }, { id: 2, value: 'De Plantilla' }, { id: 3, value: 'De Excel' }];
    const [selectedTipoCreacion, setSelectedTipoCreacion] = useState(tipoCreacion[2]);
    const [plantilla, setPlantilla] = useState(undefined);
    const [datosEmpresa, setDatosEmpresa] = useState(undefined);
    const [totalDebe, setTotalDebe] = useState(0);
    const [totalHaber, setTotalHaber] = useState(0);
    const [listaDatos, setListaDatos] = useState([]);
    const [listaTipoAsiento, setListaTipoAsiento] = useState([]);
    const [selectedTipoAsiento, setSelectedTipoAsiento] = useState(undefined);
    const [listaEstado, setListaEstado] = useState([{ value: 'D', label: 'Digitado' }, { value: 'A', label: 'Aprobado' }]);
    const [selectedEstado, setSelectedEstado] = useState(listaEstado[0]);
    const [listaTipoValor, setListaTipoValor] = useState([{ value: "1", text: 'Simple' }, { value: "2", text: 'Porcentual' }]);
    const [selectedTipoValor, setSelectedTipoValor] = useState(listaTipoValor[0].value);
    const [listaRecurrente, setListaRecurrente] = useState([{ value: "S", text: 'Si' }, { value: "N", text: 'No' }]);
    const [selectedRecurrente, setSelectedRecurrente] = useState(listaRecurrente[1].value);
    const [filaSeleccionada, setFilaSeleccionada] = useState(undefined);
    const [validarBalanceado, setValidarBalanceado] = useState(false);

    const cuentaright = { textAlign: 'right', width: '10%' };
    const cuentacenter = { textAlign: 'center', width: '90%' };
    const tablest = { width: '100%' };
    const Header = [
        { title: 'Centro Costo', field: 'CentroCosto' },
        { title: 'Nombre', field: 'Nombre' },
        { title: 'id', field: 'ID', hidden: true },
    ];

    const columnas = [
        { dataField: 'Linea', text: '', csvExport: false, hidden: true },
        {
            dataField: 'CuentaStr', text: 'Cuenta', csvText: 'Cuenta', sort: true, footer: '',
            editable: true, validator: (newValue, row, column) => {
                return onValidarCuenta(newValue, row, column);
            },
            formatter: (e, column, columnIndex, row, rowIndex) => {
                const _llaveCta = column.Linea.toString();
                const campo =
                    <table style={tablest}>
                        <tbody>
                            <tr style={tablest}>
                                <td id={_llaveCta} style={cuentacenter}>{column.CuentaStr}</td>
                                <td style={cuentaright} > <a type="button" onClick={() => { handleCuentaModal(column, columnIndex, row, rowIndex) }} ><i className="fa fa-search"></i></a></td>
                            </tr>
                        </tbody>
                    </table>
                return campo;
            }
        },
        { dataField: 'NombreCuenta', text: 'Nombre de Cuenta', sort: true, editable: false, footer: '', },
        { dataField: 'Centro_Costo', text: 'Centro Costo', hidden: true, csvExport: false, sort: true, editable: false, footer: '', },
        {
            dataField: 'Centro_CostoStr', text: 'Centro Costo', csvExport: true, csvText: 'Centro Costo', sort: true, editable: true, footer: '',
            validator: (newValue, row, column) => {
                return onValidarCCosto(newValue, row, column);
            },
            formatter: (e, column, columnIndex, row, rowIndex) => {
                const _llave = column.Linea + 'B';
                const campo =
                    <table style={tablest}>
                        <tbody>
                            <tr style={tablest}>
                                <td id={_llave} style={cuentacenter} > {column.Centro_CostoStr} </td>
                                <td style={cuentaright} > <a type="button" onClick={() => { handleModal(column, columnIndex) }} ><i className="fa fa-search"></i></a></td>
                            </tr>
                        </tbody>
                    </table>
                return campo;
            }

        },
        {
            dataField: 'Fecha', text: 'Fecha', sort: true, align: 'center', headerAlign: 'center', editable: true, footer: '',
            formatter: (row, cell) => { return cell.Fecha !== null && cell.Fecha !== '' ? farmatearFechaEstandar(cell.Fecha) : '' },
            validator: (newValue, row, column) => {
                return onValidarFecha(newValue, row, column);
            },
            editor: {
                type: Type.DATE
            }
        },
        {
            dataField: 'Documento', text: 'Documento', csvText: 'Documento', editable: true, sort: true, align: 'left', headerAlign: 'center', footer: '',
            editor: { type: Type.TEXTAREA },
            validator: (newValue, row, column) => {
                if (newValue.length > 255) {
                    return {
                        valid: false,
                        message: '¡No puede superar los 255 caracteres!'
                    }
                } else {
                    return true;
                }
            },
        },
        {
            dataField: 'Descripcion', text: 'Descripción', csvText: 'Descripcion', sort: true, align: 'left',
            headerAlign: 'left', editable: true, editor: { type: Type.TEXTAREA },
            validator: (newValue, row, column) => {
                if (newValue.length > 255) {
                    return {
                        valid: false,
                        message: '¡No puede superar los 255 caracteres!'
                    }
                } else {
                    return true;
                }
            },
            footerStyle: (column, colIndex) => {
                if (totalDebe - totalHaber < 0) {
                    return { Color: '#ff0000', textAlign: 'right' }
                } else {
                    return { Color: '#000000', textAlign: 'right' }
                }
            },
            footer: farmatearMontos(Round(totalDebe - totalHaber, 2))
        },
        {
            dataField: 'Debito', text: 'Debe', csvText: 'Debe', formatter: (row, cell) => farmatearMontos(cell.Debito), hidden: false, editable: true, align: 'right',
            validator: (newValue, row, column) => {
                return validaDebe(newValue, row);
            },
            footer: (columnData, column, columnIndex) => {
                const total = columnData.reduce((acc, item) => acc + item, 0);
                setTotalDebe(total);
                return farmatearMontos(Round(total, 2));
            }
            , type: 'number',
            footerStyle: { Color: '#ff0000', textAlign: 'right' }
        },
        {
            dataField: 'Credito', text: 'Haber', csvText: 'Haber', hidden: false, editable: true, align: 'right',
            formatter: (row, cell) => farmatearMontos(cell.Credito), type: 'number',
            footer: (columnData, column, columnIndex) => {
                const total = columnData.reduce((acc, item) => acc + item, 0);
                setTotalHaber(total);
                return farmatearMontos(Round(total, 2));
            },
            footerStyle: { Color: '#ff0000', textAlign: 'right' },
            validator: (newValue, row, column) => {
                return validaHaber(newValue, row);
            },
        },];
    const botones = [
        { name: "btnVolver", clase: "btn btn-sm pull-right flipInX animated", evento: () => volverAtras(), leyenda: "", iclase: faReply, tooltip: "Volver" },
        { name: "btnGuardar", clase: "btn btn-sm pull-right flipInX animated", evento: () => handleGuardar(), leyenda: "", iclase: faSave, tooltip: "Guardar" },
    ];

    const handleGuardar = async () => {

        const optSegopt = optSeg.TOpciones_Menu;
        const _value = (id > 0) ? optSegopt.Editar.value : optSegopt.Nuevo.value;

        const hayErrores = hayErroresLinea();
        if (hayErrores.length > 0) {
            Notificacion.error(hayErrores);
        } else {
            if (validarDatos()) {
                let validar = validarMenuOpcion(_value);
                if (!validar) {
                    if (id === 0) {
                        await guardarPlantilla();
                    } else {
                        await modificarPlantilla();
                    }
                }
            }
        }

    }

    const validarDatos = () => {
        if (Datos.Nombre.value.trim().length === 0) {
            Notificacion.warning("Debe ingresar un Nombre.");
            return false;
        }

        if (Datos.Comentario.value.trim().length === 0) {
            Notificacion.warning("Debe ingresar un Comentario.");
            return false;
        }

        if (Datos.Descripcion.value.trim().length === 0) {
            Notificacion.warning("Debe ingresar una Descripción.");
            return false;
        }

        return true;
    };

    const hayErroresLinea = () => {

        let fila = 0;
        let Error = '';
        let i = 0;
        let Linea = '';
        let Row = 0;
        let _listaDatos = [].concat(listaDatos.filter(x => x.Debito > 0 || x.Credito > 0));

        if (Datos.Descripcion.value.trim() === '' && Error === '') {
            Error = 'No se puede guardar la plantilla ya que necesita una descripción';
        }

        while (i < _listaDatos.length && Error === '') {

            if ((_listaDatos[i].CuentaStr !== '') || ((_listaDatos[i].Debito + _listaDatos[i].Credito) > 0)) {
                Linea = 'La línea ' + (i + 1).toString();

                if (_listaDatos[i].CuentaStr === '')
                    Error = Linea + ' tiene montos asociados, pero ninguna cuenta válida que referenciar.';
                else if (_listaDatos[i].Centro_CostoStr === '')
                    Error = Linea + ' tiene montos asociados, pero ningún centro de costo válido que referenciar.';

                if (Error !== '')
                    Row = i;
            }

            i++;

        }

        if (listaTipoAsiento.length > 0) {
            if (Error === '' && (SumeMontos(true) - SumeMontos(false)) !== 0)
                Error = 'El asiento no se encuentra balanceado.';
        } else {
            Error = 'Debe definir el tipo de asiento.';
        }

        return Error;

    }

    const guardarPlantilla = async () => {

        let fModificado = false;
        let Result = false;

        try {

            spinnerModalMostrar(true, 'Guardando Plantilla');

            fModificado = true;
            Result = true;

            const Descripcion = Datos.Descripcion.value;
            const Nombre = Datos.Nombre.value;
            const Comentario = Datos.Comentario.value;
            const tipoAsiento = selectedTipoAsiento.value;
            const aprobado = selectedEstado === listaEstado[1];
            const FechaInicio = moment(Datos.FechaInicial.value).startOf('month').format("YYYY/MM/DD");
            const FechaFinal = moment(Datos.FechaFinal.value).startOf('month').format("YYYY/MM/DD");
            const tipoValor = parseInt(selectedTipoValor);
            const recurrente = selectedRecurrente === "S";

            const _datos = {
                ID: id, FechaIni: FechaInicio, FechaFin: FechaFinal, FechaAct: FechaInicio, Tipo: tipoValor, Nombre: Nombre,
                Descripcion: Descripcion, Comentario: Comentario, Tipo_Asiento: tipoAsiento, Aprobado: aprobado,
                Recurrencia: recurrente, Usuario_Modifica: usuario, Empresa: empresa
            };

            let _lista = listaDatos.filter(x => parseInt(x.Debito) > 0 || parseInt(x.Credito) > 0);

            _lista.forEach((element, i) => {
                element.Linea = i + 1
            });

            const response = await EncaPlantillas_Guardar_Request(token, _datos, _lista);

            if (response.Exitoso) {
                Notificacion.success('Se guardó la plantilla exitosamente.');
                volverAtras();
            } else {
                Notificacion.error(`Error: ${response.Mensaje}`);
            }

        } catch (ex) {
            Notificacion.error(ex.message);
        } finally {
            spinnerModalMostrar(false, '');
        }

        return Result;

    }

    const modificarPlantilla = async () => {

        let NomCont = '';
        let Numero = '';

        try {

            spinnerModalMostrar(true, 'Modificando plantilla');


            const descripcion = Datos.Descripcion.value;
            const nombre = Datos.Nombre.value;
            const comentario = Datos.Comentario.value;
            const tipoAsiento = selectedTipoAsiento.value;
            const aprobado = selectedEstado === listaEstado[1];
            const FechaInicio = moment(Datos.FechaInicial.value).startOf('month').format("YYYY/MM/DD");
            const FechaFinal = moment(Datos.FechaFinal.value).startOf('month').format("YYYY/MM/DD");
            const tipoValor = parseInt(selectedTipoValor);
            const recurrente = selectedRecurrente === "S";

            const _datos = {
                ID: id, Empresa: empresa, Tipo: tipoValor, Nombre: nombre, Comentario: comentario, Descripcion: descripcion,
                Tipo_Asiento: tipoAsiento, Aprobado: aprobado, Recurrencia: recurrente,
                FechaIni: FechaInicio, FechaFin: FechaFinal, FechaAct: FechaInicio, Usuario_Modifica: usuario
            };

            let _lista = listaDatos.filter(x => parseInt(x.Debito) > 0 || parseInt(x.Credito) > 0);

            _lista.forEach((element, i) => {
                element.Linea = i + 1
            });

            const response = await EncaPlantillas_Modificar_Request(token, _datos, _lista);

            if (response.Exitoso) {
                Notificacion.success('Se modificó la plantilla exitosamente.');
                volverAtras();
            } else {
                Notificacion.error(`Error: ${response.Mensaje}`);
            }

        } catch (ex) {
            Notificacion.error(`Error: ${ex.message}`);
        } finally {
            spinnerModalMostrar(false, '');
        }
    }

    const validaDebe = (newValue, row) => {
        setTotalDebe(SumeMontos(true));
        setTotalHaber(SumeMontos(false));
        if (!isNaN(newValue)) {
            if (parseFloat(newValue) > 0 && parseFloat(row.Credito) > 0) {
                return {
                    valid: false,
                    message: 'No se puede digitar valores en ambos lados.'
                }
            } else {
                //si el valor es porcentual
                if (selectedTipoValor === listaTipoValor[1].value) {
                    if (parseFloat(newValue) !== 0 && (parseFloat(newValue) <= 0 || parseFloat(newValue) > 100)) {
                        return {
                            valid: false,
                            message: 'El monto de cada cuenta es porcentual entre 0 y 100.'
                        }
                    }
                }

                if (parseFloat(newValue) >= 0) {
                    return true;
                } else {
                    return {
                        valid: false,
                        message: '¡Debe ingresar un valor numérico!'
                    }
                }
            }
        } else {
            return {
                valid: false,
                message: '¡Debe ingresar un valor numérico!'
            }
        }
    }

    const validaHaber = (newValue, row) => {
        setTotalDebe(SumeMontos(true));
        setTotalHaber(SumeMontos(false));
        if (!isNaN(newValue)) {
            if (parseFloat(newValue) > 0 && parseFloat(row.Debito) > 0) {
                return {
                    valid: false,
                    message: '¡No puede llenar Debe y Haber en la misma fila!'
                }
            } else {

                //si el valor es porcentual
                if (selectedTipoValor === listaTipoValor[1].value) {
                    if (parseFloat(newValue) !== 0 && (parseFloat(newValue) <= 0 || parseFloat(newValue) > 100)) {
                        return {
                            valid: false,
                            message: 'El monto de cada cuenta es porcentual entre 0 y 100.'
                        }
                    }
                }

                if (parseFloat(newValue) >= 0) {
                    return true;
                } else {
                    return {
                        valid: false,
                        message: '¡Debe ingresar un valor numérico!'
                    }
                }
            }
        } else {
            return {
                valid: false,
                message: '¡Debe ingresar un valor numérico!'
            }
        }
    }

    const handleModal = async (cell, row) => {

        const modal = true;
        const _indexCost = row;


        if (!!cell.Cuenta) {
            if (cell.Cuenta != -1) {
                spinnerModalMostrar(true, 'Cargando datos');
                const response = await CentroCosto_Lista_CXCC_Request(token, empresa, cell.Cuenta);
                spinnerModalMostrar(false, '');

                let _listCentroCostoFiltro = [];

                if (response.Exitoso) {
                    _listCentroCostoFiltro = response.Datos;
                } else {
                    Notificacion.error(response.Mensaje);
                    volverAtras();
                    return;
                }

                const _idCCObj = cell.Linea.toString() + 'B';
                setSelectModal(modal), setListCentroCosto(_listCentroCostoFiltro), setListCentroCostoFiltro(_listCentroCostoFiltro);
                setIndexCost(_indexCost), setIdCCObj(_idCCObj);

            } else {
                Notificacion.warning('Debe seleccionar una cuenta contable.');
            }
        } else {
            Notificacion.warning('Debe seleccionar una cuenta contable.');
        }

    }

    const handleCuentaModal = (cell, columnIndex, row, rowIndex) => {

        const indexC = listaDatos.findIndex((element) => element.Linea === cell.Linea);

        setIndexC(indexC);
        setSelectModalTree(true);
        setPColumn(cell);
        setPColumnIndex(columnIndex);
        setPRow(row);
        setPRowIndex(rowIndex);
        setIdCtaObj(cell.Linea);

    }

    const onValidarCCosto = (newValue, row, column) => {
        if (row.Centro_CostoStr !== newValue) {
            if (column.dataField == 'Centro_CostoStr') {
                if (!!row.Cuenta) {
                    if (row.Cuenta != -1) {
                        const validacion = validaCCosto(listCCosto, row.Cuenta, newValue, listCXCC)
                        if (validacion.length > 0) {
                            return {
                                valid: false,
                                message: validacion
                            };
                        } else {
                            const listaCCosto = listCCosto.filter(item => item.Cuenta == newValue);
                            row.Centro_CostoNom = listaCCosto[0].Nombre;
                            row.Centro_Costo = listaCCosto[0].ID;
                            return true;
                        }
                    } else {
                        return {
                            valid: false,
                            message: 'Debe seleccionar una cuenta contable'
                        };
                    }
                } else {
                    return {
                        valid: false,
                        message: 'Debe seleccionar una cuenta contable'
                    };
                }
            }
        } else {
            return true;
        }
    }

    const onValidarCuenta = async (newValue, row, column) => {
        if (row.CuentaStr !== newValue) {

            if (column.dataField == 'CuentaStr') {
                const validacion = validaCuenta(listCuentas, newValue)

                if (validacion.length > 0) {
                    return {
                        valid: false,
                        message: validacion
                    };
                } else {

                    const _listaCuenta = listCuentas.filter(item => item.Cuenta == newValue || item.CuentaStr == newValue);

                    row.NombreCuenta = _listaCuenta[0].Nombre;
                    row.CuentaStr = _listaCuenta[0].Cuenta;
                    row.Cuenta = _listaCuenta[0].ID;

                    return true;
                }
            }
        } else {
            return true;
        }
    }

    const onValidarFecha = (newValue, row, column) => {
        if (newValue !== '') {
            if (!moment(newValue).isValid()) {
                return {
                    valid: false,
                    message: 'Debe ingresar una fecha válida'
                };
            } else {
                return true;
            }
        } else {
            row.Fecha = null;
            return true;
        }
    }

    const volverAtras = () => {
        historyMenu.push(SiteRutas.Plantillas);
    }

    const spinnerModalMostrar = (mostrar, texto, tipo = 3) => {
        setSpinnerModal({ mostrar: mostrar, texto: texto, tipo: tipo });
    }

    const ordenarArreglo = (a, b, columna) => {
        if (a[columna] < b[columna]) {
            return -1;
        }
        if (a[columna] > b[columna]) {
            return 1;
        }
        return 0;
    }

    const cargarSeguridad = async () => {
        const _MenuNomb = await cargarMenuNombre(Config.Modulo, optSeg.TMenuSistema.Plantillas.value);
        let _menuId = 0;

        if (_MenuNomb.ID != undefined) {
            _menuId = _MenuNomb.ID;
        }

        let _menuOpciones = null;
        if (_menuId > 0) {
            _menuOpciones = await cargarMenuOpciones(Config.Modulo, usuarioS, _menuId);
        }
        setMenuId(_menuId), setMenuOpciones(_menuOpciones);
    }

    //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 cerrarModal = () => {

        setSelectModal(false);
        setSelectedCentroCosto(undefined);
        setIndexCost(indexCost);
        setRowSelected(undefined);

    }

    const onActionResultModal = (pValido) => {
        if (pValido) {
            let _OpcionNom = opcionValidarNombre;
            setShowModalSeguridad(false); setOpcionValidar(0); setOpcionValidarNombre('');
            const _optSegopt = optSeg.TOpciones_Menu;

            switch (_OpcionNom) {
                case _optSegopt.Nuevo.value:
                    guardarPlantilla();
                    break;
                case _optSegopt.Editar.value:
                    modificarPlantilla();
                    break;
                default:
                    break;
            }
        }
    }

    const cargarTiposAsiento = async (_Datos) => {

        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 llenadoListaArbol = (pLista) => {
        let _Datos = [];
        const _Lista = pLista;
        _Datos.push({ "title": empresaNombre, "subtitle": "", "padre": -1, "value": 0 });

        _Lista.map(function (item, index) {
            _Datos.push({ "title": item.Cuenta + " " + item.Nombre, "subtitle": "", "padre": (item.Padres.length > 0 ? parseInt(item.Padres.substring(item.Padres.length - 6, item.Padres.length)) : 0), "value": item.ID });
        });

        return _Datos;
    }

    const carga_ListTree = async () => {

        const response = await Catalogo_Lista_Request(token, empresa, 0);
        let _lista = [];
        if (response.Exitoso) {
            const _listCuentas = response.Datos;
            const _listCuentasCont = llenadoListaArbol(_listCuentas);
            setListCuentas(_listCuentas);
            _lista = datosArbol(_listCuentasCont);
        }
        else {
            Notificacion.error(response.Mensaje);
            volverAtras();
        }

        return _lista;

    }

    const cargarCentrosDeCosto = async () => {

        let response = await CentroCosto_Lista_CCC_Request(token, empresa);

        if (response.Exitoso) {
            if (Array.isArray(response.Datos)) {
                setListCCosto(response.Datos);
            } else {
                Notificacion.error('No hay datos para: Centros de Costo.');
                volverAtras();
            }
        }
        else {
            Notificacion.error(response.Mensaje);
            volverAtras();
        }

        response = await CentroCosto_Lista_CXCCEmpresa_Request(token, empresa);

        if (response.Exitoso) {
            if (Array.isArray(response.Datos)) {
                setListCXCC(response.Datos);
            } else {
                Notificacion.error('No hay datos para: Centros de Costo.');
                volverAtras();
            }
        }
        else {
            Notificacion.error(response.Mensaje);
            volverAtras();
        }

    }

    const cargarDetallePlantilla = async (Plantilla, _Datos, ListaTipoAsiento) => {

        let response = await EncaPlantillas_Consultar_Request(token, Plantilla);

        if (response.Exitoso) {
            setPlantilla(response.Datos);

            setSelectedTipoAsiento(ListaTipoAsiento.filter(x => x.value === response.Datos.Tipo_Asiento)[0]);
            setSelectedTipoValor(response.Datos.Tipo.toString());
            setSelectedRecurrente(response.Datos.Recurrencia ? listaRecurrente[0].value : listaRecurrente[1].value);
            setSelectedEstado(response.Datos.Aprobado ? listaEstado[1] : listaEstado[0]);

            _Datos.FechaInicial.value = moment(response.Datos.FechaIni).toDate();
            _Datos.FechaFinal.value = moment(response.Datos.FechaFin).toDate();
            _Datos.Nombre.value = response.Datos.Nombre;
            _Datos.Descripcion.value = response.Datos.Descripcion;
            _Datos.Comentario.value = response.Datos.Comentario;

            if (response.Datos.Recurrencia) {
                _Datos.FechaInicial.attributes.readOnly = false;
                _Datos.FechaFinal.attributes.readOnly = false;
            }

            setDatos(_Datos);

        } else {
            Notificacion.error(response.Mensaje);
            volverAtras();
        }

        response = await DetallePlantillas_Listar_Request(token, Plantilla);

        if (response.Exitoso) {
            if (Array.isArray(response.Datos)) {
                let _lista = [...response.Datos];
                let _debe = 0;
                let _haber = 0;
                _lista.forEach((element, i) => {
                    element.llave = element.Linea.toString();
                    _debe = _debe + parseFloat(element.Debito);
                    _haber = _haber + parseFloat(element.Credito);
                });

                setTotalDebe(_debe);
                setTotalHaber(_haber);

                const item = {
                    Plantilla: 0,
                    Centro_Costo: 0,
                    Centro_CostoStr: "",
                    Cuenta: 0,
                    CuentaStr: "",
                    Debito: 0,
                    Fecha: null,
                    Fecha_Actualizacion: new Date("1900-01-01"),
                    Credito: 0,
                    Linea: _lista.length + 1,
                    Monto: 0,
                    MsgError: "",
                    NombreCuenta: "",
                    Documento: _lista.length === 0 ? "" : _lista[_lista.length - 1].Documento,
                    Descripcion: _lista.length === 0 ? Datos.Descripcion.value : _lista[_lista.length - 1].Descripcion,
                };

                _lista.push(item);

                setListaDatos(_lista);

            } else {
                Notificacion.error('No hay datos para: Plantilla Detalle.');
                volverAtras();
            }
        }
        else {
            Notificacion.error(response.Mensaje);
            volverAtras();
        }

    }

    const ingresarDetalle = (limpiar = false) => {

        let _listaDatos = limpiar ? [] : [].concat(listaDatos);

        let item = {
            Asiento: 0,
            Centro_Costo: 0,
            Centro_CostoStr: "",
            Credito: false,
            Cuenta: 0,
            CuentaStr: "",
            Credito: 0,
            Documento: _listaDatos.length === 0 ? "" : _listaDatos[_listaDatos.length - 1].Documento,
            Fecha: null,
            Fecha_Actualizacion: new Date("1900-01-01"),
            Debito: 0,
            Linea: (_listaDatos.length + 1),
            MsgError: "",
            NombreCuenta: "",
            Descripcion: _listaDatos.length === 0 ? Datos.Descripcion.value : _listaDatos[_listaDatos.length - 1].Descripcion,
        };

        _listaDatos.push(item);

        setListaDatos(_listaDatos);

    }

    const cargarDatosEmpresa = async () => {

        let Periodo = new Date();
        const response = await Empresa_Consulta_Request(token, empresa);

        if (response.Exitoso) {
            setDatosEmpresa(response.Datos);
            Periodo = moment(response.Datos.Periodo).toDate();
        } else {
            Notificacion.error(response.Mensaje);
            volverAtras();
        }

        return Periodo;

    }

    const cargarDatos = async (limpiar = false) => {
        let _Datos = { ...Datos }
        let Periodo = null;

        try {
            spinnerModalMostrar(true, 'Cargando Datos');
            const _id = parseInt(props.match.params.id);

            setId(_id);

            Periodo = await cargarDatosEmpresa();

            await cargarSeguridad();

            const _listCuentasContTemp = await carga_ListTree();

            setListCuentasCont(_listCuentasContTemp);

            await cargarCentrosDeCosto();

            if (_id > 0) {
                const _listaTipoAsiento = await cargarTiposAsiento(_Datos);
                await cargarDetallePlantilla(_id, _Datos, _listaTipoAsiento);
            } else {

                const _listaTipoAsiento = await cargarTiposAsiento(_Datos);
                ingresarDetalle(limpiar);

                _Datos.FechaInicial.value = moment().toDate();
                _Datos.FechaFinal.value = moment(Periodo).add(90, 'days').toDate();
                setDatos(_Datos);
            }

        } catch (ex) {
            Notificacion.error(ex.message);
        } finally {
            spinnerModalMostrar(false, '', 3);
        }

    }

    useEffect(() => {
        const carga = async () => {
            await cargarDatos()
        }
        carga()
    }, [])

    const handleSelectedTipoAsiento = (selTipoAsiento) => {
        setSelectedTipoAsiento(selTipoAsiento);
    }

    const handleSelectedEstado = (selEstado) => {
        setSelectedEstado(selEstado);
    }

    const onChangeInput = (e) => {

        const name = e.target.name;
        const value = e.target.value;

        let newAttributes = Datos[name].attributes;
        let _Datos = Object.assign({}, Datos, {
            [name]: { value: value, attributes: newAttributes },
        });

        if (name === 'Descripcion') {
            let _listaDatos = [].concat(listaDatos);
            if (_listaDatos.length === 1) {
                _listaDatos[0].Descripcion = value;
                setListaDatos(_listaDatos);
            }
        }

        setDatos(_Datos);

    }

    const onRowSelect = (row) => {
        setFilaSeleccionada(row);
    };

    const onRowSelectBusquedaTree = (row) => {
        setSelectedCuenta(row);
    }

    const onRowSelectBusqueda = (row) => {
        setSelectedCentroCosto(row);
    }

    const cerrarModalTree = () => {
        setIndexC(-1);
        setSelectModalTree(false);
    }

    const seleccionModalTree = async () => {

        if (!!selectedCuenta) {
            if (!selectedCuenta.node.children) {

                const listCCont = listCuentas.filter(item => item.ID == selectedCuenta.node.value);
                let _pColumn = { ...pColumn };

                _pColumn.Cuenta = listCCont[0].ID;
                _pColumn.CuentaStr = listCCont[0].Cuenta;
                _pColumn.NombreCuenta = listCCont[0].Nombre;

                spinnerModalMostrar(true, 'Cargando datos', 3);
                const response = await CentroCostos_CentroDefault_Request(token, empresa, _pColumn.Cuenta);
                spinnerModalMostrar(false, '', 3);

                let _listaDatos = [].concat(listaDatos);
                _listaDatos[indexC].Cuenta = _pColumn.Cuenta;
                _listaDatos[indexC].CuentaStr = _pColumn.CuentaStr;
                _listaDatos[indexC].NombreCuenta = _pColumn.NombreCuenta;

                if (response.Exitoso) {
                    _listaDatos[indexC].Centro_Costo = response.Datos.ID;
                    _listaDatos[indexC].Centro_CostoStr = response.Datos.CentroCosto;
                    _listaDatos[indexC].Centro_CostoNom = response.Datos.Nombre;
                }
                else {
                    Notificacion.error(response.Mensaje);
                }

                setListaDatos(_listaDatos);
                setActTabla(true);
                setSelectedCuenta(undefined);
                setSelectModalTree(false);
                setIndexC(-1);
                setPColumn(_pColumn);

            }
            else {
                Notificacion.error('La cuenta selccionada es padre.');
                setSelectModalTree(false);
                setSelectedCuenta(undefined);
            }
        }
        else {
            Notificacion.warning('Debe seleccionar un registro.');
        }
    }

    const selectRow = { onSelect: onRowSelect, hideSelectColumn: true, mode: "radio", clickToSelect: true, clickToEdit: true, bgColor: '#d73220' };

    const cellEdit = {
        mode: "click",
        blurToSave: true,
        autoSelectText: true,
        afterSaveCell: (oldValue, newValue, row, column) => {
            setTotalDebe(SumeMontos(true));
            setTotalHaber(SumeMontos(false));

            if (column.dataField === "Debito" || column.dataField === "Credito") {
                if (parseInt(listaDatos[listaDatos.length - 1].Debito) > 0 || parseInt(listaDatos[listaDatos.length - 1].Credito) > 0) {
                    ingresarDetalle();
                }
            }
        },
    };

    const seleccionModal = () => {

        if (!!selectedCentroCosto) {

            const listCCost = listCCosto.filter(item => item.ID == selectedCentroCosto.ID);

            let _listaDatos = [].concat(listaDatos);
            _listaDatos[indexCost].Centro_Costo = listCCost[0].ID;
            _listaDatos[indexCost].Centro_CostoStr = listCCost[0].CentroCosto;
            _listaDatos[indexCost].Centro_CostoNom = listCCost[0].Nombre;

            setListaDatos(_listaDatos);
            setSelectedCentroCosto(undefined);
            setSelectModal(false);
            setIndexCost(indexCost);

        }
        else {
            Notificacion.warning('Debe seleccionar un registro.');
        }
    }

    const handleChangeSearch = (event) => {

        let _listCentroCostoFiltro = listCentroCosto;
        _listCentroCostoFiltro = _listCentroCostoFiltro.filter(function (item) {
            return item.CentroCosto.toLowerCase().search(
                event.target.value.toLowerCase()) !== -1;
        });

        if (_listCentroCostoFiltro.length == 0) {
            _listCentroCostoFiltro = listCentroCosto;

            _listCentroCostoFiltro = _listCentroCostoFiltro.filter(function (item) {
                return item.Nombre.toLowerCase().search(
                    event.target.value.toLowerCase()) !== -1;
            });
        }

        setListCentroCostoFiltro(_listCentroCostoFiltro);

    }

    const rowStyleLista = (row, rowIndex) => {
        const style = {};
        if (row.DebeGuardar == -1) {
            style.color = '#21aba0';
        } else {
            style.color = 'black';
        }

        return style;
    }

    const SumeMontos = (Debe) => {

        let Result = parseFloat(0);

        for (let i = 0; i < listaDatos.length - 1; i++) {
            if (Debe)
                Result = Result + parseFloat(listaDatos[i].Debito);
            else
                Result = Result + parseFloat(listaDatos[i].Credito);
        }

        return Result;
    }

    const handleRadioButton = (e, id) => {
        const name = id;
        const valor = e.target.value;
        const _Datos = { ...Datos };

        switch (name) {
            case "selectedTipoValor":
                setSelectedTipoValor(valor);
                break;
            case "selectedRecurrente":
                setSelectedRecurrente(valor);

                if (valor === "S") {
                    _Datos.FechaInicial.attributes.readOnly = false;
                    _Datos.FechaFinal.attributes.readOnly = false;
                } else {
                    _Datos.FechaInicial.attributes.readOnly = true;
                    _Datos.FechaFinal.attributes.readOnly = true;
                }

                setDatos(_Datos);

                break;
            default:
                break;
        }

    };

    const onhandleChangeDate = (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);

    }

    return (<Fragment>
        <MantPlantillasInt
            titulo={id === 0 ? 'Agregar plantilla' : 'Modificar plantilla'}
            botones={botones}
            handleSelectedTipoAsiento={handleSelectedTipoAsiento}
            selectedTipoAsiento={selectedTipoAsiento}
            listaTipoAsiento={listaTipoAsiento}
            Datos={Datos}
            onChangeInput={onChangeInput}
            listaDatos={listaDatos}
            columnas={columnas}
            selectRow={selectRow}
            cellEdit={cellEdit}
            actTabla={actTabla}
            rowStyleLista={rowStyleLista}
            pColumn={pColumn}
            listaEstado={listaEstado}
            selectedEstado={selectedEstado}
            handleSelectedEstado={handleSelectedEstado}
            listaTipoValor={listaTipoValor}
            selectedTipoValor={selectedTipoValor}
            handleRadioButton={handleRadioButton}
            onhandleChangeDate={onhandleChangeDate}
            selectedRecurrente={selectedRecurrente}
            listaRecurrente={listaRecurrente}
        />
        <BotonArriba Delay={10} Visible={100} />
        <ModalSpinner
            selectedModal={SpinnerModal.mostrar}
            contentLabel={'spinnerModalProgress'}
            label={SpinnerModal.texto}
            tipoSpinner={SpinnerModal.tipo}
        />
        <ModalSeguridad
            modalTitle={'Requiere Permisos'}
            menuId={menuId}
            opcionId={opcionValidar}
            show={showModalSeguridad}
            onActionResult={onActionResultModal}
            onHide={handleCerrarModal}
        />
        <ModalBusqueda
            selectedModal={selectModal}
            contentLabel={'selectedBusquedas'}
            listaFiltro={listCentroCostoFiltro}
            columnas={Header}
            keyRow={'ID'}
            label={'Lista de Centros de Costos Asociados'}
            onSelectedRow={onRowSelectBusqueda}
            handleChangeSearch={handleChangeSearch}
            cerrarModal={cerrarModal}
            seleccionModal={seleccionModal}
            rowsSelected={rowsSelected}
        />
        <ModalBusquedaTree
            selectedModal={selectModalTree}
            contentLabel={'selectedBusquedasTree'}
            label={'Catálogo'}
            onSelectedRow={onRowSelectBusquedaTree}
            cerrarModal={cerrarModalTree}
            seleccionModal={seleccionModalTree}
            maxDepth={5}
            carga_ListTree={() => { }}
            listatree={listCuentasCont}
        />
    </Fragment>)

}
export default withRouter(memo(MantPlantillas));