package com.joe.print.mvp.ui.activity;

import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.MotionEvent;
import android.view.WindowManager;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.billy.cc.core.component.CC;
import com.billy.cc.core.component.CCResult;
import com.billy.cc.core.component.CCUtil;
import com.gingersoft.gsa.cloud.base.application.GsaCloudApplication;
import com.gingersoft.gsa.cloud.base.common.bean.PrinterManger.PrinterManager;
import com.gingersoft.gsa.cloud.base.utils.AidlUtil;
import com.gingersoft.gsa.cloud.base.utils.constans.Constans;
import com.gingersoft.gsa.cloud.base.utils.other.SPUtils;
import com.gingersoft.gsa.cloud.base.utils.toast.ToastUtils;
import com.gingersoft.gsa.cloud.base.widget.DialogUtils;
import com.gingersoft.gsa.cloud.database.bean.PrinterDeviceBean;
import com.hyweb.n5.lib.constant.PrinterConstant;
import com.hyweb.n5.lib.exception.NoInitPrinterException;
import com.hyweb.n5.lib.util.PrinterUtil;
import com.hyweb.n5.server.aidl.IOnPrintCallback;
import com.jess.arms.base.BaseActivity;
import com.jess.arms.di.component.AppComponent;
import com.jess.arms.utils.ArmsUtils;
import com.joe.print.R;
import com.joe.print.di.component.DaggerPrintComponent;
import com.joe.print.mvp.contract.PrintContract;
import com.joe.print.mvp.presenter.PrintPresenter;
import com.joe.print.mvp.print.PrintConstans;
import com.joe.print.mvp.print.PrintStatus;
import com.joe.print.mvp.print.PrintUtils;
import com.joe.print.mvp.ui.adapter.DialogPrinterListAdapter;
import com.sunmi.peripheral.printer.InnerResultCallbcak;
import com.yanzhenjie.recyclerview.widget.DefaultItemDecoration;

import java.util.List;
import java.util.Objects;

import static com.billy.cc.core.component.CCUtil.EXTRA_KEY_CALL_ID;
import static com.jess.arms.utils.Preconditions.checkNotNull;


/**
 * ================================================
 * Description:
 * <p>
 * Created by MVPArmsTemplate on 01/18/2020 14:57
 * <a href="mailto:jess.yan.effort@gmail.com">Contact me</a>
 * <a href="https://github.com/JessYanCoding">Follow me</a>
 * <a href="https://github.com/JessYanCoding/MVPArms">Star me</a>
 * <a href="https://github.com/JessYanCoding/MVPArms/wiki">See me</a>
 * <a href="https://github.com/JessYanCoding/MVPArmsTemplate">模版请保持更新</a>
 * ================================================
 * 透明activity
 * 打印入口
 * 選擇打印方式
 * ----本機打印
 * ----調用本機打印方法
 * ----網絡打印
 * ----获取網絡打印機列表
 */
public class PrintActivity extends BaseActivity<PrintPresenter> implements PrintContract.View, DialogInterface.OnDismissListener {

    private int dialogCount = 0;
    private DialogUtils selectDialog;
    /**
     * 0：上菜紙
     * 1：印單
     * 2：結賬單
     * 3：廚房單
     * 4：清機報表
     */
    private int type = -1;

    public final static int ADD_PRINT_CODE = 1001;//添加打印機回調
    private String callId;

    @Override
    public void setupActivityComponent(@NonNull AppComponent appComponent) {
        DaggerPrintComponent //如找不到该类,请编译一下项目
                .builder()
                .appComponent(appComponent)
                .view(this)
                .build()
                .inject(this);
    }

    @Override
    public int initView(@Nullable Bundle savedInstanceState) {
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
        return 0; //如果你不需要框架帮你设置 setContentView(id) 需要自行设置,请返回 0
    }

    int paperWidth = 500;

    @Override
    public void initData(@Nullable Bundle savedInstanceState) {
        callId = CCUtil.getNavigateCallId(this);
        initPrint();
        //獲取打印類型，根據打印類型生成對應的bitmap
        type = CCUtil.getNavigateParam(this, "type", 1001);
        //380  540
        List<Bitmap> bitmaps = PrintUtils.getPrintBitmap(mContext, type, paperWidth);
        if (bitmaps.size() <= 0) {
            printFile();
            finish();
            return;
        }
        // 獲得用戶默認的打印方式
        if (Objects.equals(SPUtils.get(mContext, Constans.DEFAULT_PRINT_METHOD, ""), "")) {
            // 如果沒有默認打印位置
            noDefaultPrintMethod(bitmaps);
        } else if (Objects.equals(SPUtils.get(mContext, Constans.DEFAULT_PRINT_METHOD, ""), Constans.LOCAL_PRINT)) {
            // 默認打印方式為本地，進行本地打印
            for (int i = 0; i < bitmaps.size(); i++) {
                locationPrint(bitmaps.get(i));
            }
        } else if (Objects.equals(SPUtils.get(mContext, Constans.DEFAULT_PRINT_METHOD, ""), Constans.IP_PRINT)) {
            // 默認打印方式為ip打印，調用ip打印方法
            ipPrint();
        }
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        //doSomeTing，點擊當前頁面任意地方自動關閉
        finish();
        return true;
    }

