using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Exferia_Aplicacion.Visualizacion;
using Exferia_Aplicacion.General;
using System.Reflection;
using Exferia_EntityFramework;
using System.Threading;
using Exferia_General;

namespace Exferia_Controles.ControlesAuxiliares
{
    public partial class CTU_Contabilidad_InmovilizadoHistoricoAmortizaciones : UserControl
    {
        #region Variables Privadas
        private BackgroundWorker g_obj_TareaAsincrona_Rellenar_Datos = null;
        private System.Windows.Forms.Timer g_timer_TareaAsincrona_Rellenar_Datos = new System.Windows.Forms.Timer();
        private List<long> g_lst_TareaAsincrona_Rellenar_Datos_LLAMADAS = new List<long>();

        private long g_lng_Idinmovilizado = -1;

        //Llamar al Progress
        private int g_int_TotalRegistrosInsertados = 0;

        private INTERNO_ValoresGenerales_Modelo g_mdl_INTERNO_ValoresGenerales_Modelo = null;
        private DateTime g_dtt_FechaTrabajo;
        #endregion


        #region Constructor
        public CTU_Contabilidad_InmovilizadoHistoricoAmortizaciones()
        {
            InitializeComponent();

            Repintar.Empezar(this);

            Timer_Crear();
        }


        #endregion

        private void CTU_Contabilidad_InmovilizadoHistoricoAmortizaciones_Load(object sender, EventArgs e)
        {
            
        }

        #region Timers
        private void Timer_Crear()
        {
            g_timer_TareaAsincrona_Rellenar_Datos.Interval = 500;
            g_timer_TareaAsincrona_Rellenar_Datos.Tick += delegate (object s, EventArgs ee)
            {
                g_timer_TareaAsincrona_Rellenar_Datos.Stop();

                if (g_lst_TareaAsincrona_Rellenar_Datos_LLAMADAS.Count > 0)
                {
                    try
                    {
                        //Borro el Listado
                        g_lst_TareaAsincrona_Rellenar_Datos_LLAMADAS.Clear();

                        if (g_obj_TareaAsincrona_Rellenar_Datos!=null)
                        {
                            g_obj_TareaAsincrona_Rellenar_Datos.CancelAsync();
                            while (g_obj_TareaAsincrona_Rellenar_Datos.IsBusy)
                            {
                                Application.DoEvents();
                            }
                        }
                        else
                        {
                            g_obj_TareaAsincrona_Rellenar_Datos = new BackgroundWorker();
                            g_obj_TareaAsincrona_Rellenar_Datos.DoWork += new DoWorkEventHandler(TareaAsincrona_Rellenar_Datos_DoWork);
                            g_obj_TareaAsincrona_Rellenar_Datos.ProgressChanged += new ProgressChangedEventHandler(TareaAsincrona_Rellenar_Datos_ProgressChanged);
                            g_obj_TareaAsincrona_Rellenar_Datos.RunWorkerCompleted += new RunWorkerCompletedEventHandler(TareaAsincrona_Rellenar_Datos_Completed);
                            g_obj_TareaAsincrona_Rellenar_Datos.WorkerReportsProgress = true;
                            g_obj_TareaAsincrona_Rellenar_Datos.WorkerSupportsCancellation = true;
                        }

                        //Vaciar Listado
                        ex_dgv_Historico.Rows.Clear();

                        //Vaciar barra de Progreso
                        g_int_TotalRegistrosInsertados = 0;
                        ex_pgb_BarraProgreso.Exferia_BarraProgreso_Total = 0;
                        ex_pgb_BarraProgreso.Exferia_BarraProgreso_Actualizar = 0;

                        //Mostrar cartel de cargnado
                        ex_lbl_Cargando.Visible = true;
                        ex_lbl_Cargando.BringToFront();

                        //Empezar tareaAsincrona
                        g_obj_TareaAsincrona_Rellenar_Datos.RunWorkerAsync();
                    }
                    catch (Exception ex)
                    {
                        Control_Errores.Errores_Log("", ex, nameof(CTU_Contabilidad_InmovilizadoHistoricoAmortizaciones) + "/" + nameof(Timer_Crear));
                        ex_lbl_Cargando.Visible = false;
                    }
                }
            };
        }
        #endregion

