using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.ServiceModel.Activities;
using System.Text;
using System.Web;
using System.Web.Script.Serialization;
using System.Data.SqlClient;
using System.Data;

/// <summary>
/// Summary description for SB_Infinite
/// </summary>
public class SB_Infinite
{
	public SB_Infinite()
	{
		//
		// TODO: Add constructor logic here
		//
	}
    public static string ivStr = "1234567812345678";
    public static string keyStr = "ORAgaBOBNgSbgIpayPOStCe1";//"PPDgaEDvEuHtuIfyoFXZrCe2";
    public static string AgentVPN = "SBPD0221005096";//"SBIN11000055"
    public static string FetchURL = "https://api.bsphcl.co.in/sbfgexternal/rest/fetchBillDetails/";//"https://bpdclcis.mpower.in/fgexternal/rest/fetchBillDetails/"
    public static string PostingURL = "https://api.bsphcl.co.in/sbfgexternal/rest/billPaymentPosting/";// "https://bpdclcis.mpower.in/fgexternal/rest/billPaymentPosting/";
    public static string PaymentStatusURL = "https://api.bsphcl.co.in/sbfgexternal/rest/searchPayment/";
    public static string CancleRequestURL = "https://api.bsphcl.co.in/sbfgexternal/rest/cancelPayment/";
    public static string CancleRequestStatusURL = "https://api.bsphcl.co.in/sbfgexternal/rest/cancelPaymentStatus/";
    public static string usersource = "25102065";
    public static string password = "Christy*890";
    public string Token()
    {
        string dataString = "";
        string token = "";
        try
        {
            //string data = "username=userpayment&password=India@123&grant_type=password&client_id=sso_poc"; //Testing
            string data = "username="+ usersource + "&password="+ password + "&grant_type=password&client_id=sso_poc";
            string headXML = "";
            string URL = "https://api.bsphcl.co.in/sbauth/realms/TPS/protocol/openid-connect/token";
            //string URL = "https://bpdclcis.mpower.in/auth/realms/SSO/protocol/openid-connect/token"; //Testing
            System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
            byte[] bytes = encoding.GetBytes(data);
            const System.Security.Authentication.SslProtocols _Tls12 = (System.Security.Authentication.SslProtocols)0x00000C00;
            const SecurityProtocolType Tls12 = (SecurityProtocolType)_Tls12;
            ServicePointManager.SecurityProtocol = Tls12;
            HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(URL);
            httpRequest.Method = "POST";
            httpRequest.AuthenticationLevel = System.Net.Security.AuthenticationLevel.MutualAuthRequired;
            httpRequest.ContentType = "application/x-www-form-urlencoded";
            httpRequest.ContentLength = bytes.Length;
            using (Stream stream = httpRequest.GetRequestStream())
            {
                stream.Write(bytes, 0, bytes.Length);
                stream.Close();
            }
            HttpWebResponse response = (HttpWebResponse)httpRequest.GetResponse();
            Stream s = (Stream)response.GetResponseStream();
            StreamReader readStream = new StreamReader(s);
            dataString = readStream.ReadToEnd();
            response.Close();
            s.Close();
            readStream.Close();
            if (dataString != "")
            {
                JObject joResponse = JObject.Parse(dataString);
                token = Convert.ToString((JValue)joResponse["access_token"]);

            }
        }
        catch (Exception ex)
        {
            token = "";
        }
        return token;
    }

