package cordova.plugin.netcontroll.integration;

import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaWebView;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.graphics.Bitmap;
import android.content.Context;
import android.util.Log;
import android.widget.Switch;
import android.widget.Toast;
import android.net.Uri;
import android.content.Intent;
import android.provider.MediaStore;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import androidx.annotation.NonNull;

import android.util.Base64;
// import android.util.Base64.Encoder;
// import android.util.Base64.Decoder;

// import java.util.Base64;
// import java.util.Base64.Encoder;
// import java.util.Base64.Decoder;

import static android.app.Activity.RESULT_OK;

import java.util.HashMap;
import java.util.Map;

//Elgin Plugins
//import com.elgin.e1.Impressora.Termica;
import com.elgin.e1.Impressora.Termica;
import com.elgin.e1.Pagamento.Controller.TipoImpressao;
import com.elgin.e1.Pagamento.ElginPay;

import br.com.setis.interfaceautomacao.Personalizacao;

import javax.security.auth.callback.Callback;

/**
 * This class echoes a string called from JavaScript.
 */
public class ElginSmartPay {

    private static final int FIM_OPERACAO = 0;
    private static final int FIM_IMPRESSAO = 1;
    private static final int FIM_CONFIRMACAO = 2;
    private static final int ERRO_IMPRESSAO = 3;
    private static final int TRANSACAO_PENDENTE = 4;

    //Cordova/Java Params
    private Activity mActivity;
    private Context mContext;
    private CordovaWebView webView;

    //Intents CODES
    private static int REQ_CODE_SELECAOIMAGEM = 1234;

    //CallbacksOnActivityResult
    private CallbackContext selecionarImagemCallbackContext;

    //cutPaper boolean for resultActivity
    private boolean cutPaper = false;

    //USADO PARA ENVIAR E PROCESSAR MENSAGENS
    private Handler handler;

    public void initialize(CordovaInterface cordova, CordovaWebView webView) {
        this.webView = webView;
        mActivity = cordova.getActivity();
        mContext = cordova.getActivity().getApplicationContext();

        //Initialize printer
        Termica.setContext(mActivity);
    }