        public void Cargar_DatosAuxiliares(INTERNO_ValoresGenerales_Modelo _mdl_INTERNO_ValoresGenerales_Modelo, DateTime _dtt_FechaTrabajo)
        {
            g_mdl_INTERNO_ValoresGenerales_Modelo = _mdl_INTERNO_ValoresGenerales_Modelo;
            g_dtt_FechaTrabajo = _dtt_FechaTrabajo;
        }
        public void Recargar_Datos(long _lng_idInmovilizado)
        {
            g_lng_Idinmovilizado = _lng_idInmovilizado;
            if (g_lng_Idinmovilizado > -1)
            {
                Rellenar_Listado();
            }
            else
            {
                Vaciar_Datos();
            }
        }

        public void Vaciar_Datos()
        {
            try
            {
                if (g_obj_TareaAsincrona_Rellenar_Datos != null)
                {
                    g_obj_TareaAsincrona_Rellenar_Datos.CancelAsync();
                    while (g_obj_TareaAsincrona_Rellenar_Datos.IsBusy)
                    {
                        Application.DoEvents();
                    }
                }

                //Vaciar Listado
                ex_dgv_Historico.Rows.Clear();

                //Vaciar barra de Progreso
                g_int_TotalRegistrosInsertados = 0;
                ex_pgb_BarraProgreso.Exferia_BarraProgreso_Total = 0;
                ex_pgb_BarraProgreso.Exferia_BarraProgreso_Actualizar = 0;
            }
            catch (Exception ex)
            {
                Control_Errores.Errores_Log("", ex, nameof(CTU_Contabilidad_InmovilizadoHistoricoAmortizaciones) + "/" + nameof(Vaciar_Datos));
            }
        }