    public BO_Infinite.InfiniteResponse CancleRequestStatus(string ConsumerId, string CancleRefNo)
    {
        string cancleRequestId = "";
        string json = "";
        BO_Infinite.InfiniteResponse paymentReceipt = new BO_Infinite.InfiniteResponse();
        try
        {
            json = new JavaScriptSerializer().Serialize(new
            {
                scno = ConsumerId,
                cancelRequestNo = CancleRefNo
            });
            string data = EncryptTextAES(json);
            string jsonEnc = new JavaScriptSerializer().Serialize(new
            {
                request = data
            });

            string decResponse = PostData(jsonEnc, CancleRequestStatusURL);

            InsertServiceRequestResponseLog("CancleRequestStatus", json, decResponse);


            if (decResponse != "")
            {
                paymentReceipt = JsonConvert.DeserializeObject<BO_Infinite.InfiniteResponse>(decResponse);

            }

        }
        catch (Exception ex)
        {
            InsertServiceRequestResponseLog("CheckCancleStatus", json, ex.Message);
        }
        return paymentReceipt;
    }
    public string CancleRequest(string ConsumerId, string TxnId, string proNo)
    {
        string cancleRequestId = "";
        string json = "";
        try
        {
            json = new JavaScriptSerializer().Serialize(new
            {
                scno = ConsumerId,
                paymentReferenceNumber = TxnId,
                prno = proNo
            });
            string data = EncryptTextAES(json);
            string jsonEnc = new JavaScriptSerializer().Serialize(new
            {
                request = data
            });

            string decResponse = PostData(jsonEnc, CancleRequestURL);

            InsertServiceRequestResponseLog("CancleRequest", json, decResponse);

            BO_Infinite.InfiniteResponse paymentReceipt = new BO_Infinite.InfiniteResponse();
            if (decResponse != "")
            {
                paymentReceipt = JsonConvert.DeserializeObject<BO_Infinite.InfiniteResponse>(decResponse);

                if (paymentReceipt.status.ToUpper() == "S" /*&& Convert.ToString(paymentReceipt.BSPDCL_Receipt_No) == ""*/)
                {
                    cancleRequestId = paymentReceipt.cancelRequestNo;

                }
                else
                {
                    cancleRequestId = "";
                }
            }

        }
        catch (Exception ex)
        {
           InsertServiceRequestResponseLog("ExCancleRequest", json, ex.Message);
        }
        return cancleRequestId;
    }
    public string CheckStatus(string ConsumerId, string TxnId, string PaymentMode)
    {
        string billNo = "";
        string json = "";
        try
        {
            json = new JavaScriptSerializer().Serialize(new
            {
                scno = ConsumerId,
                paymentReferenceNumber = TxnId,
                PaymentSource = usersource
            });
            string data = EncryptTextAES(json);
            string jsonEnc = new JavaScriptSerializer().Serialize(new
            {
                request = data
            });

            string decResponse = PostData(jsonEnc, PaymentStatusURL);
            InsertServiceRequestResponseLog("CheckStatus", json, decResponse);

            //webApiTokenAuthentication.Services.Common objInsertLog = new Common();
            //objInsertLog.InsertServiceRequestResponseLog("InfinitFetchBill", json.ToString(), decResponse.ToString(), ConsumerId, "", "");

            BO_Infinite.InfiniteResponse paymentReceipt = new BO_Infinite.InfiniteResponse();
            if (decResponse != "")
            {
                paymentReceipt = JsonConvert.DeserializeObject<BO_Infinite.InfiniteResponse>(decResponse);

                if (paymentReceipt.status!=null && paymentReceipt.status.ToUpper() == "S" /*&& Convert.ToString(paymentReceipt.BSPDCL_Receipt_No) == ""*/)
                {
                    billNo = paymentReceipt.prno;

                }
                else
                {
                    billNo = "";
                }
            }

        }
        catch (Exception ex)
        {
            //SB_Infinite objSB = new SB_Infinite();
            InsertServiceRequestResponseLog("CheckStatus", json, ex.Message);
        }
        return billNo;
    }
    public string PostingWalletPayment(string CANumber, string TransactionID, string Amount, string PaymentMode, string CompantCode)
    {

        string TransactionTime = System.DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");

        string SPDCLReceiptNo = "";
        try
        {
            if (true)
            {
                //post bill request

                string paymentcode = "13";
                if (PaymentMode.ToUpper() == "CASH")
                    paymentcode = "01";
                if (PaymentMode.ToUpper() == "NEFT")
                    paymentcode = "08";
                if (PaymentMode.ToUpper() == "IMPS")
                    paymentcode = "09";
                if (PaymentMode.ToUpper() == "CARD")
                    paymentcode = "14";
                if (PaymentMode.ToUpper() == "UPI")
                    paymentcode = "12";

                string json = "{\"scno\":\"" + CANumber + "\",\"paymentTransactionNumber\":\"" + TransactionID + "\",\"paidAmount\":\"" + Amount + "\",\"paymentMode\":\"" + paymentcode + "\",\"paymentSource\":\"" + usersource + "\",\"paymentDate\":\"" + TransactionTime + "\",\"discom\":\"North Bihar Power Distribution Company Ltd\",\"typeOfPayment\":\"WP\",\"agentVAN\":\"" + AgentVPN + "\"}";

                string data = EncryptTextAES(json);
                string jsonEnc = new JavaScriptSerializer().Serialize(new
                {
                    request = data
                });

                string decResponse = PostData(jsonEnc, PostingURL);
                SB_Infinite objSB = new SB_Infinite();
                objSB.InsertServiceRequestResponseLog("WalletPost", json, decResponse);
                //webApiTokenAuthentication.Services.Common objInsertLog = new Common();
                //objInsertLog.InsertServiceRequestResponseLog("InfinitPostiingCP", json.ToString(), decResponse.ToString(), objPaymentRequest.TransactionID, "", "");




            }


        }
        catch (Exception ex)
        {

        }

        return SPDCLReceiptNo;
    }
    public string PostingBillPayment(string CANumber, string TransactionID, string Amount, string PaymentMode, string CompantCode, string TransactionTime)
    {

        //string TransactionTime = System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

        string SPDCLReceiptNo = "";
        string json = "";
        try
        {
            if (true)
            {
                //post bill request

                string paymentcode = "10";
                if (PaymentMode.ToUpper() == "CASH")
                    paymentcode = "01";
                if (PaymentMode.ToUpper() == "NEFT")
                    paymentcode = "08";
                if (PaymentMode.ToUpper() == "IMPS")
                    paymentcode = "09";
                if (PaymentMode.ToUpper() == "CARD")
                    paymentcode = "14";
                if (PaymentMode.ToUpper() == "UPI")
                    paymentcode = "12";

                json = "{\"scno\":\"" + CANumber + "\",\"paymentTransactionNumber\":\"" + TransactionID + "\",\"paidAmount\":\"" + Amount + "\",\"paymentMode\":\"" + paymentcode + "\",\"paymentSource\":\""+ usersource + "\",\"paymentDate\":\"" + TransactionTime + "\",\"discom\":\"South Bihar Power Distribution Company Ltd\",\"typeOfPayment\":\"CP\",\"agentVAN\":\"" + AgentVPN + "\"}";

                string data = EncryptTextAES(json);
                string jsonEnc = new JavaScriptSerializer().Serialize(new
                {
                    request = data
                });

                string decResponse = PostData(jsonEnc, PostingURL);

                InsertServiceRequestResponseLog("ReBillPost", json, decResponse);

                BO_Infinite.InfiniteResponse paymentReceipt = new BO_Infinite.InfiniteResponse();
                if (decResponse != "")
                {
                    paymentReceipt = JsonConvert.DeserializeObject<BO_Infinite.InfiniteResponse>(decResponse);

                    if (paymentReceipt.status.ToUpper() == "S" /*&& Convert.ToString(paymentReceipt.BSPDCL_Receipt_No) == ""*/)
                    {
                        SPDCLReceiptNo = paymentReceipt.prno;
                    }

                }


            }


        }
        catch (Exception ex)
        {
            SB_Infinite objSB = new SB_Infinite();
            objSB.InsertServiceRequestResponseLog("ReBillPost", json, ex.Message);
        }

        return SPDCLReceiptNo;
    }

