﻿using DBControl;
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Text;

namespace MQTT_Client
{
    class GabiaMessenger
    {
        string mAccessToken;

        DateTime mGetAccessTokenTime;

        DBManager DBMan = null;

        int mNumMessages = 0;

        public GabiaMessenger(DBManager manager)
        {
            DBMan = manager;

            mAccessToken = GetAccessToken();
        }

        //public string SendSMS(string authCode, string PHONE_NUM, string SMS_MSG_STR)
        public string
        SendMessageOnly(string PHONE_NUM, string SMS_MSG_STR)
        {
            string inputString = "safewaresms1:" + mAccessToken;
            byte[] baseByte = System.Text.Encoding.UTF8.GetBytes(inputString);
            string base64value = Convert.ToBase64String(baseByte);

            //int n = base64value.Length % 4;
            //for (int i = 0; i < n; i++)
            //    base64value += "=";

            //MessageTextBox.Text += base64value + "\r\n";

            string responseFromServer = string.Empty;

            Debug.WriteLine($"SMS_Length : {SMS_MSG_STR.Length}");

            LogBroker.WriteLine(1, $"SMS_Length : {SMS_MSG_STR.Length}");

            HttpWebResponse response;

            try
            {
                //string postData = "phone=" + PHONE_NUM + "&callback=03151829294&message=" + SMS_MSG_STR + "&refkey=[[RESTAPITEST1549847130]]";
                string postData = "phone=" + PHONE_NUM + "&callback=03151829294&message=" + SMS_MSG_STR + "&refkey=[[RESTAPITEST1549847130]]" + "&is_foreign=Y";

                byte[] byteArray = Encoding.UTF8.GetBytes(postData);

                HttpWebRequest request;

                if(SMS_MSG_STR.Length > 85)
                    request = (HttpWebRequest)WebRequest.Create("https://sms.gabia.com/api/send/lms");
                else
                    request = (HttpWebRequest)WebRequest.Create("https://sms.gabia.com/api/send/sms");

                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";
                request.ContentLength = byteArray.Length;
                request.Headers.Add("Authorization", "Basic " + base64value);
                request.Headers.Add("cache-control", "no-cache ");
                Stream dataStream = request.GetRequestStream();
                dataStream.Write(byteArray, 0, byteArray.Length);
                dataStream.Close();

                response = (HttpWebResponse)request.GetResponse();

                using (dataStream = response.GetResponseStream())
                {
                    StreamReader reader = new StreamReader(dataStream);
                    responseFromServer = reader.ReadToEnd();
                }

                response.Close();
            }
            catch (Exception ex)
            {
                responseFromServer = ex.ToString();
            }

            return responseFromServer;
        }

        public bool
        SendMessage(string id, string PHONE_NUM, string SMS_MSG_STR)
        {
            TimeSpan timeDifference = DateTime.Now - mGetAccessTokenTime;

            if (timeDifference.TotalSeconds > 3500) 
            { 
                RefreshAccessToken();
            }

            mNumMessages++;
            
            string response = SendMessageOnly(PHONE_NUM, SMS_MSG_STR);

            LogBroker.WriteLine(1, $"### SMS-{mNumMessages}");
            //LogBroker.WriteLine(3, SMS_MSG_STR);
            LogBroker.WriteLine(3, $"  -> {PHONE_NUM}");
            LogBroker.WriteLine(1, response);

            DBMan.InsertMqttMessage($"SMS/{id}", $"{mNumMessages}, {PHONE_NUM} -> {response}");

            if (response.Contains("\"code\":\"200\""))
            {
                LogBroker.WriteLine(1, "SMS, successfully sent.");
                SetSmsLeftToTextBox(response);
                return true;
            }
            else
            {
                RefreshAccessToken();

                response = SendMessageOnly(PHONE_NUM, SMS_MSG_STR);
                
                LogBroker.WriteLine(1, response);

                DBMan.InsertMqttMessage($"SMS/{id}", $"{mNumMessages}, {PHONE_NUM} -> {response}");

                if (response.Contains("\"code\":\"200\""))
                {
                    LogBroker.WriteLine(1, "SMS, successfully sent.");
                    SetSmsLeftToTextBox(response);
                    return true;
                }
                else
                {
                    LogBroker.WriteLine(1, "SMS, not sent.");
                    return false;
                }
            }
        }

