using ClosedXML.Excel;
using DevExpress.Export;
using DevExpress.Web;
using DevExpress.XtraPrinting;
using MySqlConnector;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace OlympiaIntranet
{
    public partial class Margini : System.Web.UI.Page
    {
        DataTable dtOutputTrades = 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();
                gvPlurima10.DataBind();
                gvPlurimaVB.DataBind();
            }
        }

        protected void uploadControl_FileUploadComplete(object sender, 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();
            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 , to get individual values  
                            {
                                if (i == 0)
                                {
                                    for (int j = 0; j < rowValues.Count(); j++)
                                    {
                                        if (j == 0 || j == 1 || j == 3 || j == 10 || j == 13 || j == 15) dtCsv.Columns.Add(rowValues[j]); //add headers 0 - Business Date, 1 - Account ID,3 - Currency,10 - Open Trade Equity,13 - Initial Margin,15 - Margin Excess Deficit
                                    }
                                }
                                else
                                {
                                    DataRow dr = dtCsv.NewRow();
                                    int cont = 0;
                                    for (int k = 0; k < rowValues.Count(); k++)
                                    {
                                        if (k == 0 || k == 1 || k == 3 || k == 10 || k == 13 || k == 15)
                                        {
                                            if (k == 13) // Se è colonna InitialMargin aggiungo un - davanti
                                            {
                                                if (rowValues[k].ToString() != "0" && rowValues[k].ToString().IndexOf("-")==-1) // se il valore non è 0 e non è negativo allora aggiunge il meno
                                                {
                                                    dr[cont] = "-" + rowValues[k].ToString().Replace("\"", string.Empty);
                                                }
                                                if (rowValues[k].ToString() != "0" && rowValues[k].ToString().IndexOf("-") != -1) // se il valore non è 0 ed è negativo allora toglie il meno
                                                {
                                                    dr[cont] = rowValues[k].ToString().Replace("\"", string.Empty).Replace("-",string.Empty);
                                                }
                                                if (rowValues[k].ToString() == "0") // se il valore e 0 non modifica niente
                                                {
                                                    dr[cont] = "0";
                                                }

                                            }
                                            else dr[cont] = rowValues[k].ToString().Replace("\"", string.Empty);
                                            cont++;
                                        }
                                    }
                                    dtCsv.Rows.Add(dr); //add other rows  
                                }
                            }
                        }
                    }
                }
            }
            return dtCsv;
        }

        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)
        {
            // Serve solo per effettuare il postback e bindare gvInputCsv al datatable contenuto in Session["dtResetFile"]

            // Importa struttura colonne file excel in output per Guardian
            dtOutputTrades = ElaboraTemplateGuardian(Server.MapPath("~/App_Data/TEMPLATE/sample_imp_tra.xlsx"), "Foglio1"); // Importa colonne file template in output per Guardian

            //if (radioButtonList.SelectedIndex == 0) ElaboraMSResetFile(); // Elabora reset file 
            ElaboraOutputFile();

        }

        private void ElaboraOutputFile()
        {
            DataTable dt = (DataTable)Session["dtInputFile"];
            DataTable dtPlurima10 = new DataTable();
            dtPlurima10.Columns.Add("Conto", typeof(string));
            dtPlurima10.Columns.Add("Descrizione", typeof(string));
            dtPlurima10.Columns.Add("Currency", typeof(string));
            dtPlurima10.Columns.Add("RBC", typeof(double));
            dtPlurima10.Columns.Add("Guardian", typeof(double));
            DataTable dtPlurimaVB = new DataTable();
            dtPlurimaVB.Columns.Add("Conto", typeof(string));
            dtPlurimaVB.Columns.Add("Descrizione", typeof(string));
            dtPlurimaVB.Columns.Add("Currency", typeof(string));
            dtPlurimaVB.Columns.Add("RBC", typeof(double));
            dtPlurimaVB.Columns.Add("Guardian", typeof(double));
            if (dt.Rows.Count > 0)
            {
                string currency = string.Empty;
                string cod_rap = string.Empty;
                foreach (DataRow rigaInput in dt.Rows)
                {
                    /*
                    RBC                 Guardian
                    InitialMargin       ETD Initial Marg
                    MarginExcessDeficit ETD Cash
                    OpenTradeEquity     ETD Open Trade
                    */
                    // Rileva valori da cui poi creare le righe se sono > 0
                    if (rigaInput["AccountID"].ToString() == "C77261") cod_rap = "10CONV";
                    if (rigaInput["AccountID"].ToString() == "C77260") cod_rap = "DB6289";
                    currency = rigaInput["Currency"].ToString();
                    double initialMargin, marginExcessDeficit, openTradeEquity, initialMarginGDN, marginExcessDeficitGDN, openTradeEquityGDN = 0;
                    double diffInitialMargin, diffMarginExcessDeficit, diffOpenTradeEquity = 0;
                    string temp = string.Empty;

                    ///
                    /// Elabora InitialMargin (ETD Initial Marg)
                    ///
                    Double.TryParse(rigaInput["InitialMargin"].ToString().Replace(".", ","), out initialMargin); // Nota: E' stato necessario settare in aspx nella direttiva <%@ Page:  UICulture="it" Culture="it-IT" e fare override InitializeCulture altrimenti in produzione prendeva il settaggio USA per i decimali con il punto come decimale invece della virgola !
                    string cod_dep_liq_initialMarginGDN = String.Empty;
                    string descrInitialMarginGDN = String.Empty;

                    temp = execSP_Scalar("SELECT tmp2.qta FROM tmppostit2 tmp2 LEFT JOIN tit t ON(t.cod_tit = tmp2.cod_tit) LEFT JOIN rap r ON(r.cod_rap = tmp2.cod_rap) WHERE r.cod_rap = '" + cod_rap + "' and t.cod_div = '" + currency + "' and t.des_tit like '%ETD Initial Marg%' AND r.cod_sta in ('ATTIVO', 'PENDING') LIMIT 1; ");
                    if (!String.IsNullOrEmpty(temp)) initialMarginGDN = Convert.ToDouble(temp);
                    else initialMarginGDN = 0;
                    cod_dep_liq_initialMarginGDN = execSP_Scalar("SELECT d.cod_dep_liq from depliq d where d.cod_rap = '" + cod_rap + "' and d.cod_div = '" + currency + "' and d.des_dep_liq like '%ETD Initial Marg%';");
                    descrInitialMarginGDN = execSP_Scalar("SELECT t.des_tit FROM depliq d LEFT JOIN tit t ON (t.cod_tit = d.cod_dep_liq) WHERE  d.cod_rap = '" + cod_rap + "' and d.cod_div = '" + currency + "' and d.des_dep_liq like '%ETD Initial Marg%';");

                    diffInitialMargin = Math.Round(initialMargin - initialMarginGDN, 2);
                    if (diffInitialMargin != 0) CreaRiga(currency, cod_rap, rigaInput, cod_dep_liq_initialMarginGDN, diffInitialMargin);

                    if (cod_rap == "10CONV") CreaRigaPlurima(cod_dep_liq_initialMarginGDN, descrInitialMarginGDN, currency, initialMargin, initialMarginGDN, dtPlurima10);
                    if (cod_rap == "DB6289") CreaRigaPlurima(cod_dep_liq_initialMarginGDN, descrInitialMarginGDN, currency, initialMargin, initialMarginGDN, dtPlurimaVB);


                    ///
                    /// Elabora MarginExcessDeficit (ETD Cash)
                    ///
                    Double.TryParse(rigaInput["MarginExcessDeficit"].ToString().Replace(".", ","), out marginExcessDeficit);
                    string cod_dep_liq_marginExcessDeficitGDN = String.Empty;
                    string descrMarginExcessDeficitGDN = string.Empty;
                    temp = execSP_Scalar("SELECT tmp2.qta FROM tmppostit2 tmp2 LEFT JOIN tit t ON (t.cod_tit = tmp2.cod_tit) LEFT JOIN rap r ON (r.cod_rap = tmp2.cod_rap) WHERE  r.cod_rap = '" + cod_rap + "' and t.cod_div = '" + currency + "' and t.des_tit like '%ETD Cash%' AND r.cod_sta in ('ATTIVO', 'PENDING') LIMIT 1;");
                    if (!String.IsNullOrEmpty(temp)) marginExcessDeficitGDN = Convert.ToDouble(temp);
                    else marginExcessDeficitGDN = 0;
                    cod_dep_liq_marginExcessDeficitGDN = execSP_Scalar("SELECT d.cod_dep_liq from depliq d where d.cod_rap = '" + cod_rap + "' and d.cod_div = '" + currency + "' and d.des_dep_liq like '%ETD Cash%';");
                    descrMarginExcessDeficitGDN = execSP_Scalar("SELECT t.des_tit FROM depliq d LEFT JOIN tit t ON (t.cod_tit = d.cod_dep_liq) WHERE  d.cod_rap = '" + cod_rap + "' and d.cod_div = '" + currency + "' and d.des_dep_liq like '%ETD Cash%';");

                    diffMarginExcessDeficit = Math.Round(marginExcessDeficit - marginExcessDeficitGDN, 2);
                    if (diffMarginExcessDeficit != 0) CreaRiga(currency, cod_rap, rigaInput, cod_dep_liq_marginExcessDeficitGDN, diffMarginExcessDeficit);

                    if (cod_rap == "10CONV") CreaRigaPlurima(cod_dep_liq_marginExcessDeficitGDN, descrMarginExcessDeficitGDN, currency, marginExcessDeficit, marginExcessDeficitGDN, dtPlurima10);
                    if (cod_rap == "DB6289") CreaRigaPlurima(cod_dep_liq_marginExcessDeficitGDN, descrMarginExcessDeficitGDN, currency, marginExcessDeficit, marginExcessDeficitGDN, dtPlurimaVB);

                    ///
                    /// Elabora OpenTradeEquity (ETD Open Trade)
                    ///
                    Double.TryParse(rigaInput["OpenTradeEquity"].ToString().Replace(".", ","), out openTradeEquity);
                    string cod_dep_liq_openTradeEquityGDN = String.Empty;
                    string descrOpenTradeEquityGDN = String.Empty;

                    temp = execSP_Scalar("SELECT tmp2.qta FROM tmppostit2 tmp2 LEFT JOIN tit t ON (t.cod_tit = tmp2.cod_tit) LEFT JOIN rap r ON (r.cod_rap = tmp2.cod_rap) WHERE  r.cod_rap = '" + cod_rap + "' and t.cod_div = '" + currency + "' and t.des_tit like '%ETD Open Trade%' AND r.cod_sta in ('ATTIVO', 'PENDING') LIMIT 1;");
                    if (!String.IsNullOrEmpty(temp)) openTradeEquityGDN = Convert.ToDouble(temp);
                    else openTradeEquityGDN = 0;
                    cod_dep_liq_openTradeEquityGDN = execSP_Scalar("SELECT d.cod_dep_liq from depliq d where d.cod_rap = '" + cod_rap + "' and d.cod_div = '" + currency + "' and d.des_dep_liq like '%ETD Open Trade%';");
                    descrOpenTradeEquityGDN = execSP_Scalar("SELECT t.des_tit FROM depliq d LEFT JOIN tit t ON (t.cod_tit = d.cod_dep_liq) WHERE  d.cod_rap = '" + cod_rap + "' and d.cod_div = '" + currency + "' and d.des_dep_liq like '%ETD Open Trade%';");

                    diffOpenTradeEquity = Math.Round(openTradeEquity - openTradeEquityGDN, 2);
                    if (diffOpenTradeEquity != 0) CreaRiga(currency, cod_rap, rigaInput, cod_dep_liq_openTradeEquityGDN, diffOpenTradeEquity);

                    if (cod_rap == "10CONV") CreaRigaPlurima(cod_dep_liq_openTradeEquityGDN, descrOpenTradeEquityGDN, currency, openTradeEquity, openTradeEquityGDN, dtPlurima10);
                    if (cod_rap == "DB6289") CreaRigaPlurima(cod_dep_liq_openTradeEquityGDN, descrOpenTradeEquityGDN, currency, openTradeEquity, openTradeEquityGDN, dtPlurimaVB);

               
                }
                if (dtOutputTrades.Rows.Count > 0)
                {
                    Session["dtOutputTrades"] = (DataTable)dtOutputTrades;
                    gvOutput.DataSource = Session["dtOutputTrades"];
                    gvOutput.DataBind();

                    Session["dtPlurima10"] = (DataTable)dtPlurima10;
                    gvPlurima10.DataSource = Session["dtPlurima10"];
                    gvPlurima10.DataBind();

                    Session["dtPlurimaVB"] = (DataTable)dtPlurimaVB;
                    gvPlurimaVB.DataSource = Session["dtPlurimaVB"];
                    gvPlurimaVB.DataBind();
                }
            }
        }

        private void CreaRigaPlurima(string Conto, string DescrizioneConto, string Currency, double RBCValue, double GuardianValue, DataTable dtPlurima)
        {
            if (!String.IsNullOrEmpty(Conto))
            {
                DataRow drPlurima = dtPlurima.NewRow();
                drPlurima["Conto"] = Conto;
                drPlurima["Descrizione"] = DescrizioneConto;
                drPlurima["Currency"] = Currency;
                drPlurima["RBC"] = RBCValue;
                drPlurima["Guardian"] = GuardianValue;
                dtPlurima.Rows.Add(drPlurima);
            }
        }

        private void CreaRiga(string currency, string cod_rap, DataRow rigaInput, string cod_dep_liq, double diffValori)
        {
            DataRow dr1 = dtOutputTrades.NewRow();

            dr1["spuntato"] = "S";
            dr1["data_ope"] = DateTime.ParseExact(rigaInput["BusinessDate"].ToString(), "yyyyMMdd", CultureInfo.InvariantCulture).ToString("dd.MM.yyyy");
            dr1["data_ins"] = DateTime.ParseExact(rigaInput["BusinessDate"].ToString(), "yyyyMMdd", CultureInfo.InvariantCulture).ToString("dd.MM.yyyy");
            dr1["data_val"] = DateTime.ParseExact(rigaInput["BusinessDate"].ToString(), "yyyyMMdd", CultureInfo.InvariantCulture).ToString("dd.MM.yyyy");
            if (diffValori <= 0) dr1["cod_ope"] = "DEBTMAR";
            else dr1["cod_ope"] = "CREDMAR";
            dr1["cod_rap"] = cod_rap;
            //string cod_tit = execSP_Scalar("SELECT  t.cod_tit FROM tmppostit2 tmp2 LEFT JOIN tit t ON (t.cod_tit = tmp2.cod_tit) LEFT JOIN rap r ON (r.cod_rap = tmp2.cod_rap) WHERE  r.cod_rap = '" + cod_rap + "' and t.cod_div = '" + currency + "' and(t.options = 'S' or t.cod_tiptit like 'O1%') AND r.cod_sta in ('ATTIVO', 'PENDING') LIMIT 1;");
            string cod_tit = execSP_Scalar("SELECT  t.cod_tit FROM tra LEFT JOIN tit t ON (t.cod_tit = tra.cod_tit) LEFT JOIN rap r ON (r.cod_rap = tra.cod_rap) WHERE  r.cod_rap = '" + cod_rap + "' and t.cod_div = '" + currency + "' and (t.options = 'S' or t.cod_tiptit like 'O1%') AND r.cod_sta in ('ATTIVO', 'PENDING') ORDER BY t.data_ins desc LIMIT 1;");
            dr1["cod_tit"] = cod_tit;
            dr1["cod_div_tit"] = currency;
            dr1["cod_ctp"] = "RBEF";
            dr1["cod_dep_liq"] = cod_dep_liq;
            dr1["qta"] = diffValori;
            dr1["ctv_tit_dn"] = diffValori;
            dr1["ctv_tot_dn"] = diffValori;
            dr1["ctv_tit_dr"] = diffValori;
            dr1["ctv_tot_dr"] = diffValori;

            dtOutputTrades.Rows.Add(dr1);
        }

        private static string execSP_Scalar(string query)
        {
            object objResult;
            string result = String.Empty;
            using (var con = new MySqlConnection(Properties.Settings.Default.mySqlConnection))
            {
                var cmd = new MySqlCommand
                {
                    CommandText = query,
                    CommandType = CommandType.Text,
                    Connection = con
                };
                cmd.CommandTimeout = 0;
                con.Open(); // Open the SqlConnection.
                objResult = cmd.ExecuteScalar();

                if (objResult != null) result = objResult.ToString();
            }
            return (result);
        }

        public static DataTable ElaboraTemplateGuardian(string file, string sheetName)
        {
            // Open the Excel file using ClosedXML.
            // Keep in mind the Excel file cannot be open when trying to read it
            using (XLWorkbook workBook = new XLWorkbook(file))
            {
                //Read the first Sheet from Excel file.
                IXLWorksheet workSheet = workBook.Worksheet(1);

                //Create a new DataTable.
                DataTable dt = new DataTable();

                //Loop through the Worksheet rows.
                bool firstRow = true;
                foreach (IXLRow row in workSheet.Rows())
                {
                    //Use the first row to add columns to DataTable.
                    if (firstRow)
                    {
                        foreach (IXLCell cell in row.Cells())
                        {
                            // Definisco tipo di colonna in tabella dt a seconda delle colonne di partenza del template
                            switch (cell.Value.ToString())
                            {
                                //case "qta":
                                //    dt.Columns.Add(cell.Value.ToString(),typeof(Int64));
                                //    break;

                                case "qta":
                                case "prezzo":
                                case "cambiom":
                                case "ctv_tit_dr":
                                case "coma_dep_dr":
                                case "spese_dr":
                                case "ctv_tot_dr":
                                case "imposte_dr":
                                case "ctv_tit_dn":
                                case "imposte_dn":
                                case "ctv_tot_dn":
                                    dt.Columns.Add(cell.Value.ToString(), typeof(double));
                                    break;
                                default:
                                    dt.Columns.Add(cell.Value.ToString());
                                    break;
                            }
                            // dt.Columns.Add(cell.Value.ToString()); 
                        }
                        firstRow = false;
                    }
                    else
                    {
                        //Add rows to DataTable.
                        dt.Rows.Add();
                        int i = 0;

                        foreach (IXLCell cell in row.Cells(row.FirstCellUsed().Address.ColumnNumber, row.LastCellUsed().Address.ColumnNumber))
                        {
                            dt.Rows[dt.Rows.Count - 1][i] = cell.Value.ToString();
                            i++;
                        }
                    }
                }

                return dt;
            }
        }

        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("rbccm_margins_{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)
        {
            if (e.RowType != GridViewRowType.Data) return;

            // Colora in modo differente le righe relative ai due fondi C77261 (10CONV) e C77260 (DB6289)
            if ((string)e.GetValue("AccountID") == "C77261") e.Row.BackColor = Color.LightGray;
            if ((string)e.GetValue("AccountID") == "C77260") e.Row.BackColor = Color.LightSteelBlue;
        }

        protected void gvOutput_DataBinding(object sender, EventArgs e)
        {
            if (Session["dtOutputTrades"] != null)
            {
                gvOutput.DataSource = (DataTable)Session["dtOutputTrades"];
            }
        }

        protected void gvPlurima10_DataBinding(object sender, EventArgs e)
        {
            if (Session["dtPlurima10"] != null)
            {
                gvPlurima10.DataSource = (DataTable)Session["dtPlurima10"];
            }
        }

        protected void gvPlurimaVB_DataBinding(object sender, EventArgs e)
        {
            if (Session["dtPlurimaVB"] != null)
            {
                gvPlurimaVB.DataSource = (DataTable)Session["dtPlurimaVB"];
            }
        }
    }
}