    public void InsertServiceRequestResponseLog(string MethodName, string RequestLog, string ResponseLog)
    {
        try
        {
            SqlParameter[] warlock = new SqlParameter[]
            {
                new SqlParameter("@MethodName", MethodName),
                new SqlParameter("@RequestLog", RequestLog),
                new SqlParameter("@ResponseLog", ResponseLog)
            };
            SqlHelper.ExecuteNonQuery(SqlHelper.mainConnectionString, CommandType.StoredProcedure, "usp_Insert_ServiceRequestResponseLog", warlock);
        }
        catch (Exception ex)
        {
            throw ex;

        }
    }
    
    public string PostData(string data, string URL)
    {

        string result = "";
        string finalResult = "";
        string GetToken = Token();
        var httpWebRequest = (HttpWebRequest)WebRequest.Create(URL);
        httpWebRequest.ContentType = "application/json";
        httpWebRequest.Method = "POST";
        httpWebRequest.Headers.Add("Authorization", "Bearer " + GetToken);
        using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
        {

            streamWriter.Write(data);
            streamWriter.Flush();
            streamWriter.Close();
        }
        var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
        using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
        {
            result = streamReader.ReadToEnd();
        }
        if (result != "")
        {
            JObject joResponse = JObject.Parse(result);
            string encdata = Convert.ToString((JValue)joResponse["response"]);
            finalResult = DecryptTextAES(encdata);
        }
        return finalResult;
    }