    private void initPrint() {
        if (GsaCloudApplication.mV2.contains(Build.MODEL)) {
            paperWidth = 360;
        } else if (GsaCloudApplication.mN5.contains(Build.MODEL)) {
            paperWidth = 500;
            try {
                //初始化N5打印
//                int state = PrinterUtil.getStatus();
                boolean state = PrintStatus.initN5PrintStatus(mContext);
                if (!state) {
                    //不能打印
                    printFile();
                }
                Log.e("error", "打印機狀態：" + state);
            } catch (NullPointerException e) {
                e.printStackTrace();
                //如果是空指針，那麼需要初始化
                try {
                    PrinterUtil.initPrinter(this);
                } catch (NoInitPrinterException | RemoteException ex) {
                    ex.printStackTrace();
                    Log.e("error", "打印初始化失敗：" + ex.getMessage());
                }
            }
        }
    }

    private void noDefaultPrintMethod(List<Bitmap> bitmaps) {
        selectDialog = new DialogUtils(mContext, R.layout.print_dialog_select_device) {
            @Override
            public void initLayout(ViewHepler hepler, Dialog dialog) {
                dialogCount++;
                hepler.setViewClick(R.id.local_print, v -> {
                    for (int i = 0; i < bitmaps.size(); i++) {
                        locationPrint(bitmaps.get(i));
                    }
                    //修改默認打印方式為本地
                    SPUtils.put(mContext, Constans.DEFAULT_PRINT_METHOD, Constans.LOCAL_PRINT);
                    dialog.dismiss();
                });
                hepler.setViewClick(R.id.internet_print, v -> {
                    //修改默認打印方式為IP打印
                    SPUtils.put(mContext, Constans.DEFAULT_PRINT_METHOD, Constans.IP_PRINT);
                    ipPrint();
                });
            }
        }.createDialogView().show().setOnDismissListener(this);
    }

    /**
     * IP打印
     */
    private void ipPrint() {
        //獲取默認選中的IP打印機
        if(Objects.equals(SPUtils.get(mContext, PrintConstans.DEFAULT_PRINT_IP, ""), "")){
            //如果沒有獲取到默認打印機IP
            if (PrinterManager.getPrinterManager().getDeviceBeans() != null
                    && PrinterManager.getPrinterManager().getDeviceBeans().size() > 0) {
                //如果本地保存有打印設備
                showPrinterList();
            } else {
                //網絡獲取打印設備
                mPresenter.getPrinterList(GsaCloudApplication.getRestaurantId(mContext));
            }
        } else {
            //如果有默認選中打印機
            PrinterDeviceBean printerDeviceBean = new PrinterDeviceBean();
            printerDeviceBean.setIp((String) SPUtils.get(mContext, PrintConstans.DEFAULT_PRINT_IP, ""));
            printerDeviceBean.setPort((Integer) SPUtils.get(mContext, PrintConstans.DEFAULT_PRINT_PORT, 0));
            printerDeviceBean.setType((Integer) SPUtils.get(mContext, PrintConstans.DEFAULT_PRINT_PAPER, 0));
            startToIpPrint(printerDeviceBean);
        }
    }

    /**
     * 本地打印
     */
    private void locationPrint(Bitmap bitmap) {
        //本機打印
        if (bitmap == null) {
            ToastUtils.show(mContext, "未獲取到打印內容");
            printFile();
            return;
        }
        String model = Build.MODEL;
        if (GsaCloudApplication.mV2.contains(model)) {
            //商米打印
            AidlUtil.getInstance().printBitmap(bitmap, new InnerResultCallbcak() {
                @Override
                public void onRunResult(boolean isSuccess) {
                    //返回接⼝执⾏的情况(并⾮真实打印):成功或失败
                    if (isSuccess) {
                        ToastUtils.show(mContext, "打印成功");
                        printSuccess();
                    } else {
                        ToastUtils.show(mContext, "打印失敗");
                        printFile();
                    }
                }

                @Override
                public void onReturnString(String result) {
                    //部分接⼝会异步返回查询数据
                    ToastUtils.show(mContext, "onReturnString：" + result);
                }

                @Override
                public void onRaiseException(int code, String msg) {
                    //接⼝执⾏失败时，返回的异常状态
                    ToastUtils.show(mContext, "打印異常狀態碼：" + code + "---MSG:" + msg);
                }

                @Override
                public void onPrintResult(int code, String msg) {
                    //事务模式下真实的打印结果返回
                    ToastUtils.show(mContext, "打印結果：" + code + "---MSG:" + msg);
                }
            });
        } else if (GsaCloudApplication.mN5.contains(model)) {
            //N5打印
            try {
                try {
                    PrinterUtil.appendImage(bitmap, PrinterConstant.ALIGN_CENTER);
                    startN5Print();
                } catch (NullPointerException e) {
                    ToastUtils.show(mContext, "打印失敗，請重試");
                    Log.e("error", "打印失敗請重試：" + e.getMessage());
                    finish();
                }
            } catch (RemoteException e) {
                e.printStackTrace();
                Log.e("error", "打印失敗請重試RemoteException：" + e.getMessage());
                printFile();
            }
        } else {
            ToastUtils.show(mContext, "暫不支持本機型打印");
            printFile();
        }
    }


