import { Fragment, memo, useState, useEffect, useRef } from 'react';
import React from 'react';
import { faReply, faSave } from '@fortawesome/free-solid-svg-icons';
import { useSessionStorage } from '../../../components/Util/Hooks/useSessionStorage.jsx';
import ModalSpinner from '../../../components/UI/modalSpinner/modalSpinner.jsx';
import ModalSeguridad from '../../Seguridad/ModalSeguridad.jsx';
import optSeg from '../../../components/Util/seg-menu-opciones.js';
import MantCentrosCostosInt from './MantCentrosCostosInt.jsx';
import { withRouter, useHistory } from 'react-router-dom';
import { CentrosCostos_Listar_Request, DetalleCentroCostos_Listar_Request, CentrosCost_Guardar_Request, CentrosCost_Modificar_Request, DetalleCentroCostos_GuardarLista_Request, DetalleCentroCostos_Eliminar_Request } from '../../../request/MantenimientosRequest.jsx';
import { SiteRutas } from '../../../request/RutasConfig.jsx';
import Config from '../../../components/Util/constantes.js';
import { Obtener_MenuOpciones_Lista_Request, Obtener_MenuNombre_Request } from "../../../request/MenuRequest.jsx"
import Swal from 'sweetalert2';
import { Notificacion } from '../../../components/Util/Notificacion/Notificacion.jsx';
import { Catalogo_Lista_Tipos_Request } from '../../../request/ServicioRequest.jsx';
import { datosArbolCheck } from '../../../components/Util/Util.jsx';
import moment from 'moment/moment.js';