        #region Rellenar DataaGridView
        private void Rellenar_Listado()
        {
            try
            {
                g_lst_TareaAsincrona_Rellenar_Datos_LLAMADAS.Add(DateTime.Now.Ticks);

                //Arranco el timer
                g_timer_TareaAsincrona_Rellenar_Datos.Start();
            }
            catch (Exception ex)
            {
                Control_Errores.Errores_Log("", ex, nameof(CTU_Contabilidad_Saldo) + "/" + nameof(Rellenar_Listado));
                ex_lbl_Cargando.Visible = false;
            }
        }
        protected void TareaAsincrona_Rellenar_Datos_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                #region Modelo de Inmovilizado
                //Cargamos el ensamblado
                Assembly obj_assembly = Assembly.LoadFrom(Variables.G_STR_LIBRERIA_RUTAINICIAL + @"\" + Variables.G_STR_LIBRERIA_CONTABILIDAD + ".dll");
                //Obtenemos el tipo de la clase
                Type obj_type = obj_assembly.GetType(Variables.G_STR_LIBRERIA_CONTABILIDAD + "." + Variables.G_STR_LIBRERIA_DATOSCONTABILIDAD);
                //creamos la instancia
                var obj_clase = Activator.CreateInstance(obj_type);
                //Cargamos el metodo solicitado
                MethodInfo m = obj_clase.GetType().GetMethod(Variables.G_STR_LIBRERIA_DATOSCONTABILIDAD_PROCEDIMIENTO_CTAINMOVILIZADOS_OBTENERMODELO_POR_ID, BindingFlags.Instance | BindingFlags.NonPublic);

                object[] arr_parametros = { g_lng_Idinmovilizado };

                //Pasamos los parametros al metodo y lo ejecutamos
                CTA_Inmovilizados mdl_CTA_Inmovilizados = (CTA_Inmovilizados)m.Invoke(obj_clase, arr_parametros);
                #endregion

                if (mdl_CTA_Inmovilizados != null)
                {
                    #region Listado de amortizaciones
                    //Cargamos el ensamblado
                    Assembly obj_assembly_2 = Assembly.LoadFrom(Variables.G_STR_LIBRERIA_RUTAINICIAL + @"\" + Variables.G_STR_LIBRERIA_CONTABILIDAD + ".dll");
                    //Obtenemos el tipo de la clase
                    Type obj_type_2 = obj_assembly_2.GetType(Variables.G_STR_LIBRERIA_CONTABILIDAD + "." + Variables.G_STR_LIBRERIA_DATOSCONTABILIDAD);
                    //creamos la instancia
                    var obj_clase_2 = Activator.CreateInstance(obj_type_2);
                    //Cargamos el metodo solicitado
                    MethodInfo m_2 = obj_clase_2.GetType().GetMethod(Variables.G_STR_LIBRERIA_DATOSCONTABILIDAD_PROCEDIMIENTO_CTAAMORTIZACIONESLINEA_OBTENERMODELO_POR_IDINMOVILIZADO_AUX_1, BindingFlags.Instance | BindingFlags.NonPublic);

                    object[] arr_parametros_2 = { g_lng_Idinmovilizado,
                                            true,
                                            true };

                    //Pasamos los parametros al metodo y lo ejecutamos
                    List<CTA_AmortizacionesLinea> lst_CTA_AmortizacionesLinea = (List<CTA_AmortizacionesLinea>)m_2.Invoke(obj_clase_2, arr_parametros_2);
                    #endregion

                    //Total de registros
                    int int_TotalRegistros = 3 + (lst_CTA_AmortizacionesLinea!=null ? lst_CTA_AmortizacionesLinea.Count : 0);

                    //VALOR
                    g_int_TotalRegistrosInsertados += 1;
                    ((BackgroundWorker)sender).ReportProgress(1, Transformar_Modelo_A_Row_Otros(mdl_CTA_Inmovilizados,1));

                    //AMORTIZACION ALTA
                    g_int_TotalRegistrosInsertados += 1;
                    ((BackgroundWorker)sender).ReportProgress(1, Transformar_Modelo_A_Row_Otros(mdl_CTA_Inmovilizados, 2));

                    //Totales
                    decimal dcm_Total_Amortizado = mdl_CTA_Inmovilizados.importeAmortizadoEnAlta;
                    decimal dcm_Total_Pendiente = mdl_CTA_Inmovilizados.importeAmortizable - mdl_CTA_Inmovilizados.importeAmortizadoEnAlta;
                    int int_TotalDias= 0;

                    if (lst_CTA_AmortizacionesLinea != null && lst_CTA_AmortizacionesLinea.Count > 0)
                    {
                        int int_Dias = 0;
                         foreach (CTA_AmortizacionesLinea mdl_CTA_AmortizacionesLinea in lst_CTA_AmortizacionesLinea)
                        {
                            //Aumentar Total
                            g_int_TotalRegistrosInsertados += 1;

                            //Dias
                            TimeSpan obj_TimeSpan_fechas = mdl_CTA_AmortizacionesLinea.fechaCalculoFin - mdl_CTA_AmortizacionesLinea.fechaCalculoInicio;
                            int_Dias=obj_TimeSpan_fechas.Days + 1;

                            //Añadir al DataGridView
                            ((BackgroundWorker)sender).ReportProgress(1, Transformar_Modelo_A_Row(mdl_CTA_AmortizacionesLinea, dcm_Total_Pendiente, int_Dias));

                            //Se Cancelo la tarea asincrona #########################
                            if (((BackgroundWorker)sender).CancellationPending)
                            {
                                e.Cancel = true;
                                return;
                            }

                            //Esperar un poco
                            Thread.Sleep(1);

                            //Totales
                            dcm_Total_Pendiente -= mdl_CTA_AmortizacionesLinea.importeAmortizar;
                            dcm_Total_Amortizado+= mdl_CTA_AmortizacionesLinea.importeAmortizar;
                            int_TotalDias += int_Dias;
                        }
         
                    }

                    //Total Final
                    g_int_TotalRegistrosInsertados += 1;
                    ((BackgroundWorker)sender).ReportProgress(1, Transformar_Modelo_A_Row_Totales(int_TotalDias,mdl_CTA_Inmovilizados.importeAmortizable,dcm_Total_Amortizado, dcm_Total_Pendiente));
                    
                }
            }
            catch (ThreadAbortException)
            {
                e.Cancel = true;
            }
            catch (Exception)
            {
                e.Cancel = true;
            }
        }
        private void TareaAsincrona_Rellenar_Datos_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            try
            {
                ex_dgv_Historico.Rows.Add((DataGridViewRow)e.UserState);

                ex_pgb_BarraProgreso.Exferia_BarraProgreso_Actualizar = g_int_TotalRegistrosInsertados;

                if (ex_lbl_Cargando.Visible)
                {
                    ex_lbl_Cargando.Visible = false;
                }
            }
            catch (Exception)
            { }
        }
        protected void TareaAsincrona_Rellenar_Datos_Completed(object sender, RunWorkerCompletedEventArgs e)
        {
            ex_lbl_Cargando.Visible = false;
        }