    private void startN5Print() {
        try {
            PrinterUtil.startPrint(true, new IOnPrintCallback.Stub() {
                @Override
                public void onPrintResult(int i) {
                    Log.e("error", "打印回調：" + i);
                    if (i == 0) {
                        //打印成功
                        printSuccess();
                    } else {
                        //打印失敗
                        printFile();
                    }
                }

                @Override
                public IBinder asBinder() {
                    return this;
                }
            });
        } catch (RemoteException e) {
            e.printStackTrace();
            //打印失敗
            Log.e("error", "打印失敗請重試22222222222RemoteException：" + e.getMessage());
            printFile();
        }
    }

    /**
     * 打印失敗
     */
    private void printFile() {
        CC.sendCCResult(callId, CCResult.error("print error"));
        finish();
    }

    /**
     * 打印成功
     */
    private void printSuccess() {
        CC.sendCCResult(callId, CCResult.success());
        finish();
    }

    @Override
    public void initIntent() {

    }

    @Override
    public void initTopBar() {

    }

    @Override
    public void initLanguage() {

    }

    @Override
    public void initLayoutParams() {

    }

    @Override
    public void initLayoutVisible() {

    }

    @Override
    public void showLoading(String message) {

    }

    @Override
    public void hideLoading() {

    }

    @Override
    public void showMessage(@NonNull String message) {
        checkNotNull(message);
        ToastUtils.show(mContext, message);
    }

    @Override
    public void launchActivity(@NonNull Intent intent) {
        checkNotNull(intent);
        ArmsUtils.startActivity(intent);
    }

    @Override
    public void killMyself() {
        finish();
    }

    @Override
    public void showPrinterList() {
        if (selectDialog != null && selectDialog.isShowing()) {
            selectDialog.dismiss();
        }
        List<PrinterDeviceBean> deviceBeans = PrinterManager.getPrinterManager().getDeviceBeans();
        if (deviceBeans != null) {
            if (deviceBeans.size() == 1) {
                //如果只配置了一個打印機，直接使用這個打印機進行打印
                startToIpPrint(deviceBeans.get(0));
            } else {
                //有打印機，彈出彈窗，選擇打印機
                new DialogUtils(mContext, R.layout.print_dialog_internet_list) {
                    @Override
                    public void initLayout(ViewHepler hepler, Dialog dialog) {
                        dialogCount++;
                        RecyclerView mRvPrintList = hepler.getView(R.id.rv_print_list);

                        DialogPrinterListAdapter printListAdapter = new DialogPrinterListAdapter(deviceBeans, mContext);
                        mRvPrintList.setLayoutManager(new LinearLayoutManager(mContext));
                        //分割线
                        mRvPrintList.addItemDecoration(new DefaultItemDecoration(ContextCompat.getColor(mContext, R.color.line_color)));
                        mRvPrintList.setAdapter(printListAdapter);
                        printListAdapter.setOnItemClickListener((adapter, view, position) -> {
                            startToIpPrint(deviceBeans.get(position));
                            dialog.dismiss();
                        });
                        dialog.setOnDismissListener(PrintActivity.this);
                    }
                }
                        .setHeight(ArmsUtils.getScreenHeidth(mContext) / 2)
                        .createDialogView()
                        .show();
            }
        } else {
            //沒有配置打印機
            startActivityForResult(new Intent(mContext, PrinterAddActivity.class), ADD_PRINT_CODE);
        }
    }

    private void startToIpPrint(PrinterDeviceBean deviceBean) {
        dialogCount = 2;//設置為2為了不讓回調打印失敗，因為這裡是跳轉ip打印，會關閉選擇ip的dialog，dialog關閉時會調用onDismiss方法，如果dialogCount小於2就會回調打印失敗
        Intent intent = new Intent(mContext, IpPrintActivity.class);
        intent.putExtra("ip", deviceBean.getIp());
        intent.putExtra("port", deviceBean.getPort());
        intent.putExtra("paperType", deviceBean.getType());
        intent.putExtra("type", type);
        intent.putExtra(EXTRA_KEY_CALL_ID, callId);
        startActivity(intent);
        finish();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == ADD_PRINT_CODE && resultCode == PrintActivity.ADD_PRINT_CODE) {
            //添加打印機成功，
            if (data != null && data.getSerializableExtra("printDevice") != null) {
                startToIpPrint((PrinterDeviceBean) data.getSerializableExtra("printDevice"));
            }
        }
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        dialogCount--;
        if (dialogCount <= 0) {
            printFile();
            finish();
        }
    }

}