    public String Teste() {
        return "Result - ElginClass: ok";
    }

    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        if (action.equals("AbreConexaoImpressora")) {
            try {
                JSONObject params = args.getJSONObject(0);

                int tipo = params.getInt("tipo");
                String modelo = params.getString("modelo");
                String conexao = params.getString("conexao");
                int parametro = params.getInt("parametro");

                int result = Termica.AbreConexaoImpressora(tipo, modelo, conexao, parametro);
                callbackContext.success(result);
            } catch (Exception e) {
                callbackContext.error("AbreConexaoImpressora error: " + e.toString());
            }
            return true;
        } else if (action.equals("FechaConexaoImpressora")) {
            try {
                int result = Termica.FechaConexaoImpressora();
                callbackContext.success(result);
            } catch (Exception e) {
                callbackContext.error("FechaConexaoImpressora error: " + e.toString());
            }
            return true;
        } else if (action.equals("AvancaPapel")) {
            try {
                JSONObject params = args.getJSONObject(0);

                int linhas = params.getInt("linhas");

                int result = Termica.AvancaPapel(linhas);

                callbackContext.success(result);
            } catch (Exception e) {
                callbackContext.error("AvancaPapel error: " + e.toString());
            }
            return true;
        } else if (action.equals("Corte")) {
            try {
                JSONObject params = args.getJSONObject(0);

                int avanco = params.getInt("avanco");

                int result = Termica.Corte(avanco);

                callbackContext.success(result);
            } catch (Exception e) {
                callbackContext.error("Corte error: " + e.toString());
            }
            return true;
        } else if (action.equals("ImpressaoTexto")) {
            try {
                JSONObject params = args.getJSONObject(0);

                String dados = params.getString("dados");
                int posicao = params.getInt("posicao");
                int stilo = params.getInt("stilo");
                int tamanho = params.getInt("tamanho");

                int result = Termica.ImpressaoTexto(dados, posicao, stilo, tamanho);
                result = Termica.AvancaPapel(1);
                callbackContext.success(result);
            } catch (Exception e) {
                callbackContext.error("ImpressaoTexto error: " + e.toString());
            }
            return true;
        } else if (action.equals("ImpressaoCodigoBarras")) {
            try {
                JSONObject params = args.getJSONObject(0);

                int tipo = params.getInt("tipo");
                String dados = params.getString("dados");
                int altura = params.getInt("altura");
                int largura = params.getInt("largura");
                int HRI = params.getInt("HRI");

                int result = Termica.ImpressaoCodigoBarras(tipo, dados, altura, largura, HRI);

                callbackContext.success(result);
            } catch (Exception e) {
                callbackContext.error("ImpressaoCodigoBarras error: " + e.toString());
            }
            return true;
        } else if (action.equals("DefinePosicao")) {
            try {
                JSONObject params = args.getJSONObject(0);

                int posicao = params.getInt("posicao");

                int result = Termica.DefinePosicao(posicao);

                callbackContext.success(result);
            } catch (Exception e) {
                callbackContext.error("DefinePosicao error: " + e.toString());
            }
            return true;
        } else if (action.equals("ImpressaoQRCode")) {
            try {
                JSONObject params = args.getJSONObject(0);

                String dados = params.getString("dados");
                int tamanho = params.getInt("tamanho");
                int nivelCorrecao = params.getInt("nivelCorrecao");

                int result = Termica.ImpressaoQRCode(dados, tamanho, nivelCorrecao);

                callbackContext.success(result);
            } catch (Exception e) {
                callbackContext.error("ImpressaoQRCode error: " + e.toString());
            }
            return true;
        } else if (action.equals("ImprimeXMLNFCe")) {
            try {
                JSONObject params = args.getJSONObject(0);

                String dados = params.getString("dados");
                int indexcsc = params.getInt("indexcsc");
                String csc = params.getString("csc");
                int param = params.getInt("param");

                int result = Termica.ImprimeXMLNFCe(dados, indexcsc, csc, param);

                callbackContext.success(result);
            } catch (Exception e) {
                callbackContext.error("ImprimeXMLNFCe error: " + e.toString());
            }
            return true;
        } else if (action.equals("ImprimeXMLSAT")) {
            try {
                JSONObject params = args.getJSONObject(0);

                String dados = params.getString("dados");
                int param = params.getInt("param");

                int result = Termica.ImprimeXMLSAT(dados, param);

                callbackContext.success(result);

            } catch (Exception e) {
                callbackContext.error("ImprimeXMLSAT error: " + e.toString());
            }
            return true;
        } else if (action.equals("AbreGavetaElgin")) {
            try {
                int result = Termica.AbreGavetaElgin();

                callbackContext.success(result);
            } catch (Exception e) {
                callbackContext.error("AbreGavetaElgin error: " + e.toString());
            }
            return true;
        } else if (action.equals("StatusImpressora")) {
            try {
                JSONObject params = args.getJSONObject(0);

                int param = params.getInt("param");

                int result = Termica.StatusImpressora(param);

                callbackContext.success(result);
            } catch (Exception e) {
                callbackContext.error("StatusImpressora error: " + e.toString());
            }
            return true;
        } else if (action.equals("ImprimeImagemBase64")) {
            try {
                JSONObject params = args.getJSONObject(0);
                String base64String = params.getString("base64String");
                int result = 0;
                String base64Image = base64String.split(",")[1];
                byte[] decodedString = Base64.decode(base64Image, Base64.DEFAULT);
                Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
                result = Termica.ImprimeBitmap(decodedByte);
                if (result == 1) {
                    // // //     if (this.cutPaper) {
                    // // //         result = Termica.Corte(avanco);
                    // // //     }
                }
                // // // // callbackContext.success(decodedString);
                callbackContext.success(result);
            } catch (Exception e) {
                callbackContext.error("ImprimeImagemBase64 error: " + e.toString());
            }
            return true;
        } else if (action.equals("ImpressaoTextoNetPrint")) {
            JSONObject params = args.getJSONObject(0);
            try {
                String dados = params.getString("dados");
                Boolean negrito = false;
                try {
                    negrito = params.getBoolean("negrito");
                }catch (Exception ex){
                }

                String html = cordova.plugin.netcontroll.integration.util.NetControllPrinter.ConverterTextoImpressoToHtml(dados, negrito);
                int ret = Termica.AvancaPapel(1);
                if (ret != 0) {
                    callbackContext.error("Erro ao avancar papel: " + ret);
                    return false;
                }
                cordova.plugin.netcontroll.integration.util.NetControllPrinter.ConverterHtmlToBitmap(html, mContext, bitmap -> {
                    if (bitmap != null) {
                        try {
                            int retPrint = Termica.ImprimeBitmap(bitmap);
                            if (retPrint != 0) {
                                callbackContext.error("Erro ao Imprimir bitmap: " + retPrint);
                                return;
                            } else {
                                callbackContext.success("Impresso Ok");
                            }
                        } catch (Exception errorPost) {
                            callbackContext.error("Result - ConverterHtmlToBitmap: " + "Error Detail: " + errorPost);
                        }
                    }
                });
            } catch (Exception e) {
                callbackContext.error("ImpressaoTextoNetPrint error: " + e.toString());
            }
            return true;
        } else if (action.equals("ImpressaoBase64NetPrint")) {
            try{
                JSONObject params = args.getJSONObject(0);
                String base64String = params.getString("base64String");
                Bitmap dadosBmp = cordova.plugin.netcontroll.integration.util.NetControllPrinter.ConverterBase64ToBitmap(base64String);
                //dadosBmp = cordova.plugin.netcontroll.integration.util.NetControllPrinter.ResizeBitmap(dadosBmp, 100);
                int retPrint = Termica.ImprimeBitmap(dadosBmp);
                if (retPrint != 0) {
                    callbackContext.error("Erro ao Imprimir bitmap: " + retPrint);
                } else {
                    callbackContext.success("Impresso Base64 Ok");
                }
            } catch (Exception e){
                callbackContext.error("PrintTesteBase64 error: " + e.toString());
            }
            return true;
        } else if (action.equals("IniciarPagamento")) {
            try {

                
                
                ElginPay pagamento = new ElginPay();
                

                Personalizacao.Builder pb = new Personalizacao.Builder();
                // pb.informaIconeToolbar(new File("/sdcard/ic_launcher_round.png"));  // Altera o ícone
                // pb.informaFonte(new File("/system/fonts/Clockopia.ttf"));           // Altera a fonte
                // pb.informaCorFonte("#FC9F00");                                      // Altera a cor da fonte
                // pb.informaCorFonteTeclado("#FC9F00");                               // Altera a cor da fonte do teclado
                // pb.informaCorFundoToolbar("#FC9F00");                               // Altera a cor do fundo da barra superior
                // pb.informaCorFundoTela("#0C0807");                                  // Altera a cor do fundo da tela
                // pb.informaCorTeclaLiberadaTeclado("#464B4E");                       // Altera a cor da tecla liberada do teclado
                // pb.informaCorFundoTeclado("#1B1A1C");                               // Altera a cor do fundo do teclado
                // pb.informaCorTextoCaixaEdicao("#464B4E");                           // Altera a cor do texto da caixa de edição
                // pb.informaCorSeparadorMenu("#FC9F00");                              // Altera a cor dos separadores do menu
                Personalizacao personalizacao = pb.build(); // Cria o objeto de personalização


                pagamento.setPersonalizacao(personalizacao);

                JSONObject params = args.getJSONObject(0);
                int tipoTransacao = params.getInt("tipoTransacao");
                String valor = params.getString("valor");
                int tipoFinanciamento = params.getInt("tipoFinanciamento");
                int numeroParcelas = params.getInt("numeroParcelas");
                int tipoImpressao = params.getInt("tipoImpressao");

                switch (tipoImpressao) {
                    case 0:
                        pagamento.setTipoImpressao(TipoImpressao.IMPRESSAO_PADRAO);
                        break;
                    case 1:
                        pagamento.setTipoImpressao(TipoImpressao.IMPRESSAO_DIRETA_VIA_CLIENTE_VIA_ESTABELECIMENTO);
                        break;
                    case 2:
                        pagamento.setTipoImpressao(TipoImpressao.IMPRESSAO_DIRETA_VIA_CLIENTE);
                        break;
                    case 3:
                        pagamento.setTipoImpressao(TipoImpressao.IMPRESSAO_DIRETA_VIA_ESTABELECIMENTO);
                        break;
                    case 4:
                        pagamento.setTipoImpressao(TipoImpressao.IMPRESSAO_DESABILITADA);
                        break;
                    case 5:
                        pagamento.setTipoImpressao(TipoImpressao.IMPRESSAO_INDEFINIDA);
                        break;
                    default:
                        throw new IllegalStateException("Unexpected value: " + tipoImpressao);
                }

                //TipoImpressao tipoImpressao = pagamento.getTipoImpressao();

                //USADO PARA ENVIAR E PROCESSAR MENSAGENS
                handler = new Handler(Looper.getMainLooper()) {
                    @Override
                    public void handleMessage(@NonNull Message msg) {
                        //super.handleMessage(msg);
                        int msgWhat = msg.what;
                        switch (msgWhat) {
                            case ElginSmartPay.FIM_OPERACAO:
                                String teste1 = "imprimeComprovante";
                                break;
                            case ElginSmartPay.FIM_IMPRESSAO:
                                String teste2 = "finalizaVenda";
                                break;
                            case ElginSmartPay.FIM_CONFIRMACAO:
                                String teste3 = "apresentaMensagemPadrao";
                                break;
                            case ElginSmartPay.ERRO_IMPRESSAO:
                                String teste4 = "ProblemaImpressao";
                                break;
                            case ElginSmartPay.TRANSACAO_PENDENTE:
                                String teste5 = "resolveTransacaoPendente";
                                break;
                            default:
                                throw new IllegalStateException("Unexpected value: " + msgWhat);
                        }
                        String saida = (String) msg.obj;
                        callbackContext.success(saida);
                    }
                };

                switch (tipoTransacao) {
                    case 1:
                        pagamento.iniciaVendaCredito(valor, tipoFinanciamento, numeroParcelas, mActivity, handler);
                        break;
                    case 2:
                        pagamento.iniciaVendaDebito(valor, mActivity, handler);
                        break;
                    default:
                        throw new IllegalStateException("Unexpected value: " + tipoTransacao);
                }
                return true;
            } catch (Exception e) {
                callbackContext.error("IniciarPagamento error: " + e.toString());
            }
            return false;
        } else if (action.equals("IniciarCancelamentoVenda")) {
            try {
                JSONObject params = args.getJSONObject(0);
                String valorTransacao = params.getString("valorTransacao");
                String dataTransacao = params.getString("dataTransacao");
                String nsuTransacao = params.getString("nsuTransacao");

                ElginPay pagamento = new ElginPay();

                int tipoImpressao = params.getInt("tipoImpressao");

                switch (tipoImpressao) {
                    case 0:
                        pagamento.setTipoImpressao(TipoImpressao.IMPRESSAO_PADRAO);
                        break;
                    case 1:
                        pagamento.setTipoImpressao(TipoImpressao.IMPRESSAO_DIRETA_VIA_CLIENTE_VIA_ESTABELECIMENTO);
                        break;
                    case 2:
                        pagamento.setTipoImpressao(TipoImpressao.IMPRESSAO_DIRETA_VIA_CLIENTE);
                        break;
                    case 3:
                        pagamento.setTipoImpressao(TipoImpressao.IMPRESSAO_DIRETA_VIA_ESTABELECIMENTO);
                        break;
                    case 4:
                        pagamento.setTipoImpressao(TipoImpressao.IMPRESSAO_DESABILITADA);
                        break;
                    case 5:
                        pagamento.setTipoImpressao(TipoImpressao.IMPRESSAO_INDEFINIDA);
                        break;
                    default:
                        throw new IllegalStateException("Unexpected value: " + tipoImpressao);
                }


                //USADO PARA ENVIAR E PROCESSAR MENSAGENS
                handler = new Handler(Looper.getMainLooper()) {
                    @Override
                    public void handleMessage(@NonNull Message msg) {
                        //super.handleMessage(msg);
                        String saida = (String) msg.obj;
                        callbackContext.success(saida);
                    }
                };
                pagamento.iniciaCancelamentoVenda(valorTransacao,nsuTransacao, dataTransacao, mActivity, handler);
                //callbackContext.success("IniciarCancelamentoVenda");
            } catch (Exception e) {
                callbackContext.error("IniciarCancelamentoVenda error: " + e.toString());
            }
            return true;
        } 


        return false;
    }

    // public void printerStop() {
    //     Termica.FechaConexaoImpressora();
    // }
}