        private DataGridViewRow Transformar_Modelo_A_Row_Otros(CTA_Inmovilizados _mdl_CTA_Inmovilizados, int _int_Tipo)
        {
            DataGridViewRow obj_DataGridViewRow = (DataGridViewRow)ex_dgv_Historico.RowTemplate.Clone();
            obj_DataGridViewRow.CreateCells(ex_dgv_Historico);

            //Valor
            if (_int_Tipo==1)
            {
                obj_DataGridViewRow.Cells[0].Value = -1;
                obj_DataGridViewRow.Cells[2].Value = "VALOR";
                obj_DataGridViewRow.Cells[3].Value = "";
                obj_DataGridViewRow.Cells[4].Value = "";
                obj_DataGridViewRow.Cells[5].Value = "";
                obj_DataGridViewRow.Cells[6].Value = "";
                obj_DataGridViewRow.Cells[7].Value = string.Format("{0:0.00}", _mdl_CTA_Inmovilizados.importeAmortizable);
                obj_DataGridViewRow.Cells[8].Value = "";
                obj_DataGridViewRow.Cells[9].Value = "";
            }
            //Amortizacion Alta
            else
            {
                obj_DataGridViewRow.Cells[0].Value = -1;
                obj_DataGridViewRow.Cells[2].Value = "Amortizado en ALTA";
                obj_DataGridViewRow.Cells[3].Value = "";
                obj_DataGridViewRow.Cells[4].Value = "";
                obj_DataGridViewRow.Cells[5].Value = "";
                obj_DataGridViewRow.Cells[6].Value = "";
                obj_DataGridViewRow.Cells[7].Value = "";
                obj_DataGridViewRow.Cells[8].Value = string.Format("{0:0.00}", _mdl_CTA_Inmovilizados.importeAmortizadoEnAlta);
                obj_DataGridViewRow.Cells[9].Value = string.Format("{0:0.00}", (_mdl_CTA_Inmovilizados.importeAmortizable - _mdl_CTA_Inmovilizados.importeAmortizadoEnAlta));
            }
            
            return obj_DataGridViewRow;
        }

        private DataGridViewRow Transformar_Modelo_A_Row(CTA_AmortizacionesLinea _mdl_CTA_AmortizacionesLinea,decimal _dcm_Pendiente,int _int_Dias)
        {
            DataGridViewRow obj_DataGridViewRow = (DataGridViewRow)ex_dgv_Historico.RowTemplate.Clone();
            obj_DataGridViewRow.CreateCells(ex_dgv_Historico);

            obj_DataGridViewRow.Cells[0].Value = _mdl_CTA_AmortizacionesLinea.idAmortizacionCabecera;
            obj_DataGridViewRow.Cells[2].Value = "Amortización " + _mdl_CTA_AmortizacionesLinea.CTA_AmortizacionesCabecera.numeroDocumento;
            obj_DataGridViewRow.Cells[3].Value = _mdl_CTA_AmortizacionesLinea.fechaCalculoInicio.ToString("dd/MM/yyyy");
            obj_DataGridViewRow.Cells[4].Value = _mdl_CTA_AmortizacionesLinea.fechaCalculoFin.ToString("dd/MM/yyyy");
            obj_DataGridViewRow.Cells[5].Value = _int_Dias.ToString();
            obj_DataGridViewRow.Cells[6].Value = string.Format("{0:0.00}", _mdl_CTA_AmortizacionesLinea.tipoAmortizacion);
            obj_DataGridViewRow.Cells[7].Value = "";
            obj_DataGridViewRow.Cells[8].Value = string.Format("{0:0.00}", _mdl_CTA_AmortizacionesLinea.importeAmortizar);
            obj_DataGridViewRow.Cells[9].Value = string.Format("{0:0.00}", (_dcm_Pendiente - _mdl_CTA_AmortizacionesLinea.importeAmortizar));

            return obj_DataGridViewRow;
        }

        
        private DataGridViewRow Transformar_Modelo_A_Row_Totales(int _int_Dias,decimal _dcm_Valor, decimal _dcm_Amortizado,decimal _dcm_Pendiente)
        {
            DataGridViewRow obj_DataGridViewRow = (DataGridViewRow)ex_dgv_Historico.RowTemplate.Clone();
            obj_DataGridViewRow.CreateCells(ex_dgv_Historico);

            obj_DataGridViewRow.Cells[0].Value = -2;
            obj_DataGridViewRow.Cells[2].Value = "TOTALES";
            obj_DataGridViewRow.Cells[3].Value = "";
            obj_DataGridViewRow.Cells[4].Value = "";
            obj_DataGridViewRow.Cells[5].Value = _int_Dias.ToString();
            obj_DataGridViewRow.Cells[6].Value = "";
            obj_DataGridViewRow.Cells[7].Value = string.Format("{0:0.00}", _dcm_Valor);
            obj_DataGridViewRow.Cells[8].Value = string.Format("{0:0.00}", _dcm_Amortizado);
            obj_DataGridViewRow.Cells[9].Value = string.Format("{0:0.00}", _dcm_Pendiente);

            return obj_DataGridViewRow;
        }
        #endregion