        public string
        GetNumberOfRemainingMessages()
        {
            Debug.WriteLine("AccessToken : " + mAccessToken);

            string inputString = "safewaresms1:" + mAccessToken;
            
            byte[] baseByte = System.Text.Encoding.UTF8.GetBytes(inputString);
            
            string base64value = Convert.ToBase64String(baseByte);

            string responseFromServer = string.Empty;

            string[] str;
            string remain = string.Empty;

            HttpWebResponse response;

            try
            {
                //string postData = "undefined=";
                //byte[] byteArray = Encoding.UTF8.GetBytes(postData);

                HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://sms.gabia.com/api/user/info");

                request.Method = "GET";

                request.MediaType = "application/x-www-form-urlencoded"; // + "undefined=";
                //request.ContentLength = byteArray.Length;
                request.Headers.Add("Authorization", "Basic " + base64value);
                request.Headers.Add("cache-control", "no-cache ");

                //Stream dataStream = request.GetRequestStream();
                //dataStream.Write(byteArray, 0, byteArray.Length);
                //dataStream.Close();

                using (response = (HttpWebResponse)request.GetResponse())
                {
                    Stream dataStream = response.GetResponseStream();

                    StreamReader reader = new StreamReader(dataStream);
                    responseFromServer = reader.ReadToEnd();

                    str = responseFromServer.Split(',');

                    if (str.Length > 5)
                    {
                        string[] str2;
                        str2 = str[4].Split(':');
                        if (str2.Length > 1)
                        {
                            if (str2[0] == "\"sms_count\"")
                            {
                                remain = str2[1].Replace("\"", "");
                            }
                        }
                        dataStream.Close();
                    }
                }
                response.Close();
            }
            catch (Exception ex)
            {
                responseFromServer = ex.ToString();
            }

            return remain;
        }

        //public string smsAuthPost()
        private string
        GetAccessToken()
        {
            mGetAccessTokenTime = DateTime.Now;

            // API 키 값.
            // ee44b0ea6f32b53f48b5dec3d14ebdc7
            // safewaresms1:ee44b0ea6f32b53f48b5dec3d14ebdc7 --> c2FmZX....
            string base64value = "c2FmZXdhcmVzbXMxOmVlNDRiMGVhNmYzMmI1M2Y0OGI1ZGVjM2QxNGViZGM3";

            string responseFromServer = string.Empty;
            string postData = "grant_type=client_credentials";

            HttpWebResponse response;

            try
            {
                byte[] byteArray = Encoding.UTF8.GetBytes(postData);

                HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://sms.gabia.com/oauth/token");
                
                request.Method = "POST";

                request.ContentType = "application/x-www-form-urlencoded";
                request.ContentLength = byteArray.Length;

                request.Headers.Add("Authorization", "Basic " + base64value);
                request.Headers.Add("cache-control", "no-cache ");

                Stream dataStream = request.GetRequestStream();
                dataStream.Write(byteArray, 0, byteArray.Length);
                dataStream.Close();

                response = (HttpWebResponse)request.GetResponse();

                using (dataStream = response.GetResponseStream())
                {
                    StreamReader reader = new StreamReader(dataStream);
                    responseFromServer = reader.ReadToEnd();
                }

                response.Close();
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
                responseFromServer = ex.ToString();
            }

            string retAuthStr = responseFromServer;

            string[] strArr;
            strArr = responseFromServer.Split(',');

            if (strArr.Length > 0)
            {
                string[] strArrSub;
                strArrSub = strArr[0].Split(':');

                if (strArrSub.Length > 0)
                {
                    string enc64Str = strArrSub[1].Replace("\"", "");
                    retAuthStr = enc64Str.Replace("\r", "");
                }
            }

            return retAuthStr;
        }

        private void
        RefreshAccessToken()
        {
            mAccessToken = GetAccessToken();

            LogBroker.WriteLine(1, "Gabia AccessToken, refreshed.");
        }

        private void
        SetSmsLeftToTextBox(string response)
        {
            string[] strArr = response.Split(',');

            for(int i = 0; i < strArr.Length; i++)
            {
                if (strArr[i].Contains("\"AFTER_SMS_QTY\":"))
                {
                    string[] strSubArr = strArr[i].Split(':');

                    string strSmsLeft = strSubArr[1].Replace("\"", "");

                    SmsLeft.SetText(strSmsLeft);
                }
            }
        }
    }
}
