using ScaBox30.Controller;
using ScaBox30.Model;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.OleDb;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ScaBox30
{
    public partial class DataUI : Form
    {
        private List<Char> _barcode = new List<char> { };
        private DbController _db = new DbController();
        private OleDbDataReader _reader;

        private List<Data> _new_data = new List<Data>();
        private string _data_json = Application.StartupPath + "\\data.json";
        private string _db_mdb = "";

        // AZUL SELECTOR BLANCO
        /*Color header = Color.FromArgb(52, 73, 94);
        Color selector = Color.White;
        Color primary = Color.FromArgb(84, 153, 199);
        Color secondary = Color.FromArgb(174, 214, 241);*/

        // AZUL SELECTOR GRIS AZUL
        Color header = Color.FromArgb(52, 93, 200);
        Color selector = Color.Silver;
        Color primary = Color.FromArgb(84, 153, 199);
        Color secondary = Color.FromArgb(174, 214, 241);

        // ROJO SELECTOR CRIMSON
        /*Color header = Color.Firebrick;
        Color selector = Color.Crimson;
        Color primary = Color.FromArgb(255, 128, 128);
        Color secondary = Color.FromArgb(255, 192, 192);*/

        // ROJO SELECTOR BLANCO
        /*Color header = Color.Firebrick;
        Color selector = Color.White;
        Color primary = Color.FromArgb(255, 128, 128);
        Color secondary = Color.FromArgb(255, 192, 192);*/


        public DataUI()
        {
            InitializeComponent();
            InitializeItems();
            this.SetStyle(ControlStyles.ResizeRedraw, true);
            LoadUsers();
            LoadJson(_data_json);
            ActiveControl = textBoxCCE;
            SetGridStyle(header, selector, primary, secondary);
        }

        private void SetGridStyle(Color _header, Color _selector, Color _primary, Color _secundary)
        {
            if (true)
            {
                // CONFIGURACION GENERAL DEL DATAGRIDVIEW
                dataGridView1.BackgroundColor = _secundary;                                                                 // ESTABLECE EL COLOR DE FONDO
                dataGridView1.EnableHeadersVisualStyles = false;                                                            // HABILITA O DESHABILITA EL BORDE DEL HEADER
                dataGridView1.ScrollBars = ScrollBars.Both;                                                                 // HABILITA EL SCROLLBAR DE MANERA VERTICAL Y HORIZONTAL
                dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells;                         // AJUSTA DE MANRA AUTOMATICA EL TAMAÑO DE LAS COLUMNAS
                dataGridView1.GridColor = Color.White;                                                                      // ESTABLECE EL COLOR DE LAS LINEAS DE LA CUADRICULA
                // SELECTOR DE FILAS
                dataGridView1.RowHeadersVisible = false;                                                                    // DESHABILITA LA VISUALIZACION DEL HEADER DE LAS FILAS
                dataGridView1.AllowUserToResizeRows = false;                                                                // DESHABILITA LA POSIBILIDAD DE CAMBIAR DE TAMAÑO LAS FILAS
                // ESTILO DE COLUMNAS
                dataGridView1.ColumnHeadersHeight = 23;                                                                     // ESTABLECE EL ALTO DE LAS FILAS
                dataGridView1.ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.None;                                
                dataGridView1.ColumnHeadersDefaultCellStyle.BackColor = header;
                dataGridView1.ColumnHeadersDefaultCellStyle.Font = new Font("Microsoft Sans Serif", 10F, style:FontStyle.Bold , GraphicsUnit.Pixel);
                dataGridView1.ColumnHeadersDefaultCellStyle.ForeColor = Color.White;
                dataGridView1.ColumnHeadersDefaultCellStyle.SelectionBackColor = _selector;
                dataGridView1.ColumnHeadersDefaultCellStyle.SelectionForeColor = Color.White;
                // ESTILO DE CELDAS
                //dataGridView1.CellBorderStyle = DataGridViewCellBorderStyle.None;
                dataGridView1.DefaultCellStyle.BackColor = _primary;
                dataGridView1.DefaultCellStyle.Font = new Font("Microsoft Sans Serif", 10F, GraphicsUnit.Pixel);
                dataGridView1.DefaultCellStyle.ForeColor = Color.Black;
                dataGridView1.DefaultCellStyle.SelectionBackColor = _selector;
                dataGridView1.DefaultCellStyle.SelectionForeColor = Color.Black;
                dataGridView1.DefaultCellStyle.ForeColor = Color.Black;
                // ESTILO CELDAS ALTERNADAS
                dataGridView1.AlternatingRowsDefaultCellStyle.BackColor = _secundary;
                dataGridView1.AlternatingRowsDefaultCellStyle.Font = new Font("Microsoft Sans Serif", 10F, GraphicsUnit.Pixel);
                dataGridView1.AlternatingRowsDefaultCellStyle.ForeColor = Color.Black;
                dataGridView1.AlternatingRowsDefaultCellStyle.SelectionBackColor = _selector;
                dataGridView1.AlternatingRowsDefaultCellStyle.SelectionForeColor = Color.Black;
            }

        }


        // CARGA EL ARCHIVO DATA.JSON EXISTENTE
        private void LoadJson(String jsonfile)
        {
            if (File.Exists(jsonfile))
            {
                Globals.actual_data.Clear();
                this.Cursor = Cursors.WaitCursor;
                string jscontent = File.ReadAllText(jsonfile);
                Globals.actual_data = JsonSerializer.Deserialize<List<Data>>(jscontent);
                dataGridView1.DataSource = Globals.actual_data;
                labelRegistros.Text = "Registros: " + Globals.actual_data.Count.ToString();
                jscontent = "";
                this.Cursor = Cursors.Default;
            }
        }


        private void LoadUsers()
        {
            CreateUserJson(Globals.auth_json);
            LoadUserJson(Globals.auth_json);
        }


        private void CreateUserJson(string jsonfile)
        {
            if (!File.Exists(jsonfile))
            {
                List<User> users = new List<User> { };
                users.Add(new User() { user = "admin", password = "admin123" });
                var json = JsonSerializer.Serialize<List<User>>(users);
                File.WriteAllText(jsonfile, json);
                users.Clear();
            }
        }


        private void LoadUserJson(string jsonfile)
        {
            if (File.Exists(jsonfile))
            {
                Globals.users.Clear();
                string jsoncontent = File.ReadAllText(jsonfile);
                Globals.users = JsonSerializer.Deserialize<List<User>>(jsoncontent);
                jsoncontent = "";
            }
        }






        // OBTIENE EL BOX_CAPACITY EXISTENTE
        private String FindBoxCapacity(List<Data> actual, OleDbDataReader nueva)
        {
            // String capacity = "";
            /*foreach (var item in actual)
            {
                if (item.CCE == nueva.GetValue(0).ToString()){ capacity = item.Box_Capacity; }
            }*/

            var capacity = (from item in actual where item.CCE == nueva.GetValue(0).ToString() select item.Box_Capacity).FirstOrDefault();

            return capacity;
        }



        // CARGA LOS ELEMENTOS DE LA FILA SELECCIONADA A LA INTERFAZ
        private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex > -1)
            {
                //textBoxCCE.Text = dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString();
            }
        }



        // GUARDA LOS CAMBIOS REALIZADOS AL DATAGRIDVIEW
        private void buttonSave_Click(object sender, EventArgs e)
        {
            this.Cursor = Cursors.WaitCursor;
            List<Data> records = new List<Data> { };

            // OBTIENE LA INFORMACION DEL DATAGRIDVIEW Y LA PASA A UNA INSTANCIA DE LA CLASE DB
            foreach (DataGridViewRow row in dataGridView1.Rows)
            {
                Data rowd = row.DataBoundItem as Data;
                if (rowd != null){ records.Add(rowd); }
            }

            var json = JsonSerializer.Serialize<List<Data>>(records);
            File.WriteAllText(_data_json, json);
            this.Cursor = Cursors.Default;
            // SE REALIZAN TAREAS DE LIMPIEZA DE MEMORIA
            records.Clear();
            GC.Collect();
            GC.WaitForPendingFinalizers();
            //******************************************
            RJMessageBox.Show("Actualizada correctamente", "ScanBox", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }



        private void textBoxCCE_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData == Keys.Enter)
            {
                int rowIndex = -1;
                foreach (DataGridViewRow row in dataGridView1.Rows)
                {
                    if (row.Cells[0].Value.ToString().Equals(textBoxCCE.Text))
                    {
                        rowIndex = row.Index;
                        break;
                    }
                }
                if (rowIndex > -1)
                {
                    dataGridView1.ClearSelection();
                    dataGridView1.Rows[rowIndex].Selected = true;
                    dataGridView1.FirstDisplayedScrollingRowIndex = rowIndex;
                }
                else
                {
                    RJMessageBox.Show("OPC No encontrdao", "ScanBox", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }

                textBoxCCE.Clear();
            }
        }

        

        private String OpenDbFileDialog()
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "Access File (*.mdb)|*.mdb|All files (*.*)|*.*";
            openFileDialog.ShowDialog();
            return openFileDialog.FileName;
        }

        private async void buttonOpenFile_Click(object sender, EventArgs e)
        {
            

            Usuario usuario = new Usuario();
            DialogResult result = usuario.ShowDialog();


            if (Globals.valid_user && result != DialogResult.Cancel)
            {
                _db_mdb = OpenDbFileDialog();
                textPathFile.Text = _db_mdb;

                await Task.Delay(500);


                // SI EL ARCHIVO DATA.JSON EXISTE SE OBTIENEN LOS REGISTROS ACTUALES
                if (File.Exists(_data_json))
                {
                    this.Cursor = Cursors.WaitCursor;
                    string filecontent = File.ReadAllText(_data_json);
                    Globals.actual_data = JsonSerializer.Deserialize<List<Data>>(filecontent);
                    filecontent = "";
                    this.Cursor = Cursors.Default;
                }



                if (File.Exists(_db_mdb))
                {
                    this.Cursor = Cursors.WaitCursor;

                    _db.SetWorkingDb(_db_mdb);
                    _db.Open();
                    try
                    {
                        // POR MEDIO DEL QUERY NOS ASEGURAMOS DE TRAER LA DATA EN EL ORDEN CORRECTO
                        string base_columns = "CCE,VERSION,ETAT,MARQUE,TEINTE,PS1,PS2,DIAM,SPHM,CYLM,Ref_Etiquette,code_epc,oeil,base,addition,epc,indice,dec,diam1,diam2,ref_coque,ref_cond,nom_1,nom_2,matiere_fr,matiere_us,couleur_fr,couleur_us,vernis,traitement_1,traitement_2,traitement_3,signom,sig1,sig2,code_upc,code_jan1,code_jan2,Reserve1,Reserve2,reserve_art_1,reserve_art_2,Ref_NiceLabel";


                        // SE REALIZA UNA CONSULTA DE PRUEBA PARA DETERMINAR LA CANTIDAD DE COLUMNAS A IMPORTAR
                        _reader = _db.Query("SELECT * FROM Standard");
                        if (_reader != null)
                        {
                            Globals.boxcapacity = _reader.FieldCount == 44 ? true : false;
                        }

                        _reader = Globals.boxcapacity ? ( _db.Query("SELECT " + base_columns + ", Box_Capacity FROM Standard" )) : (_db.Query("SELECT " + base_columns + " FROM Standard"));


                        if (_reader != null && !_reader.IsClosed) // Si la consulta no retornó un valor null y si el reader no es null y no está cerrado 
                        {
                            while (_reader.Read())
                            {
                                _new_data.Add(
                                    new Data
                                    {
                                        
                                        CCE = _reader.GetValue(0).ToString().Replace(" ", ""),
                                        VERSION = _reader.GetValue(1).ToString().Replace(" ", ""),
                                        ETAT = _reader.GetValue(2).ToString().Replace(" ", ""),
                                        MARQUE = _reader.GetValue(3).ToString().Replace(" ", ""),
                                        TEINTE = _reader.GetValue(4).ToString().Replace(" ", ""),
                                        PS1 = _reader.GetValue(5).ToString().Replace(" ", ""),
                                        PS2 = _reader.GetValue(6).ToString().Replace(" ", ""),
                                        DIAM = _reader.GetValue(7).ToString().Replace(" ", ""),
                                        SPHM = _reader.GetValue(8).ToString().Replace(" ", ""),
                                        CYLM = _reader.GetValue(9).ToString().Replace(" ", ""),
                                        Ref_Etiquette = _reader.GetValue(10).ToString().Replace(" ", ""),
                                        code_epc = _reader.GetValue(11).ToString().Replace(" ", ""),
                                        oeil = _reader.GetValue(12).ToString().Replace(" ", ""),
                                        @base = _reader.GetValue(13).ToString().Replace(" ", ""),
                                        addition = _reader.GetValue(14).ToString().Replace(" ", ""),
                                        epc = _reader.GetValue(15).ToString().Replace(" ", ""),
                                        indice = _reader.GetValue(16).ToString().Replace(" ", ""),
                                        dec = _reader.GetValue(17).ToString().Replace(" ", ""),
                                        diam1 = _reader.GetValue(18).ToString().Replace(" ", ""),
                                        diam2 = _reader.GetValue(19).ToString().Replace(" ", ""),
                                        ref_coque = _reader.GetValue(20).ToString().Replace(" ", ""),
                                        ref_cond = _reader.GetValue(21).ToString().Replace(" ", ""),
                                        nom_1 = _reader.GetValue(22).ToString(),
                                        nom_2 = _reader.GetValue(23).ToString(),
                                        matiere_fr = _reader.GetValue(24).ToString().Replace(" ", ""),
                                        matiere_us = _reader.GetValue(25).ToString().Replace(" ", ""),
                                        couleur_fr = _reader.GetValue(26).ToString().Replace(" ", ""),
                                        couleur_us = _reader.GetValue(27).ToString().Replace(" ", ""),
                                        vernis = _reader.GetValue(28).ToString().Replace(" ", ""),
                                        traitement_1 = _reader.GetValue(29).ToString().Replace(" ", ""),
                                        traitement_2 = _reader.GetValue(30).ToString().Replace(" ", ""),
                                        traitement_3 = _reader.GetValue(31).ToString().Replace(" ", ""),
                                        signom = _reader.GetValue(32).ToString().Replace(" ", ""),
                                        sig1 = _reader.GetValue(33).ToString().Replace(" ", ""),
                                        sig2 = _reader.GetValue(34).ToString().Replace(" ", ""),
                                        code_upc = _reader.GetValue(35).ToString().Replace(" ", ""),
                                        code_jan1 = _reader.GetValue(36).ToString().Replace(" ", ""),
                                        code_jan2 = _reader.GetValue(37).ToString().Replace(" ", ""),
                                        Reserve1 = _reader.GetValue(38).ToString().Replace(" ", ""),
                                        Reserve2 = _reader.GetValue(39).ToString().Replace(" ", ""),
                                        reserve_art_1 = _reader.GetValue(40).ToString().Replace(" ", ""),
                                        reserve_art_2 = _reader.GetValue(41).ToString().Replace(" ", ""),
                                        Ref_NiceLabel = _reader.GetValue(42).ToString().Replace(" ", ""),
                                        Box_Capacity = Globals.boxcapacity? _reader.GetValue(43).ToString().Replace(" ", "") : FindBoxCapacity(Globals.actual_data, _reader),
                                    } // new db
                                ); // new_records

                            }
                            _reader.Close();
                            _db.Close();

                            labelRegistros.Text = "Registros: " + _new_data.Count();

                            var json = JsonSerializer.Serialize<List<Data>>(_new_data);
                            File.WriteAllText(_data_json, json);
                            // SE REALIZAN TAREAS DE LIMPIEZA DE MEMORIA
                            _new_data.Clear();
                            Globals.actual_data.Clear();
                            GC.Collect();
                            GC.WaitForPendingFinalizers();
                            // *****************************************
                            LoadJson(_data_json);
                            RJMessageBox.Show("Base de datos importada correctamente", "ScanBox", MessageBoxButtons.OK,MessageBoxIcon.Information);

                        }
                        else
                        {
                            RJMessageBox.Show("No fue posible importar la base de datos. Asegurese de que la tabla Standard existe.", "ScanBox", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }


                        this.Cursor = Cursors.Default;

                    }
                    catch (Exception ex)
                    {
                        this.Cursor = Cursors.Default;
                        MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }

                // Reset login
                Globals.valid_user = false;
            }
            else
            {
                if (result != DialogResult.Cancel)
                {
                    RJMessageBox.Show("No tiene permiso para realizar esta acción", "ScanBox", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }



            


        }


        private void dataGridView1_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            

            if (!Globals.valid_user)
            {
                Usuario usuario = new Usuario();
                DialogResult result = usuario.ShowDialog();

                if (Globals.valid_user)
                {
                    RJMessageBox.Show("Ya puede editar la tabla", "ScanBox", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    dataGridView1.ReadOnly = false;
                }
                else
                {
                    if (result != DialogResult.Cancel)
                    {
                        RJMessageBox.Show("No tiene permiso para realizar esta acción", "ScanBox", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        dataGridView1.ReadOnly = true;
                    }
                    
                }
            }

        }


        // VALIDACIONES DE LA COLUMNA BOX_CAPACITY
        private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            var value = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
            string colname = "Box_Capacity";

            if (value != null && dataGridView1.Columns[e.ColumnIndex].Name == colname)
            {
                if (Int32.TryParse(value.ToString(), out int x))
                {
                    //Restrucción de 3 dígitos
                    //if (x > 99)
                    //{
                    //    RJMessageBox.Show("BoxCapacity no puede ser mayor a dos dígitos", "ScanBox", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    //    dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = "";
                    //}

                    //Restriccion de cero
                    if (!(x > 1))
                    {
                        RJMessageBox.Show("BoxCapacity debe ser mayor a cero", "ScanBox", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = "";
                    }
                }
                else
                {
                    RJMessageBox.Show("Solo se permiten números", "ScanBox", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = "";
                }
            }

        }



        private void btnEdit_Click(object sender, EventArgs e)
        {
            Usuario usuario = new Usuario();
            usuario.ShowDialog();


            if (Globals.valid_user)
            {
                RJMessageBox.Show("Ya puede editar la tabla", "ScanBox", MessageBoxButtons.OK, MessageBoxIcon.Information);
                dataGridView1.ReadOnly = false;
            }else
            {
                RJMessageBox.Show("No tiene permiso para realizar esta acción", "ScanBox", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                dataGridView1.ReadOnly = true;
            }

            
        }

        private void DataUI_FormClosing(object sender, FormClosingEventArgs e)
        {
            // Reset login
            Globals.valid_user = false;
        }


        private void InitializeItems()
        {
            this.FormBorderStyle = FormBorderStyle.None;
            this.Padding = new Padding(Globals.borderSize);//Set border size
            this.btnClose.DialogResult = DialogResult.Cancel;
            this.labelCaption.Text = this.Text;
            this.panelTitleBar.BackColor = Globals.primaryColor;
            this.panelTitleBar.Padding = new Padding(0, 0, 0, Globals.borderSize);
            this.BackColor = Globals.primaryColor;
        }


        #region -> Maximizar
        private void btnMax_Click(object sender, EventArgs e)
        {

            if (WindowState == FormWindowState.Maximized)
            {
                this.WindowState = FormWindowState.Normal;
            }
            else
            {
                WindowState = FormWindowState.Maximized;
            }
        }
        #endregion

        #region -> Minimizar
        private void btnMin_Click(object sender, EventArgs e)
        {
            if (WindowState == FormWindowState.Normal || WindowState == FormWindowState.Maximized)
            {
                this.WindowState = FormWindowState.Minimized;
            }
            else
            {
                WindowState = FormWindowState.Normal;
            }
        }
        #endregion

        #region -> Drag Form
        [DllImport("user32.DLL", EntryPoint = "SendMessage")]
        private extern static void SendMessage(System.IntPtr hWnd, int wMsg, int wParam, int lParam);
        [DllImport("user32.DLL", EntryPoint = "ReleaseCapture")]
        private extern static void ReleaseCapture();
        private void panelTitleBar_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Clicks == 2)
            {
                WindowState = WindowState == FormWindowState.Maximized ? FormWindowState.Normal: FormWindowState.Maximized;
            }
            else
            {
                ReleaseCapture();
                SendMessage(this.Handle, 0x112, 0xf012, 0);
            } 
        }

        #endregion

        #region -> Resize Form
        private const int cGrip = 16;
        private const int cCaption = 32;
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == 0x84)
            {
                Point pos = new Point(m.LParam.ToInt32());
                pos = this.PointToClient(pos);
                if (pos.Y < cCaption)
                {
                    m.Result = (IntPtr)2;
                    return;
                }

                if (pos.X >= this.ClientSize.Width - cGrip && pos.Y >= this.ClientSize.Height - cGrip)
                {
                    m.Result = (IntPtr)17;
                    return;
                }
            }
            base.WndProc(ref m);
        }




        #endregion

        
    }
}
