using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Newtonsoft.Json;
using TaxProGST.API;
using TaxProGST.JsonModels;

namespace TaxProGSTApiWinFormsDemo
{
    public partial class frmGSTR1Api : Form
    {
        GSTSession GstSession = new GSTSession();
        public frmGSTR1Api()
        {
            try
            {
                InitializeComponent();

            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        private void frmGSTR1Api_Load(object sender, EventArgs e)
        {
            try
            {
                GstSession.ApiSetting = Shared.LoadAPISetting();
                GstSession.ApiLoginDetails = Shared.LoadAPILoginDetails();
                if(GstSession.ApiLoginDetails != null)
                {
                    txtGSTUserID.Text = GstSession.ApiLoginDetails?.GstPortalUserID ?? "";
                    txtGSTIN.Text = GstSession.ApiLoginDetails?.GSTIN ?? "";
                }
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        private void btnBrowseGstr1Json_Click(object sender, EventArgs e)
        {
            OpenFileDialog FileDialog = new OpenFileDialog();
            FileDialog.Filter = "GSTR-1 JSon Files (*.json)|*.json";  //Set filters
            FileDialog.FilterIndex = 1;          //Specify default filter
            if(FileDialog.ShowDialog() == DialogResult.Cancel)
                return;
            txtGSTR1Json.Text = FileDialog.FileName;
        }

        private void cboSignType_SelectedIndexChanged(object sender, EventArgs e)
        {
            if(cboSignType.Text == "EVC")
            {
                btnEVCOTP.Enabled = true;
                txtEVCOTP.ReadOnly = false;
            }
            else
            {
                btnEVCOTP.Enabled = false;
                txtEVCOTP.ReadOnly = true;
            }

        }

        private async void btnUploadData_Click(object sender, EventArgs e)
        {
            try
            {
                txtAPIResponse.Text = "Please wait...";
                await Task.Delay(200);
                if(string.IsNullOrEmpty(txtGSTR1Json.Text))
                    MessageBox.Show("GSTR-1 Json file path not provided");
              
                txtReferenceID.Text = "";
                lblRefID.Text = "";
                #region For Uploading using Json File
                string json = File.ReadAllText(txtGSTR1Json.Text);
               
                TxnRespWithTransAndRefID txnResp = await GSTR1API.SaveGstr1Async(GstSession, txtReturnPeriod.Text, json);
                #endregion
                #region For Upload using object Example for B2B Only
                //Gstr1Json gstr1 = new Gstr1Json();
                //gstr1.gstin = txtGSTIN.Text;
                //gstr1.fp = txtReturnPeriod.Text;
                //gstr1.gt = 0;//Gross Turnover
                //gstr1.cur_gt = 0;//Current Gross Turnover
                //gstr1.version = "GSTXXX";
                //gstr1.hash = "hash";
                //gstr1.b2b = new List<Gstr1Json.B2b>();
                //Gstr1Json.B2b B2BRecord = new Gstr1Json.B2b();
                //B2BRecord.ctin = "27GSPMH0041G1ZZ";
                //B2BRecord.inv = new List<Gstr1Json.B2b.Inv>();
                //Gstr1Json.B2b.Inv B2bInv = new Gstr1Json.B2b.Inv();
                //B2bInv.inum = "INV" + txtReturnPeriod.Text + "001";
                //B2bInv.idt = DateTime.ParseExact("01" + txtReturnPeriod.Text, "dd-mm-yyyy",  System.Globalization.CultureInfo.InvariantCulture);
                //B2bInv.val = 5900;
                //B2bInv.pos = "27";
                //B2bInv.rchrg = "N";
                //B2bInv.inv_typ = "R";
                //B2bInv.itms = new List<Gstr1Json.B2b.Inv.Itm>();
                //Gstr1Json.B2b.Inv.Itm B2BInvItem = new Gstr1Json.B2b.Inv.Itm();
                //B2BInvItem.num = 1;
                //B2BInvItem.itm_det = new Gstr1Json.B2b.Inv.Itm.ItmDet();
                //B2BInvItem.itm_det.rt = 18;
                //B2BInvItem.itm_det.txval = 5000;
                //B2BInvItem.itm_det.camt = 450;
                //B2BInvItem.itm_det.samt = 450;
                //B2BInvItem.itm_det.iamt = 0;
                //B2BInvItem.itm_det.csamt = 0;
                //B2bInv.itms.Add(B2BInvItem);
                //B2BRecord.inv.Add(B2bInv);
                //gstr1.b2b.Add(B2BRecord);
                //TxnRespWithTransAndRefID txnResp = await GSTR1API.SaveGstr1Async(GstSession, txtReturnPeriod.Text, gstr1);

                #endregion

                if (txnResp.IsSuccess)
                {
                    txtReferenceID.Text = txnResp.ReferenceID;
                    lblRefID.Text = txnResp.ReferenceID;
                }
                txtAPIResponse.Text = txnResp.TxnOutcome;
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }

        private async void btnCheckReturnStatus_Click(object sender, EventArgs e)
        {
            try
            {
                txtAPIResponse.Text = "Please wait...";
                await Task.Delay(200);
                TxnRespWithObj<Gstr1ReturnStatusJson> txnResp = await SharedAPI.GetReturnStatusAsync<Gstr1ReturnStatusJson>(GstSession, "GSTR1", txtGSTIN.Text , txtReturnPeriod.Text, lblRefID.Text,true);
                if(txnResp.IsSuccess)
                {
                    txtAPIResponse.Text = txnResp.TxnOutcome;
                    var errReport = txnResp.RespObj.error_report;
                }
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private async void btnDownloadData_Click(object sender, EventArgs e)
        {
            try
            {
                txtAPIResponse.Text = "Please wait...";
                TxnRespWithObj<Gstr1Json> txnResp = new TxnRespWithObj<Gstr1Json>();
                txnResp = await GSTR1API.GetGstr1DataScheduleAsync(GstSession, cboSchedule.Text, "Get " + cboSchedule.Text + " Data", txtGSTIN.Text, txtReturnPeriod.Text, "N", "", "", true);
                if(txnResp.IsSuccess)
                    txtAPIResponse.Text = JsonConvert.SerializeObject(txnResp.RespObj, Formatting.Indented);
                else
                    txtAPIResponse.Text = txnResp.TxnOutcome;


            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private async  void btnDownloadSummary_Click(object sender, EventArgs e)
        {
            try
            {
                txtAPIResponse.Text = "Please wait...";

                #region Method1 to GetSummary
                TxnRespWithPayload txnResp = new TxnRespWithPayload();
                txnResp = await GSTR1API.GetGstr1SummaryPayloadAsync(GstSession, txtGSTIN.Text, txtReturnPeriod.Text, true  );
                if(txnResp.IsSuccess && !string.IsNullOrEmpty(txnResp.ResponsePayload))
                    txtAPIResponse.Text = txnResp.ResponsePayload;
                else
                    txtAPIResponse.Text = txnResp.TxnOutcome;
                #endregion
                #region Or Method2 to GetSummary
                //TxnRespWithObj<GSTR1ReturnJson> txnResp = new TxnRespWithObj<GSTR1ReturnJson>();
                //txnResp = await GSTR1API.GetGstr1SummaryAsync(GstSession, txtGSTIN.Text, txtReturnPeriod.Text , true);
                //txtAPIResponse.Text = txnResp.TxnOutcome;
                #endregion

            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private async void btnSubmitt_Click(object sender, EventArgs e)
        {
            try
            {
                txtAPIResponse.Text = "Please wait...";
                SubmitGSTR jGSTR = new SubmitGSTR();
                jGSTR.gstin = txtGSTIN.Text;
                jGSTR.ret_period = txtReturnPeriod.Text;
                TxnRespWithTransAndRefID txnResp = await SharedAPI.SubmitGSTRReturnWithRefIdAsync(GstSession, "GSTR1", txtReturnPeriod.Text, jGSTR, true);
                if(txnResp.IsSuccess)
                {
                    txtReferenceID.Text = txnResp.ReferenceID;
                    lblRefID.Text = txnResp.ReferenceID;
                }
                txtAPIResponse.Text = txnResp.TxnOutcome;
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private async void btnEVCOTP_Click(object sender, EventArgs e)
        {
            try
            {
                txtAPIResponse.Text = "Please wait...";
                TxnRespWithRefAck txnResp = await AuthAPI.GetEVCOTPAsync(GstSession, txtGSTIN.Text, "R1", txtPAN.Text);
                if(txnResp.IsSuccess)
                    txtAPIResponse.Text = "EVC OTP Send Successfully on Registered Mobile and Email";
                else
                    txtAPIResponse.Text  = "Failed : Response - " + txnResp.TxnOutcome;
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            
        }

        private async void btnFileReturn_Click(object sender, EventArgs e)
        {
            try
            {
                txtAPIResponse.Text = "Please wait...";
                TxnRespWithPayload txnResp;
                TxnRespWithRefAck txtRespWithARN = new TxnRespWithRefAck();
                string strResponsePayload = "";
                txnResp = await GSTR1API.GetGstr1SummaryPayloadAsync(GstSession, txtGSTIN.Text, txtReturnPeriod.Text, true);
                if(txnResp.IsSuccess && !string.IsNullOrEmpty(txnResp.ResponsePayload))
                {
                    strResponsePayload = txnResp.ResponsePayload;
                    txtRespWithARN =  await GSTR1API.FileGstr1WithPayloadAsync(GstSession, txtReturnPeriod.Text, strResponsePayload, cboSignType.Text, txtPAN.Text, true, txtEVCOTP.Text);
                    txtAPIResponse.Text = txtRespWithARN.TxnOutcome;
                }
                else
                    txtAPIResponse.Text = txnResp.TxnOutcome;
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private async void btnGetInvoiceData_Click(object sender, EventArgs e)
        {
            try
            {
                txtAPIResponse.Text = "Please wait...";
                TxnRespWithObj<Gstr1EInvoiceJson> txnResp = new TxnRespWithObj<Gstr1EInvoiceJson>();
                txnResp = await GSTR1API.GetEInvoicesAsync(GstSession, "Get " + cboEInvoiceSchedule.Text + " e-Invoice Data", txtGSTIN.Text, txtReturnPeriod.Text, cboEInvoiceSchedule.Text);
                if(txnResp.IsSuccess)
                    txtAPIResponse.Text = JsonConvert.SerializeObject(txnResp.RespObj, Formatting.Indented);
                else
                    txtAPIResponse.Text = txnResp.TxnOutcome;


            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private async void btnReset_Click(object sender, EventArgs e)
        {
            try
            {
                txtAPIResponse.Text = "Please wait...";
                await Task.Delay(200);
                txtReferenceID.Text = "";
                lblRefID.Text = "";
                TxnRespWithRefID txnResp = await GSTR1API.ResetGstr1Async(GstSession,txtGSTIN.Text, txtReturnPeriod.Text);
                if(txnResp.IsSuccess)
                {
                    txtReferenceID.Text = txnResp.ReferenceID;
                    lblRefID.Text = txnResp.ReferenceID;
                }
                txtAPIResponse.Text = txnResp.TxnOutcome;
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private async void btnValidateHSNSummary_Click(object sender, EventArgs e)
        {
            try
            {
                txtAPIResponse.Text = "Please wait...";
                await Task.Delay(200);
                txtReferenceID.Text = "";
                lblRefID.Text = "";
                TxnResp txnResp = await GSTR1API.ValidateHsnSummaryAsync(GstSession, "Validate HSN Summary", txtGSTIN.Text, txtReturnPeriod.Text);
                if(txnResp.IsSuccess)
                    txtAPIResponse.Text = JsonConvert.SerializeObject(txnResp, Formatting.Indented);
                else
                    txtAPIResponse.Text = txnResp.TxnOutcome;
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private async void btnGenerateSummary_Click(object sender, EventArgs e)
        {
            try
            {
                txtAPIResponse.Text = "Please wait...";
                SubmitGSTR jGSTR = new SubmitGSTR();
                jGSTR.gstin = txtGSTIN.Text;
                jGSTR.ret_period = txtReturnPeriod.Text;
                //For Generating Summary below is mandatory. If this will not pass then instead of Generate Summary Return will be Submitted.
                //Use this carefully
                jGSTR.generate_summary = "Y";
                TxnRespWithTransAndRefID txnResp = await SharedAPI.SubmitGSTRReturnWithRefIdAsync(GstSession, "GSTR1", txtReturnPeriod.Text, jGSTR, true);
                if(txnResp.IsSuccess)
                {
                    txtReferenceID.Text = txnResp.ReferenceID;
                    lblRefID.Text = txnResp.ReferenceID;
                }
                txtAPIResponse.Text = txnResp.TxnOutcome;
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private async void btnProceedToFileOrGenerateSummary_Click(object sender, EventArgs e)
        {
            try
            {
                //GSTR1 version 3.0 APIs have been updated. In this release Submit API will be replaced with Proceed to file (PTF). 
                //Now, on calling the Procced to File API , summary for that return period will be generated. 
                //Unlike Submit where return period freezes after doing submit, after doing Proceed to File user is still allowed to save invoices 
                //and perform PTF again to generate latest summary.
                ////GSTR1 version 3.1 Updated for GSTR-1 Nil Return

                txtAPIResponse.Text = "Please wait...";
                SubmitGSTR jGSTR = new SubmitGSTR();
                jGSTR.gstin = txtGSTIN.Text;
                jGSTR.ret_period = txtReturnPeriod.Text;
                ///Pass below parameter for GSTR-1 Nil Return. In case of Nil Return No need to check Return Status of Ref. ID.
                //jGSTR.isnil = "Y";
                TxnRespWithTransAndRefID txnResp = await SharedAPI.ProceedToFileGSTRAsync(GstSession, "GSTR1", txtReturnPeriod.Text, jGSTR, true);
                if(txnResp.IsSuccess)
                {
                    txtReferenceID.Text = txnResp.ReferenceID;
                    lblRefID.Text = txnResp.ReferenceID;
                }
                txtAPIResponse.Text = txnResp.TxnOutcome;
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            try
            {
                Process.Start("explorer.exe", "https://developer.gst.gov.in/pages/apiportal/data/ReleaseNotes/Release_Notes_HSN_Bifurcation_GSTR1_and_1A_G2B_API.pdf");
            }
            catch
            {

               
            }
        }
    }
}