    public static string DecryptTextAES(string cipherText)
    {
        try
        {
            string iv = "1234567812345678"; // Initialization vector
            cipherText = cipherText.Replace(" ", "+"); // Handle spaces (Base64 padding)

            // Convert the Base64 encoded cipherText to byte array
            byte[] encData = Convert.FromBase64String(cipherText);

            byte[] tdesKeyData = Encoding.UTF8.GetBytes(keyStr);
            byte[] myIV = Encoding.UTF8.GetBytes(iv);

            using (Aes aesAlg = Aes.Create())
            {
                aesAlg.Mode = CipherMode.CBC;
                aesAlg.Padding = PaddingMode.PKCS7;
                aesAlg.Key = tdesKeyData;
                aesAlg.IV = myIV;

                using (MemoryStream ms = new MemoryStream())
                {
                    using (CryptoStream cs = new CryptoStream(ms, aesAlg.CreateDecryptor(), CryptoStreamMode.Write))
                    {
                        cs.Write(encData, 0, encData.Length);
                        cs.FlushFinalBlock();
                    }
                    byte[] plainText = ms.ToArray();
                    return Encoding.UTF8.GetString(plainText);
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error during decryption: " + ex.Message);
            return null;
        }
    }
    public string EncryptTextAES(string plainText)
    {
        try
        {
            string iv = ivStr;// "1234567812345678"; // Initialization vector
            byte[] plaintext = Encoding.UTF8.GetBytes(plainText);
            byte[] tdesKeyData = Encoding.UTF8.GetBytes(keyStr);
            byte[] myIV = Encoding.UTF8.GetBytes(iv);

            using (Aes aesAlg = Aes.Create())
            {
                aesAlg.Mode = CipherMode.CBC;
                aesAlg.Padding = PaddingMode.PKCS7;
                aesAlg.Key = tdesKeyData;
                aesAlg.IV = myIV;

                using (MemoryStream ms = new MemoryStream())
                {
                    using (CryptoStream cs = new CryptoStream(ms, aesAlg.CreateEncryptor(), CryptoStreamMode.Write))
                    {
                        cs.Write(plaintext, 0, plaintext.Length);
                        cs.FlushFinalBlock();
                    }
                    byte[] cipherText = ms.ToArray();
                    return Convert.ToBase64String(cipherText);
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error: " + ex.Message);
            return null;
        }
    }
    public string Encrypt(string PlainText)
    {
        RijndaelManaged aes = new RijndaelManaged();
        aes.BlockSize = 128;
        aes.KeySize = 256;

        // It is equal in java 
        /// Cipher _Cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");    
        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.PKCS7;

        byte[] keyArr = ASCIIEncoding.UTF8.GetBytes(keyStr);
        byte[] KeyArrBytes32Value = new byte[32];
        Array.Copy(keyArr, KeyArrBytes32Value, 32);

        // Initialization vector.   
        // It could be any value or generated using a random number generator.
        byte[] ivArr = ASCIIEncoding.UTF8.GetBytes(ivStr);
        byte[] IVBytes16Value = new byte[16];
        Array.Copy(ivArr, IVBytes16Value, 16);

        aes.Key = KeyArrBytes32Value;
        aes.IV = IVBytes16Value;

        ICryptoTransform encrypto = aes.CreateEncryptor();

        byte[] plainTextByte = ASCIIEncoding.UTF8.GetBytes(PlainText);
        byte[] CipherText = encrypto.TransformFinalBlock(plainTextByte, 0, plainTextByte.Length);
        return Convert.ToBase64String(CipherText);
    }

    public static string Decrypt(string CipherText)
    {
        RijndaelManaged aes = new RijndaelManaged();
        aes.BlockSize = 128;
        aes.KeySize = 256;

        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.PKCS7;

        byte[] keyArr = ASCIIEncoding.UTF8.GetBytes(keyStr);
        byte[] KeyArrBytes32Value = new byte[
            32
        ];
        Array.Copy(keyArr, KeyArrBytes32Value,
        32);

        // Initialization vector.   
        // It could be any value or generated using a random number generator.
        byte[] ivArr = ASCIIEncoding.UTF8.GetBytes(ivStr);
        byte[] IVBytes16Value = new byte[
            16
        ];
        Array.Copy(ivArr, IVBytes16Value,
        16);

        aes.Key = KeyArrBytes32Value;
        aes.IV = IVBytes16Value;

        ICryptoTransform decrypto = aes.CreateDecryptor();

        byte[] encryptedBytes = Convert.FromBase64CharArray(CipherText.ToCharArray(),
        0, CipherText.Length);
        byte[] decryptedData = decrypto.TransformFinalBlock(encryptedBytes,
        0, encryptedBytes.Length);
        return ASCIIEncoding.UTF8.GetString(decryptedData);
    }
}