using ClosedXML.Excel;
using DevExpress.Web;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace OlympiaIntranet
{
    public partial class ReportAllFunds : System.Web.UI.Page
    {
        //DataTable dtOutput = new DataTable();
        protected override void InitializeCulture() // Aggiunto altrimenti in produzione prendeva settaggi USA per i decimali con il punto invece che con la virgola
        {
            Culture = "it-IT";
            UICulture = "it";

        }
        protected void Page_Load(object sender, EventArgs e)
        {
            if (HttpContext.Current.User.Identity.IsAuthenticated == false)
            {
                Response.Redirect("~/SignIn.aspx");
            }

            //Bind the grid only once
            if (!IsPostBack)
            {
                gvInputCsv.DataBind();
                gvOutput.DataBind();
            }
        }

        protected void uploadControl_FileUploadComplete(object sender, DevExpress.Web.FileUploadCompleteEventArgs e)
        {
            Session["dtInputFile"] = ProcessInputFile(e.UploadedFile);
        }

        public DataTable ProcessInputFile(UploadedFile uploadedFile)
        {
            // ref link: https://www.c-sharpcorner.com/blogs/read-csv-file-into-data-table1
            DataTable dtCsv = new DataTable();
            try
            {
                int idxSuffix = 1; // suffiso per disambiguare colonne con lo stesso nome nel csv di input
                string Fulltext;
                if (uploadedFile.IsValid) //if (FileUpload.HasFile && IsPostBack)
                {
                    using (StreamReader sr = new StreamReader(uploadedFile.FileContent))
                    {
                        while (!sr.EndOfStream)
                        {
                            Fulltext = sr.ReadToEnd().ToString(); //read full file text  
                            string[] rows = Fulltext.Split('\n'); //split full file text into rows  
                            for (int i = 0; i < rows.Count() - 1; i++)
                            {
                                string[] rowValues = rows[i].Split(';'); //split each row with comma to get individual values  
                                {
                                    if (i == 0)  // legge la prima riga degli header
                                    {
                                        for (int j = 0; j < rowValues.Count(); j++)
                                        {
                                            if (dtCsv.Columns.Contains(rowValues[j].Trim())) // Se il nome colonna già esiste in dtCsv allora aggiunge idxSuffix al nome (ad esempio Perc. Type)
                                            {
                                                dtCsv.Columns.Add(rowValues[j].Trim() + "_" + idxSuffix);
                                                idxSuffix++;
                                            }
                                            else dtCsv.Columns.Add(rowValues[j].Trim()); //add headers  
                                        }
                                    }
                                    else
                                    {
                                        if (rowValues[5] == "VMOB" || rowValues[5] == "FUTU" || rowValues[5] == "OPTI") // importa solo le righe che hanno VMOB,FUTU,OPTI nella colonna 'Asset Type'
                                        {
                                            DataRow dr = dtCsv.NewRow();
                                            for (int k = 0; k < rowValues.Count(); k++)
                                            {
                                                dr[k] = rowValues[k].ToString();
                                            }
                                            dtCsv.Rows.Add(dr); //add other rows  
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                return dtCsv;
            }
            catch (Exception)
            {
                dtCsv = null;
                throw;
            }
            
        }

        protected void gvInputCsv_DataBinding(object sender, EventArgs e)
        {
            if (Session["dtInputFile"] != null)
            {
                gvInputCsv.DataSource = (DataTable)Session["dtInputFile"];
            }
        }

        protected void btnElaboraInput_Click(object sender, EventArgs e)
        {
            // ref link: https://stackoverflow.com/questions/14422655/linq-on-datatable-select-specific-column-into-datatable-not-whole-table
            // Generare dal datatable Session["dtInputFile"] un json da usare come parametro alla query reportAllFunds_ProcessData
            // il json deve contenere :  Nav date, Asset, Asset Type, Bloomberg ID , Perc Type 

            DataTable dtInput = (DataTable)Session["dtInputFile"];

            if (dtInput == null) return;  // esce se non è stato caricato alcun csv caricato

            // Seleziono colonne dal csv in input e le metto in un array di anonymous type
            var listParams = from r in dtInput.AsEnumerable()
                             let objectArray = new object[]
                             {
                                r.Field<string>("Nav date").Trim(),
                                r.Field<string>("Asset").Trim(),
                                r.Field<string>("Asset type").Trim(),
                                r.Field<string>("Asset status").Trim(),
                                r.Field<string>("Asset CCY").Trim(),
                                ConvertToDouble(r.Field<string>("Perc. Type")),
                                r.Field<string>("Bloomberg ID").Trim()
                             }
                             select objectArray;

            // Copio l'array in un datatable dtParams per poi convertirlo in json con newtonsoft
            DataTable dtParams = new DataTable();
            dtParams.Columns.Add("NavDate", typeof(string));
            dtParams.Columns.Add("Asset", typeof(string));
            dtParams.Columns.Add("AssetType", typeof(string));
            dtParams.Columns.Add("AssetStatus", typeof(string));
            dtParams.Columns.Add("AssetCCY", typeof(string));
            dtParams.Columns.Add("PercType", typeof(double));
            dtParams.Columns.Add("BloombergID", typeof(string));

            foreach (var array in listParams)
            {
                dtParams.Rows.Add(array);
            }

            // Converte il datatabel dtParams in json 
            string json = JsonConvert.SerializeObject(dtParams);

            // Esegue query per su GuardianDB per elaborare i dati 
            if (String.IsNullOrEmpty(json) == false)
            {
                DataTable dt = new DataTable();
                SqlDataReader result;
                using (var con = new SqlConnection(Properties.Settings.Default.SqlConnection))
                {
                    var cmd = new SqlCommand
                    {
                        CommandText = "reportAllFunds_ProcessData",
                        CommandType = CommandType.StoredProcedure,
                        Connection = con
                    };
                    cmd.Parameters.AddWithValue("@json", json);
                    con.Open(); // Open the OleDBConnection.
                    result = cmd.ExecuteReader();
                    dt.Load(result);
                    Session["dtOutputTrades"] = (DataTable)dt;
                    gvOutput.DataSource = Session["dtOutputTrades"];
                    gvOutput.DataBind();
                }
            }
        }

        protected double ConvertToDouble(string val)
        {
            double tempDouble = 0.0;
            Double.TryParse(val.Trim().Replace(".", ","), out tempDouble);
            return (tempDouble);
        }

        protected void btnOutputGuardian_Click(object sender, EventArgs e)
        {
            // Metodo 1) - Crea file di output in formato .xlsx per guardian relativo a MS Trades
            // Prepare the response
            string fileType = string.Empty;
            string excelTrades = string.Format("reportAllFunds_{0:yyyyMMdd}.xlsx", DateTime.Today.Date);
            HttpResponse httpResponse = Response;
            httpResponse.Clear();
            httpResponse.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
            httpResponse.AddHeader("content-disposition", string.Format("attachment;filename={0}", excelTrades));

            // Flush the workbook to the Response.OutputStream
            DataTable dt = (DataTable)Session["dtOutputTrades"];
            using (var workbook = new XLWorkbook())
            {
                using (MemoryStream memoryStream = new MemoryStream())
                {
                    workbook.Worksheets.Add(dt, "Foglio1");
                    workbook.SaveAs(memoryStream);
                    memoryStream.WriteTo(httpResponse.OutputStream);
                    memoryStream.Close();
                }
            }
            httpResponse.End();
        }

        protected void gvInputCsv_HtmlRowPrepared(object sender, ASPxGridViewTableRowEventArgs e)
        {

        }

        protected void gvOutput_DataBinding(object sender, EventArgs e)
        {

        }
    }
}