using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Net.Http;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Net;
using System.Text.RegularExpressions;

namespace TrayCheckoutApi.Controllers
{
    public class NotificationController : Controller
    {
        private string tokenTransaction;
        private string xmlResponse;
        private string dataResponse;
        private string resultError;
        private string orderStore;
        private string orderNumber;
        private string totalPaid;
        private string statusId;
        private string statusName;
        private string message;
        private string dataRequest;

        public ActionResult Index()
        {
            resultError = "";
            message = "";
            Response.StatusCode = 206;
            string token = Request["token"];
            if (!String.IsNullOrEmpty(token))
            {
                setTokenTransaction(token);
                ViewData["token_transaction"] = token;
                Notification();
                ViewData["xmlResponse"] = xmlResponse;
                ViewData["dataResponse"] = dataResponse;
                ViewData["orderStore"] = orderStore;
                ViewData["dataRequest"] = dataRequest;
            }
            else
            {
                resultError = "Post inválido!";
            }
            messageService();
            ViewData["httpCode"] = Response.StatusCode;
            return View();
        }

        public ActionResult Form()
        {
            return View();
        }


        private void messageService()
        {
            ViewData["messageColor"] = (resultError.Count() > 0) ? "#ff0000" : "#00ff00";
            ViewData["resultMessage"] = " Notification Transaction (get_by_token) - message_response[" + message + "]!\nHTTP CODE RESPONSE: " + Response.StatusCode + "\n " + resultError;
        }


        private void setTokenTransaction(string token_transaction)
        {
            tokenTransaction = token_transaction;
        }

        private void loadOrder(string transaction_id)
        {
            /* 
             * Dados de teste correspondentes ao Token da Transação consultada - Sugestão para carregar os dados do pedido
             * */
            if (transaction_id == "3094")
            {
                totalPaid = "199.99"; // tipo definido string, para não conflitar na conversão em máquinas com formato diferentes de  pt-BR
                orderNumber = "net_01";
                statusId = "4";
                statusName = "Aguardando Pagamento";
                orderStore = "Pedido: " + orderNumber + " \nTotal: " + totalPaid + "\n Status: " + statusId + "-" + statusName;
            }
        }

        /* Implementar este método para atualizar o Pedido na loja*/
        private void UpdateOrderStatus(string order, string status_id, string status_name)
        {
            orderStore += "\nImplementar rotina para atualizar o status do pedido!\n\n";
            orderStore += "Pedido " + orderNumber + " com status " + statusId + "-" + statusName + " alterado para " + status_id + "-" + status_name;
            statusId = status_id;
            statusName = status_name;
            SendMail();
        }

        private void SendMail()
        {
            orderStore += "\nImplementar rotida para envio de email! ";
        }

        private List<KeyValuePair<string, string>> formData()
        {
            var list = new List<KeyValuePair<string, string>>();
            list.Add(new KeyValuePair<string, string>("token_account", ConfigTrayCheckout.tokenAccount));
            list.Add(new KeyValuePair<string, string>("token_transaction", tokenTransaction));
            return list;
        }

        private void formatForm(List<KeyValuePair<string, string>> form)
        {
            dataRequest = string.Join(",", form.ToArray());
            dataRequest = Regex.Replace(dataRequest, @"[,]", "\n");
        }

        private void Notification()
        {
            var form = formData();
            var content = new FormUrlEncodedContent(form);
            //Método pode ser excluido, utilizado apenas para quebrar linha dos dados do form para melhor visualização
            formatForm(form);
            TrayCheckout tc = new TrayCheckout();
            tc.RequestTrayCheckout(content, ConfigTrayCheckout.UrlGetByToken());
            if (tc.getHttpStatusCode().Equals(HttpStatusCode.OK))
            {
                Response.StatusCode = 200;
                XmlDocument xml = new XmlDocument();
                xmlResponse = tc.getContent();
                xml.LoadXml(xmlResponse);
                tc.setXml(xml);
                if (!tc.sucessResponse())
                {
                    message = tc.getMessage();
                    //atribuir erros para ser exibido
                    resultError += tc.getGeneralError();
                    resultError += tc.getValidationError();
                    Response.StatusCode = 206;
                    return;
                }
                message = tc.getMessage();
                XmlNodeList transaction = xml.GetElementsByTagName("transaction"); 
 
                string order_number = transaction[0]["order_number"].InnerText;
                string transaction_id = transaction[0]["transaction_id"].InnerText;

                loadOrder(transaction_id);
                if (!order_number.Equals(orderNumber))
                {
                    resultError += "Pedido não encontrado ou não corresponde com pedido da loja. Pedido carregado na loja: [" + orderNumber + "]  Pedido recebido TrayCheckout: [" + order_number +"]";
                    Response.StatusCode = 206;
                    return;
                }
                dataTransaction(transaction[0]);
                XmlNodeList payment = xml.GetElementsByTagName("payment");
                string price_original = payment[0]["price_original"].InnerText;
                if (Convert.ToDouble(totalPaid) != Convert.ToDouble(price_original))
                {
                    resultError += "Total pago à Tray é diferente do valor original! [totalPaid] " + totalPaid + " [price_original] " + price_original;
                    Response.StatusCode = 206;
                    return;
                }
                dataPayment(payment[0]);
            }
        }

        private void dataPayment(XmlNode nodePayment)
        {
            string price_payment = nodePayment["price_payment"].InnerText;
            string payment_response = nodePayment["payment_response"].InnerText;
            string url_payment = nodePayment["url_payment"].InnerText;
            string tid = nodePayment["tid"].InnerText;
            string split = nodePayment["split"].InnerText;
            string payment_method_id = nodePayment["payment_method_id"].InnerText;
            string payment_method_name = nodePayment["payment_method_name"].InnerText;
            string linha_digitavel = nodePayment["price_payment"].InnerText;
            dataResponse += "\nMethod: " + payment_method_id + " - " + payment_method_name + " Split: " + split + " Price: " + price_payment;
            dataResponse += "\nResponse: " + payment_response + " \nUrl Payment:" + url_payment;
        }

        private void dataTransaction(XmlNode nodeTransaction)
        {
            string order_number = nodeTransaction["order_number"].InnerText;
            string status_id = nodeTransaction["status_id"].InnerText;
            string status_name = nodeTransaction["status_name"].InnerText;
            string transaction_id = nodeTransaction["transaction_id"].InnerText;
            dataResponse = "\nPedido: " + order_number;
            dataResponse += "\nStatus: " + status_id + " - " + status_name;
            dataResponse += "\nId Transação: " + transaction_id;
            UpdateOrderStatus(order_number, status_id, status_name);
        }
    }
}
