
using Oracle.ManagedDataAccess.Client;
using System;
using System.Collections.Generic;
using System.Data;

using System.Dynamic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EKONO.DB
{
    public class Conexion
    {
        private static string UserID = "EKONO";
        private static string Password = "EKONO";
        private static string ServiceName = "POS";
        private static string Host = "192.168.1.180";//Desarrollo
        //private static string Host = "192.168.1.168";//Produccion
        private static string Port = "1521";
        private static string ExceptionPath;
        private static string oradb = "Data Source = (DESCRIPTION =" +
                               "(ADDRESS =" +
                                 "(PROTOCOL = TCP)" +
                                 "(HOST = " + Host + ")" +
                                 "(PORT = " + Port + ")" +
                               ")" +
                               "(CONNECT_DATA =" +
                                 "(SERVER = dedicated)" +
                                 "(SERVICE_NAME = " + ServiceName +")" +
                               ")" +
                             ")" +
                             ";User Id = " + UserID + "; Password = " + Password + ";";
        
        public static void Conectar()
        {
            
        }
        
            /// <summary>
            /// Ejecutar una consulta que retorna un DataTable
            /// </summary>
            /// <param name="select"></param>
            /// <returns>Datatable</returns>
        public static DataTable EjecutarSelect(string select)
        {
            
            OracleConnection conn = new OracleConnection(oradb);  // C#
            conn.Open();
            OracleCommand cmd = new OracleCommand();
            cmd.Connection = conn;
            cmd.CommandText = select;
            cmd.CommandType = CommandType.Text;
            OracleDataReader dr = cmd.ExecuteReader();
            DataTable schemaTable = dr.GetSchemaTable();
            DataTable dtData = new DataTable("Data");           
            foreach (DataRow schemarow in schemaTable.Rows)
            {
                dtData.Columns.Add(schemarow.ItemArray[0].ToString(), System.Type.GetType(schemarow.ItemArray[11].ToString()));
            }
            while (dr.Read())
            {
                object[] ColArray = new object[dr.FieldCount];
                for (int i = 0; i < dr.FieldCount; i++)
                {
                    if (dr[i] != null) ColArray[i] = dr[i];
                }
                dtData.LoadDataRow(ColArray, true);
            }
           
            conn.Dispose();
       
            return dtData;
        }

        /// <summary>
        /// Ejecuta una consulta que retorna un único dato
        /// </summary>
        /// <param name="select"></param>
        /// <returns></returns>
        public static string EjecutarSelecResultadoUnico(string select)
        {
            string resultado = string.Empty;                
            OracleConnection conn = new OracleConnection(oradb);  // C#
            conn.Open();
            OracleCommand cmd = new OracleCommand();
            cmd.Connection = conn;
            cmd.CommandText = select;
            cmd.CommandType = CommandType.Text;
            OracleDataReader dr = cmd.ExecuteReader();
            DataTable schemaTable = dr.GetSchemaTable();
            DataTable dtData = new DataTable("Data");
            foreach (DataRow schemarow in schemaTable.Rows)
            {
                dtData.Columns.Add(schemarow.ItemArray[0].ToString(), System.Type.GetType(schemarow.ItemArray[11].ToString()));
            }
            while (dr.Read())
            {
                object[] ColArray = new object[dr.FieldCount];
                for (int i = 0; i < dr.FieldCount; i++)
                {
                    if (dr[i] != null) resultado= dr[i].ToString();
                }
               

            }

            conn.Dispose();

            return resultado;
        }

        /// <summary>
        /// Ejecutar un procedimiento almacenado
        /// </summary>
        /// <param name="sp_nombre">Nombre del procedimiento almacenado</param>
        /// <param name="nombresParametros">Nombre de los parámetros del procedimiento almacenado</param>
        /// <param name="valores">Valores de los parámetros del procedimiento almacenado</param>
        /// <param name="tiposValores">Tipo de valores de los parámetros del procedimiento almacenado</param>
        /// <param name="direccionParametros">Si los parametros son de entrada o salida input, output</param>
        /// <param name="tieneVariableSalida">Si posee algún parámetro de salida output</param>
        /// <returns></returns>
        public static string EjecutarProcedimientoAlmacenado(
            string sp_nombre
            ,List<string> nombresParametros
            ,List<dynamic> valores
            ,List<OracleDbType> tiposValores
            ,List<ParameterDirection> direccionParametros,bool tieneVariableSalida)
            {
            string valorVariableSalida = string.Empty;
            try
            {
              
                using (OracleConnection conn = new OracleConnection(oradb))
                {

                    conn.Open();
                    // 1.  Crea el comando con el sp que le pasamos
                    OracleCommand cmd = new OracleCommand(sp_nombre, conn);

                    // 2. Seleccionamos el tipo de comando como procedimiento almacenado
                    cmd.CommandType = CommandType.StoredProcedure;

                    // 3. Agregamos los parametros en el roden, NombresParametros,tiposValores,y direccion osea entrada o salida
                    for (int i = 0; i < nombresParametros.Count; i++)
                    {
                        if (valores[i].ToString() != "NULL")
                        {
                            cmd.Parameters.Add(new OracleParameter("@" + nombresParametros[i]
                             , tiposValores[i], valores[i], direccionParametros[i]));
                        }
                        else
                        {
                            valores[i] = DBNull.Value;
                            cmd.Parameters.Add(new OracleParameter("@" + nombresParametros[i]
                           , tiposValores[i], valores[i], direccionParametros[i]));
                        }
                       
                    }



                    // execute the command
                    using (OracleDataReader rdr = cmd.ExecuteReader())
                    {
                        if (tieneVariableSalida)
                        {
                            if (cmd.Parameters.Count > 0)
                            {
                                valorVariableSalida = cmd.Parameters[0].Value.ToString();
                            }                          
                        }
                        // iterate through results, printing each to console
                        while (rdr.Read())
                        {
                            //si el sp devuelve un select se pueden extraer los datos asi por el nombre de las columnas ejn el select
                            //Console.WriteLine("Product: {0,-35} Total: {1,2}", rdr["ProductName"], rdr["Total"]);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogException(ex.ToString());
                return valorVariableSalida+ex.ToString();
            }

            return valorVariableSalida;
        }

        public static long WMS_S_DOCUMENTO()
        {
            OracleConnection conn = new OracleConnection(oradb);
            try
            {
                conn.Open();
                OracleCommand loCmd = conn.CreateCommand();
                loCmd.CommandType = CommandType.Text;
                loCmd.CommandText = "select WMS_S_DOCUMENTO.nextval from dual";
                long lnNextVal = Convert.ToInt64(loCmd.ExecuteScalar());
                conn.Close();
                conn.Dispose();
                return lnNextVal;
            }
            catch (Exception)
            {
                conn.Close();
                conn.Dispose();
                return -1;
            }
           
        }


        /// <summary>
        /// Esta funcion se encarga de almacenar los reportes de errores recopilados en los catch las funciones anteriores
        /// </summary>
        /// <param name="Exception">Es el nombre de la excepcion</param>
        private static void LogException(string Exception)
        {
            try
            {

                if (ExceptionPath == null)
                {

                    /// Ruta en la que se almacenara la informacion 
                    ExceptionPath = @"";
                    DateTime localDate = DateTime.Now;
                    string year = localDate.Year.ToString();
                    string mes = localDate.Month.ToString();
                    string day = localDate.Day.ToString();
                    string datetime = DateTime.Now.ToString("hh-mm-ss tt");

                    if (mes.Length == 1)
                    {
                        mes = "0" + mes;
                    }
                    if (day.Length == 1)
                    {
                        day = "0" + day;
                    }

                    /*
                     * Direccion dinamica
                     * Permite abrir una ventana para almacenar el archivo don de elija el usuario
                    using (var fbd = new FolderBrowserDialog())
                    {
                        DialogResult resultado = fbd.ShowDialog();

                        if (resultado == DialogResult.OK && !string.IsNullOrEmpty(fbd.SelectedPath))
                        {
                            this.ExceptionPath += fbd.SelectedPath + "\\754610004" + year + mes + day + "LOGExceptionsPLUS.txt"; ;
                        }
                    }
                    */

                    /// Direccion de almaceamiento por defecto
                    ExceptionPath += "C:\\ekono\\Common\\EventZunifyWebHook" + year + "-" + mes + "-" + day + " " + datetime + ".txt"; ;

                    if (!String.IsNullOrEmpty(ExceptionPath))
                    {
                        using (System.IO.StreamWriter sw = System.IO.File.CreateText(ExceptionPath))
                        {

                            sw.WriteLine("Excepciones de Zunify Webhook");

                        }
                    }


                }

                if (!String.IsNullOrEmpty(ExceptionPath))
                {
                    using (System.IO.StreamWriter sw = System.IO.File.AppendText(ExceptionPath))
                    {

                        sw.WriteLine(Exception);


                    }
                }


            }

            catch (Exception vError)
            {

                Console.WriteLine(vError.Message);
            }

        }
    }
}
 
        