        #region Eventos DataGridView
        private void ex_dgv_Historico_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            if (e.ColumnIndex == 5 && ex_dgv_Historico[0, e.RowIndex].Value.ToString() == "-2")
            {
                //Alineado
                e.CellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
                e.CellStyle.Font = new Font(e.CellStyle.Font, FontStyle.Bold);

                //Colores
                ex_dgv_Historico.Rows[e.RowIndex].DefaultCellStyle.BackColor = Colores.G_COLOR_LISTADO_TOTALES_FONDO;
                ex_dgv_Historico.Rows[e.RowIndex].DefaultCellStyle.SelectionBackColor = Colores.G_COLOR_LISTADO_TOTALES_FONDO;
                ex_dgv_Historico.Rows[e.RowIndex].DefaultCellStyle.ForeColor = Colores.G_COLOR_LISTADO_TOTALES_LETRA;
                ex_dgv_Historico.Rows[e.RowIndex].DefaultCellStyle.SelectionForeColor = Colores.G_COLOR_LISTADO_TOTALES_LETRA;
            }
        }

        private void ex_dgv_Historico_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                if (ex_dgv_Historico.Columns[e.ColumnIndex].Name == "VerAmortizacion")
                {
                    if (ex_dgv_Historico[0, e.RowIndex].Value != null &&
                        !ex_dgv_Historico[0, e.RowIndex].Value.ToString().Equals("-1") &&
                        !ex_dgv_Historico[0, e.RowIndex].Value.ToString().Equals("-2"))
                    {
                        

                        INTERNO_OpcionesDetalle_Modelo mdl_INTERNO_OpcionesDetalle_Modelo = Datos_Generales.PRV_Opciones_Buscar_Detalles(Variables.G_STR_OPCION_CTA_AMORTIZACIONESCABECERA);

                        //Cargamos el ensamblado
                        Assembly m_assembly = Assembly.LoadFrom(Variables.G_STR_LIBRERIA_RUTAINICIAL + @"\" + Variables.G_STR_LIBRERIA_CONTABILIDAD + ".dll");
                        //Obtenemos el tipo de la clase
                        Type m_type = m_assembly.GetType(Variables.G_STR_LIBRERIA_CONTABILIDAD + "." + Variables.G_STR_LIBRERIA_OPCIONES);
                        //creamos la instancia
                        var obj_Clase = Activator.CreateInstance(m_type);
                        //Cargamos el metodo solicitado
                        MethodInfo obj_MethodInfo = obj_Clase.GetType().GetMethod(Variables.G_STR_LIBRERIA_OPCIONES_PROCEDIMIENTO_MOSTRAR_EN_MANTENIMIENTO, BindingFlags.Instance | BindingFlags.NonPublic);


                        object[] arr_Parametros = { Variables.G_STR_OPCION_CTA_AMORTIZACIONESCABECERA,
                                                    null,
                                                    null,
                                                    g_mdl_INTERNO_ValoresGenerales_Modelo,
                                                    g_dtt_FechaTrabajo,
                                                    mdl_INTERNO_OpcionesDetalle_Modelo,
                                                    long.Parse(ex_dgv_Historico[0, e.RowIndex].Value.ToString()),
                                                    "",
                                                    "",
                                                    null,
                                                    null};
                        //Pasamos los parametros al metodo y lo ejecutamos
                        obj_MethodInfo.Invoke(obj_Clase, arr_Parametros);
                    }
                    
                }
            }
            catch (Exception ex)
            {
                Control_Errores.Errores_Log("", ex, nameof(CTU_Contabilidad_InmovilizadoHistoricoAmortizaciones) + "/" + nameof(ex_dgv_Historico_CellClick));
            }
        }
        #endregion
    }
}
