using GlobalPayments.Api.Terminals.Abstractions;
using GlobalPayments.Api.Terminals.Ingenico;
using GlobalPayments.Api.Terminals.Ingenico.Requests;
using GlobalPayments.Api.Terminals.Ingenico.Responses;
using GlobalPaymentsTestApp.Forms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace GlobalPaymentsTestApp.Control {
    public partial class ResponseControl : UserControl {

        private Receipt _receiptForm;
        private string _receipt;

        public ResponseControl() {
            InitializeComponent();
        }

        public ResponseControl(PATRequest request) {
            InitializeComponent();
            Clear();
            ParseTransactionOutcome(request);
        }

        public ResponseControl(IDeviceResponse response) {
            InitializeComponent();
            Clear();
            ParseResponse(response);
        }

        public ResponseControl(ITerminalReport report, int i) {
            InitializeComponent();
            Clear();
            ParseReport(report, i);
        }

        public ResponseControl(ITerminalResponse response) {
            InitializeComponent();
            Clear();
            ParseTerminalResponse(response);
        }

        public ResponseControl(StateResponse response) {
            InitializeComponent();
            Clear();
            ParseStateResponse(response);
        }

        public void Clear() {
            Invoker.SetTextBox(txtEPoSNumber, string.Empty);
            Invoker.SetTextBox(txtTransactionStatus, string.Empty);
            Invoker.SetTextBox(txtAmountResp, string.Empty);
            Invoker.SetTextBox(txtPayment, string.Empty);
            Invoker.SetTextBox(txtCurrencyResp, string.Empty);
            Invoker.SetTextBox(txtPrivDataResp, string.Empty);
            Invoker.SetTextBox(txtTransactionStatus, string.Empty);
            Invoker.SetRichTextBox(txtRawResponse, string.Empty);

            Invoker.SetTextBox(txtAuthCode, string.Empty);
            Invoker.SetTextBox(txtCashbackAmt, string.Empty);
            Invoker.SetTextBox(txtGratuityAmt, string.Empty);
            Invoker.SetTextBox(txtFinalTxnAmt, string.Empty);
            Invoker.SetTextBox(txtAvailableAmt, string.Empty);
            Invoker.SetTextBox(txtPaymentMethod, string.Empty);
            Invoker.SetTextBox(txtTxnSubType, string.Empty);
            Invoker.SetTextBox(txtSplitSaleAmt, string.Empty);
            Invoker.SetTextBox(txtDCCAmt, string.Empty);
            Invoker.SetTextBox(txtDCCCurrency, string.Empty);
            Invoker.SetTextBox(txtDCCStatus, string.Empty);
            Invoker.SetTextBox(txtTableId, string.Empty);

            Invoker.SetRichTextBox(txtRawResponse, false);
            Invoker.SetButton(btnReceipt, false);
        }

        private void ParseTransactionOutcome(PATRequest request) {
            decimal? amount = decimal.Parse(request.TransactionOutcome.Amount) / 100;
            TransactionOutcomeRequest outcome = request.TransactionOutcome;

            Invoker.SetTextBox(txtEPoSNumber, "00");
            Invoker.SetTextBox(txtTransactionStatus, outcome.Status);
            Invoker.SetTextBox(txtAmountResp, amount);
            Invoker.SetTextBox(txtPayment, "0");
            Invoker.SetTextBox(txtCurrencyResp, outcome.CurrencyCode);
            Invoker.SetTextBox(txtPrivDataResp, outcome.PrivateData);
            Invoker.SetRichTextBox(txtRawResponse, outcome.ToString());
            Invoker.SetRichTextBox(txtRawResponse, true);

            Invoker.SetTextBox(txtAuthCode, outcome.RepField.AuthorizationCode);
            Invoker.SetTextBox(txtCashbackAmt, outcome.RepField.CashbackAmount != null ? outcome.RepField.CashbackAmount.Value.ToString("n2") : null);
            Invoker.SetTextBox(txtGratuityAmt, outcome.RepField.GratuityAmount != null ? outcome.RepField.GratuityAmount.Value.ToString("n2") : null);
            Invoker.SetTextBox(txtFinalTxnAmt, outcome.RepField.FinalAmount != null ? outcome.RepField.FinalAmount.Value.ToString() : null);
            Invoker.SetTextBox(txtAvailableAmt, outcome.RepField.AvailableAmount != null ? outcome.RepField.AvailableAmount.Value.ToString("n2") : null);
            Invoker.SetTextBox(txtPaymentMethod, outcome.RepField.PaymentMethod.ToString());
            Invoker.SetTextBox(txtTxnSubType, outcome.RepField.TransactionSubType.ToString());
            Invoker.SetTextBox(txtSplitSaleAmt, outcome.RepField.SplitSaleAmount != null ? outcome.RepField.SplitSaleAmount.Value.ToString("n2") : null);
            Invoker.SetTextBox(txtDCCAmt, outcome.RepField.DccAmount != null ? outcome.RepField.DccAmount.Value.ToString("n2") : null);
            Invoker.SetTextBox(txtDCCCurrency, outcome.RepField.DccCode);
            Invoker.SetTextBox(txtDCCStatus, outcome.RepField.DccStatus.ToString());
            Invoker.SetTextBox(txtTableId, outcome.RepField.TableId.ToString());
        }

        private void ParseResponse(IDeviceResponse response) {
            Invoker.SetTextBox(txtEPoSNumber, response.ReferenceNumber);
            Invoker.SetTextBox(txtTransactionStatus, response.Status);
            Invoker.SetTextBox(txtAmountResp, ((IngenicoTerminalResponse)response).TransactionAmount);
            Invoker.SetTextBox(txtPayment, ((IngenicoTerminalResponse)response).PaymentMode);
            Invoker.SetTextBox(txtCurrencyResp, ((IngenicoTerminalResponse)response).CurrencyCode);
            Invoker.SetTextBox(txtPrivDataResp, ((IngenicoTerminalResponse)response).PrivateData);
            Invoker.SetTextBox(txtFinalTxnAmt, ((IngenicoTerminalResponse)response).FinalTransactionAmount);
            Invoker.SetTextBox(txtDCCAmt, ((IngenicoTerminalResponse)response).DccAmount);
            Invoker.SetTextBox(txtDCCCurrency, ((IngenicoTerminalResponse)response).DccCurrency);
            Invoker.SetTextBox(txtDCCStatus, ((IngenicoTerminalResponse)response).DccStatus);
            Invoker.SetTextBox(txtSplitSaleAmt, ((IngenicoTerminalResponse)response).SplitSaleAmount);
            Invoker.SetTextBox(txtTxnSubType, ((IngenicoTerminalResponse)response).TransactionSubType);
            Invoker.SetTextBox(txtTableId, ((IngenicoTerminalResponse)response).TableId);
            Invoker.SetRichTextBox(txtRawResponse, response.ToString());
            Invoker.SetRichTextBox(txtRawResponse, true);

            if (!string.IsNullOrEmpty(((IngenicoTerminalResponse)response).Receipt)) {
                Invoker.SetButton(btnReceipt, true);
                _receipt = ((IngenicoTerminalResponse)response).Receipt;
            }
        }

        private void ParseReport(ITerminalReport report, int i) {
            Invoker.SetTextBox(txtEPoSNumber, report.ReferenceNumber);
            Invoker.SetTextBox(txtTransactionStatus, report.Status);

            if (i == 0) {
                Invoker.SetTextBox(txtFinalTxnAmt, ((ReportResponse)report).FinalTransactionAmount);
                Invoker.SetTextBox(txtPayment, ((ReportResponse)report).PaymentMode);
                Invoker.SetTextBox(txtCurrencyResp, ((ReportResponse)report).CurrencyCode);
                Invoker.SetTextBox(txtPrivDataResp, ((ReportResponse)report).PrivateData);
                Invoker.SetTextBox(txtDCCAmt, ((ReportResponse)report).DccAmount);
                Invoker.SetTextBox(txtDCCCurrency, ((ReportResponse)report).DccCurrency);
                Invoker.SetTextBox(txtDCCStatus, ((ReportResponse)report).DccStatus);
                Invoker.SetTextBox(txtSplitSaleAmt, ((ReportResponse)report).SplitSaleAmount);
                Invoker.SetTextBox(txtTxnSubType, ((ReportResponse)report).TransactionSubType);
                Invoker.SetTextBox(txtTableId, ((ReportResponse )report).TableId);
            } else {
                Invoker.SetTextBox(txtFinalTxnAmt, ((IngenicoTerminalReportResponse)report).FinalTransactionAmount);
                Invoker.SetTextBox(txtPayment, ((IngenicoTerminalReportResponse)report).PaymentMode);
                Invoker.SetTextBox(txtCurrencyResp, ((IngenicoTerminalReportResponse)report).CurrencyCode);
                Invoker.SetTextBox(txtPrivDataResp, ((IngenicoTerminalReportResponse)report).PrivateData);
                Invoker.SetTextBox(txtDCCAmt, ((IngenicoTerminalReportResponse)report).DccAmount);
                Invoker.SetTextBox(txtDCCCurrency, ((IngenicoTerminalReportResponse)report).DccCurrency);
                Invoker.SetTextBox(txtDCCStatus, ((IngenicoTerminalReportResponse)report).DccStatus);
                Invoker.SetTextBox(txtSplitSaleAmt, ((IngenicoTerminalReportResponse)report).SplitSaleAmount);
                Invoker.SetTextBox(txtTxnSubType, ((IngenicoTerminalReportResponse)report).TransactionSubType);
                Invoker.SetTextBox(txtTableId, ((IngenicoTerminalReportResponse)report).TableId);
            }
            Invoker.SetRichTextBox(txtRawResponse, report.ToString());
            Invoker.SetRichTextBox(txtRawResponse, true);
        }

        private void ParseTerminalResponse(ITerminalResponse response) {
            Invoker.SetTextBox(txtEPoSNumber, response.ReferenceNumber);
            Invoker.SetTextBox(txtTransactionStatus, ((IngenicoTerminalResponse)response).Status);
            Invoker.SetTextBox(txtAmountResp, response.TransactionAmount);
            Invoker.SetTextBox(txtPayment, ((IngenicoTerminalResponse)response).PaymentMode);
            Invoker.SetTextBox(txtCurrencyResp, ((IngenicoTerminalResponse)response).CurrencyCode);
            Invoker.SetTextBox(txtPrivDataResp, ((IngenicoTerminalResponse)response).PrivateData);
            Invoker.SetTextBox(txtAuthCode, response.AuthorizationCode);
            Invoker.SetTextBox(txtCashbackAmt, response.CashBackAmount);
            Invoker.SetTextBox(txtGratuityAmt, response.TipAmount);
            Invoker.SetTextBox(txtFinalTxnAmt, ((IngenicoTerminalResponse)response).FinalTransactionAmount);
            Invoker.SetTextBox(txtAvailableAmt, response.BalanceAmount);
            Invoker.SetTextBox(txtPaymentMethod, response.PaymentType);
            Invoker.SetTextBox(txtTxnSubType, ((IngenicoTerminalResponse)response).TransactionSubType);
            Invoker.SetTextBox(txtSplitSaleAmt, ((IngenicoTerminalResponse)response).SplitSaleAmount);
            Invoker.SetTextBox(txtDCCAmt, ((IngenicoTerminalResponse)response).DccAmount);
            Invoker.SetTextBox(txtDCCCurrency, ((IngenicoTerminalResponse)response).DccCurrency);
            Invoker.SetTextBox(txtDCCStatus, ((IngenicoTerminalResponse)response).DccStatus);
            Invoker.SetTextBox(txtTableId, ((IngenicoTerminalResponse)response).TableId);
            Invoker.SetRichTextBox(txtRawResponse, response.ToString());
            Invoker.SetRichTextBox(txtRawResponse, true);

            if (!string.IsNullOrEmpty(((IngenicoTerminalResponse)response).Receipt)) {
                Invoker.SetButton(btnReceipt, true);
                _receipt = ((IngenicoTerminalResponse)response).Receipt;
            }
        }

        private void ParseStateResponse(StateResponse response) {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine($"Terminal Status: {response.TerminalStatus}");
            sb.AppendLine();
            sb.AppendLine($"Sales Mode: {response.SalesMode}");
            sb.AppendLine();
            sb.AppendLine($"Capabilities: {response.TerminalCapabilities}");
            sb.AppendLine();
            sb.AppendLine($"Additional Capabilities: {response.AdditionalTerminalCapabilities}");
            sb.AppendLine();
            sb.AppendLine($"App ver. number: {response.AppVersionNumber}");
            sb.AppendLine();
            sb.AppendLine($"Handset number: {response.HandsetNumber}");
            sb.AppendLine();
            sb.AppendLine($"TID: {response.TerminalId}");

            Invoker.SetRichTextBox(txtRawResponse, sb.ToString());
            Invoker.SetRichTextBox(txtRawResponse, true);
        }

        private void btnReceipt_Click(object sender, EventArgs e) {
            _receiptForm = new Receipt(_receipt);
            _receiptForm.Show();
        }
    }
}