export function MantCentrosCostos(props) {

    let historyMenu = useHistory();

    const listaDatosDet = {
        Numero: { value: 0, attributes: { readOnly: true, focus: false, label: "Número", hidden: "unset" }, },
        Nombre: { value: "", attributes: { readOnly: false, focus: false, label: "Nombre", hidden: "unset", maxLength: "50" }, },
        Titulo: { value: "", attributes: { readOnly: false, focus: false, label: 'Título para asiento contable', hidden: "unset", } },
        Descripcion: { value: "", attributes: { readOnly: false, focus: false, label: 'Descripción', hidden: "unset", maxLength: "255" } },
    }

    const mounted = useRef();
    const [menuId, setMenuId] = useState(0);
    const [Id, setId] = useState(0);
    const [Datosdet, setDatosdet] = useState(listaDatosDet);
    const [menuOpciones, setMenuOpciones] = useState([]);
    const [opcionValidar, setOpcionValidar] = useState(0);
    const [Pais, setPais] = useSessionStorage('paisCON');
    const [token, setToken] = useSessionStorage('tokenCON', '');
    const [usuario, setUsuario] = useSessionStorage('usuarioCON');
    const [empresa, setEmpresa] = useSessionStorage('empresaCON', 0);
    const [empresaNombre, setEmpresaNombre] = useSessionStorage('empresaNombreCON');
    const [usuarioS, setUsuarioS] = useSessionStorage('UsuarioSCON');
    const [opcionValidarNombre, setOpcionValidarNombre] = useState('');
    const [showModalSeguridad, setShowModalSeguridad] = useState(false);

    const [listCuentasCont, setListCuentasCont] = useState([]);
    const [listChecked, setListChecked] = useState([]);
    const [listExpanded, setListExpanded] = useState(["0"])

    const [spinnerTipo, setSpinnerTipo] = useState(1);
    const [spinnerLabel, setSpinnerLabel] = useState('');
    const [spinnerModal, setSpinnerModal] = useState(undefined);

    const botones = [
        {
            name: "btnHomeC",
            clase: "btn btn-sm pull-right flipInX animated",
            evento: () => volverAtras(),
            leyenda: "",
            iclase: faReply,
            tooltip: "Volver"
        },
        {
            name: "btnGuardarC",
            clase: "btn btn-sm pull-right flipInX animated",
            evento: () => EditarGuardarCC(),
            leyenda: "",
            iclase: faSave,
            tooltip: "Guardar"
        },
    ];

    const validaDatos = () => {

        if (Datosdet.Nombre.value.toString().trim() === "") {
            Notificacion.warning("Debe ingresar un nombre para el centro de costo.");
            return;
        }

        if (Datosdet.Titulo.value.toString().trim() === "") {
            Notificacion.warning("Debe ingresar un titulo para el centro de costo.");
            return;
        }

        return true;
    };

    useEffect(() => {

        if (!mounted.current) {
            const carga = async () => {
                await cargarDatos()
            }
            carga();

            mounted.current = true;
        }

    }, []);

    const cargarDatos = async () => {

        let spinnerLabel = "Cargando Datos...", arrayChecked = [];
        spinnerModalMostrar(true, spinnerLabel, 3);

        await cargarSeguridad();

        let CentroCostosID = parseInt(props.match.params.id);

        if (CentroCostosID > 0) {

            const responseCentrosCosto = await CentrosCostos_Listar_Request(token, empresa, CentroCostosID, 0, 0);

            if (responseCentrosCosto.Exitoso) {

                if (responseCentrosCosto.Datos[0].ID > 0 && responseCentrosCosto.Datos[0].Empresa > 0) {

                    let datos = Datosdet;

                    datos.Numero.value = CentroCostosID;
                    datos.Nombre.value = responseCentrosCosto.Datos[0].Nombre;
                    datos.Titulo.value = responseCentrosCosto.Datos[0].Titulo;
                    datos.Descripcion.value = responseCentrosCosto.Datos[0].Descripcion;

                    setDatosdet(datos);

                } else {
                    Notificacion.error("No se encontró el centro de costo indicado.");
                    volverAtras();
                    return;
                }

            } else {
                Notificacion.error("Sucedió un error al consultar el centro de costo.");
                volverAtras();
                return;
            }

            const responseDetalleCC = await DetalleCentroCostos_Listar_Request(token, CentroCostosID, 0);

            if (responseDetalleCC.Exitoso) {

                if (responseDetalleCC.Datos.length > 1) {
                    for (let i in responseDetalleCC.Datos) {
                        arrayChecked.push(responseDetalleCC.Datos[i].Cuenta);
                    }
                } else {
                    if (responseDetalleCC.Datos[0].Cuenta > 0 && responseDetalleCC.Datos[0].Centro > 0) {
                        for (let i in responseDetalleCC.Datos) {
                            arrayChecked.push(responseDetalleCC.Datos[i].Cuenta);
                        }
                    }
                }

            } else {
                Notificacion.error("Sucedió un error al consultar el detalle del centro de costo.");
                volverAtras();
                return;
            }

        } else {

        }

        const _ListCuentasCont = await carga_ListTree();
        setListChecked(arrayChecked);
        setListCuentasCont(_ListCuentasCont);

        setId(CentroCostosID);
        spinnerModalMostrar(false, '', 3);

    }

    const carga_ListTree = async () => {

        const conjunto = `${Config.tcEgresos}, ${Config.tcCostos}`;

        const response = await Catalogo_Lista_Tipos_Request(token, empresa, conjunto);
        let _lista = [];
        if (response.Exitoso) {

            const _listCuentasCont = llenadoListaArbol(response.Datos);
            _lista = datosArbolCheck(_listCuentasCont, false);

            const nodos = getNodeIds(_lista);

            setListExpanded(nodos);
        }
        else {
            Notificacion.error(response.Mensaje);
            volverAtras();
        }

        return _lista;

    }

    function getNodeIds(nodes) {
        let ids = [];
        let vuelta = 0;

        if (nodes !== undefined) {
            nodes.forEach(({ value, children }) => {
                ids = [...ids, value, ...getNodeIds(children)];
            });
        }

        return ids;
    }

    const llenadoListaArbol = (pLista) => {
        let _Datos = [];
        const _Lista = pLista;
        _Datos.push({ "title": empresaNombre, "subtitle": "", "padre": -1, "value": 0, "disabled": "true" });

        _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 cargarSeguridad = async () => {
        const _MenuNomb = await cargarMenuNombre(Config.Modulo, optSeg.TMenuSistema.CentrosdeCosto.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 volverAtras = () => {
        historyMenu.push(SiteRutas.CentrosCosto);
    }

    const onActionResultModal = (pValido) => {
        if (pValido) {
            let _OpcionNom = opcionValidarNombre;
            setShowModalSeguridad(false); setOpcionValidar(0); setOpcionValidarNombre('');
            const _optSegopt = optSeg.TOpciones_Menu;
            switch (_OpcionNom) {
                case _optSegopt.Editar.value:
                    finalizaEditarGuardar();
                    break;
                case _optSegopt.Nuevo.value:
                    finalizaEditarGuardar();
                    break;
                default:
                    break;
            }
        }
    }

    const handleCerrarModal = () => setShowModalSeguridad(false);

    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 confirmEliminarCentro = async () => {

        let resultado = false;
        Swal.fire({
            title: 'Atención',
            html: '<h4>¿Está seguro de querer borrar el Centro de Costos?</h4>',
            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;

            } else if (result.dismiss === Swal.DismissReason.cancel) {
                resultado = false;
            }
        });

    }

    const finalizaEditarGuardar = async () => {

        let spinnerLabel = Id > 0 ? "Actualizando Datos..." : "Guardando Datos...";
        spinnerModalMostrar(true, spinnerLabel, 3);
        let listaCheck = listChecked, listaCuentas = [];

        let item = generarItem();

        item.Empresa = empresa;
        item.Usuario_Modifica = usuario;
        item.Nombre = Datosdet.Nombre.value;
        item.Titulo = Datosdet.Titulo.value;
        item.Descripcion = Datosdet.Descripcion.value;

        if (Id > 0) {

            item.ID = Id;

            const responseEditar = await CentrosCost_Modificar_Request(token, item);

            if (responseEditar.Exitoso) {

                //Eliminar
                const responseElimina = await DetalleCentroCostos_Eliminar_Request(token, item.ID, 0);

                if (responseElimina.Exitoso) {

                    //Guardar Lista
                    if (listaCheck.length > 0) {

                        for (let i in listaCheck) {

                            let itemCuenta = generarItemCuentas();

                            itemCuenta.Centro = item.ID;
                            itemCuenta.Cuenta = listaCheck[i];

                            listaCuentas.push(itemCuenta)

                        }

                        const responseInsCuentas = await DetalleCentroCostos_GuardarLista_Request(token, listaCuentas);

                        if (responseInsCuentas.Exitoso) {
                            Notificacion.success("Se ha actualizado el centro de costos exitosamente.");
                            volverAtras();
                            return;
                        } else {
                            Notificacion.error("Sucedió un error al actualizar el detalle del centro de costos.");
                            volverAtras();
                            return;
                        }

                    } else {
                        Notificacion.success("Se ha actualizado el centro de costos exitosamente.");
                        volverAtras();
                        return;
                    }

                } else {
                    Notificacion.error("Sucedió un error al modificar el detalle del centro de costos.");
                    volverAtras();
                    return;
                }

            } else {
                Notificacion.error("Sucedió un error al modificar el centro de costo.");
                volverAtras();
                return;
            }

        } else {

            const responseGuardar = await CentrosCost_Guardar_Request(token, item, Config.ncCentroCosto);

            if (!responseGuardar.Exitoso) {

                if (isNaN(responseGuardar.Mensaje)) {
                    Notificacion.error("Sucedió un error al guardar el centro de costo.");
                    volverAtras();
                    return;
                } else {

                    const idGuardado = responseGuardar.Mensaje;

                    if (listaCheck.length > 0) {

                        for (let i in listaCheck) {

                            let itemCuenta = generarItemCuentas();

                            itemCuenta.Centro = idGuardado;
                            itemCuenta.Cuenta = listaCheck[i];

                            listaCuentas.push(itemCuenta)

                        }

                        const responseInsCuentas = await DetalleCentroCostos_GuardarLista_Request(token, listaCuentas);

                        if (responseInsCuentas.Exitoso) {
                            Notificacion.success("Se ha creado el centro de costos exitosamente.");
                            volverAtras();
                            return;
                        } else {
                            Notificacion.error("Sucedió un error al guardar el detalle del centro de costos.");
                        }

                    } else {
                        Notificacion.success("Se ha creado el centro de costos exitosamente.");
                        volverAtras();
                    }

                }

            }

        }

        spinnerModalMostrar(false, '', 3);

    }

    const generarItem = () => {

        return {
            ID: 0,
            Empresa: 0,
            Numero: 0,
            Nombre: "",
            Titulo: "",
            Descripcion: "",
            Fecha_Actualizacion: moment("1900-01-01").format("YYYY/MM/DD"),
            Usuario_Modifica: "",
            Usuario_Fecha_Actualiza: moment("1900-01-01").format("YYYY/MM/DD"),
        };

    };

    const generarItemCuentas = () => {

        return {
            Centro: 0,
            Cuenta: 0,
            Fecha_Actualizacion: moment("1900-01-01").format("YYYY/MM/DD"),
        };

    };

    const spinnerModalMostrar = (pSpinnerModal, pSpinnerLabel, pSpinnerTipo) => {
        setSpinnerModal(pSpinnerModal);
        setSpinnerLabel(pSpinnerLabel);
        setSpinnerTipo(pSpinnerTipo);
    }

    const EditarGuardarCC = () => {

        if (validaDatos()) {

            const optSegopt = optSeg.TOpciones_Menu;
            const _value = Id > 0 ? optSegopt.Editar.value : optSegopt.Nuevo.value;

            let validar = validarMenuOpcion(_value);

            if (!validar) {
                confirmEliminarCentro();
            }


        }

    }

    const onChangeInput = (e) => {
        const name = e.target.name;
        const value = e.target.value;

        let newAttributes = Datosdet[name].attributes;

        //newAttributes.focus = true; //Se asigna foco al componente
        const datos = Object.assign({}, Datosdet, { [name]: { value: value, attributes: newAttributes } });

        setDatosdet(datos);
    };

    const handleCheck = (pCheck, targetNode) => {

        setListChecked(pCheck);
    }

    const handelExp = (pCheck) => {
        setListExpanded(pCheck);
    }

    return (
        <Fragment>

            <MantCentrosCostosInt
                titulo={"Detalle Centros Costos"}
                botones={botones}
                Datos={Datosdet}
                onChangeInput={onChangeInput}

                listCuentasCont={listCuentasCont}
                listChecked={listChecked}
                listExpanded={listExpanded}
                handleCheck={handleCheck}
                handelExp={handelExp}
            />

            <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(MantCentrosCostos))