package com.gingersoft.supply_chain.mvp.ui.widget;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView;

import com.billy.cc.core.component.CC;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.viewholder.BaseViewHolder;
import com.gingersoft.gsa.cloud.common.utils.XPermissionUtils;
import com.gingersoft.gsa.cloud.common.utils.other.TextUtil;
import com.gingersoft.gsa.cloud.common.utils.toast.ToastUtils;
import com.gingersoft.gsa.cloud.component.ComponentName;
import com.gingersoft.gsa.cloud.ui.utils.AppDialog;
import com.gingersoft.supply_chain.R;
import com.gingersoft.supply_chain.R2;
import com.gingersoft.supply_chain.mvp.bean.PurchaseFoodEncodeSn;
import com.qmuiteam.qmui.alpha.QMUIAlphaButton;
import com.qmuiteam.qmui.alpha.QMUIAlphaImageButton;
import com.qmuiteam.qmui.alpha.QMUIAlphaTextView;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import cn.bingoogolapple.qrcode.core.BarcodeType;
import me.yokeyword.fragmentation.SupportHelper;

/**
 * @author 宇航.
 * User: admin
 * Date: 2021/3/18
 * Time: 17:23
 * Use: 掃描sn碼
 */
public class ScanSnView extends FrameLayout {

    private List<PurchaseFoodEncodeSn> purchaseFoodEncodeSns;

    @BindView(R2.id.rv_sn_code)
    RecyclerView rvSnCode;
    int recyclerHeight = 0;
    private SnCodeAdapter adapter;
    @BindView(R2.id.btn_confirm_sn)
    QMUIAlphaButton btnFoodIngredientsConfirm;
    @BindView(R2.id.btn_cancel_sn)
    QMUIAlphaButton btnFoodIngredientsCancel;
    @BindView(R2.id.ed_input_sn)
    EditText edInputSn;
    @BindView(R2.id.iv_scan_sn)
    QMUIAlphaImageButton btnScanSn;
    @BindView(R2.id.tv_submit_sn)
    QMUIAlphaTextView tvSubmitSn;
    @BindView(R2.id.tv_hint_scan_sn)
    TextView tvScanSn;
    private Fragment fragment;
    /**
     * 取消
     */
    private OnCancelListener onCancelListener;
    /**
     * 單個掃碼或輸入回調
     */
    private OnSingerResultListener onSingerResultListener;
    /**
     * sn碼刪除回調
     */
    private OnDeleteSnCodeListener onDeleteSnCodeListener;
    /**
     * 確認回調
     */
    private ScanSnPopup.OnScanResultListener onScanResultListener;

    /**
     * 初始時snCode的數量，點擊取消時，如果現有的sn數量和剛開始的一樣多，就不提示
     */
    private int initCodeSize = 0;
    /**
     * 新增的sn码数量
     */
    private int newCodeSize = 0;
    /**
     * 最大掃碼數量
     */
    public int maxCodeSize = -1;
    /**
     * 最少掃碼數量
     */
    public int minCodeSize = -1;

    /**
     * 是否顯示掃碼按鈕
     */
    public boolean showScan = true;

    private ScanSnView(Context context) {
        this(context, null);
    }

    private ScanSnView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    private ScanSnView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public ScanSnView(Fragment fragment) {
        this(fragment, null);
    }

    public ScanSnView(Fragment fragment, List<PurchaseFoodEncodeSn> purchaseFoodEncodeSns) {
        super(fragment.requireContext());
        if (purchaseFoodEncodeSns == null) {
            this.purchaseFoodEncodeSns = new ArrayList<>();
        } else {
            this.purchaseFoodEncodeSns = purchaseFoodEncodeSns;
        }
        initCodeSize = this.purchaseFoodEncodeSns.size();
        for (PurchaseFoodEncodeSn purchaseFoodEncodeSn : this.purchaseFoodEncodeSns) {
            if (purchaseFoodEncodeSn.newAdd) {
                newCodeSize++;
            }
        }
        this.fragment = fragment;
    }

    public ScanSnView init() {
        View rootView = LayoutInflater.from(getContext()).inflate(R.layout.layout_scan_sn, this, false);
        ButterKnife.bind(this, rootView);
        //初始化adapter
        adapter = new SnCodeAdapter(R.layout.item_sn_code, purchaseFoodEncodeSns);
        setConfirmBtnState();
        rvSnCode.setAdapter(adapter);
        if (showScan) {
            btnScanSn.setVisibility(VISIBLE);
            //掃描sn媽
            btnScanSn.setOnClickListener(v -> scanSn());
        } else {
            btnScanSn.setVisibility(GONE);
            tvScanSn.setText(R.string.str_enter_sn);
        }
        rvSnCode.post(() -> {
            if (recyclerHeight == 0) {
                recyclerHeight = rvSnCode.getMeasuredHeight();
            }
            LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) rvSnCode.getLayoutParams();
            layoutParams.height = recyclerHeight;
            rvSnCode.setLayoutParams(layoutParams);
        });
        edInputSn.setOnEditorActionListener((v, actionId, event) -> {
            if (actionId == EditorInfo.IME_ACTION_UNSPECIFIED) {
                //響應回車按鈕
                //隐藏软键盘
                SupportHelper.hideSoftInput(v);
                commitSnCode();
                setConfirmBtnState();
            }
            return false;
        });
        //提交按鈕
        tvSubmitSn.setOnClickListener(v -> {
            //提交輸入框中的sn碼
            commitSnCode();
        });

        btnFoodIngredientsConfirm.setOnClickListener(v -> {
            //保存本次掃描的所有sn碼
            //校驗掃描數量和規定的數量是不是一致的，
            onScanResultListener.onScanResult(null, adapter.getData());
        });

        btnFoodIngredientsCancel.setOnClickListener(v -> {
            if (adapter.getData().size() != initCodeSize) {
                AppDialog.getInstance().showTipDialog(getContext(), "關閉後不會保存SN碼記錄", () -> {
                    if (onCancelListener != null) {
                        onCancelListener.onCancel();
                    }
                });
            } else if (onCancelListener != null) {
                onCancelListener.onCancel();
            }
        });
        adapter.setOnItemChildClickListener((adapter1, view, position) -> {
            if (view.getId() == R.id.iv_sn_code_delete) {
                if (adapter.getItem(position).newAdd) {
                    onSingerResultListener.onScanValue(false, adapter.getItem(position), adapter.getItemCount());
                    if (onDeleteSnCodeListener != null) {
                        onDeleteSnCodeListener.onDelete(adapter.getItem(position), position);
                    }
                    if (adapter.getItem(position).newAdd) {
                        newCodeSize--;
                    }
                    adapter1.removeAt(position);
                    setConfirmBtnState();
                } else {
                    ToastUtils.show(getContext(), "已入庫的SN碼不可刪除");
                }
            }
        });
        addView(rootView);
        return this;
    }

    private void scanSn() {
        if (fragment == null) {
            ToastUtils.show(getContext(), "掃碼功能無法啟用，請聯繫開發人員");
            return;
        }
        XPermissionUtils.launchCamera(fragment, (allGranted, grantedList, deniedList) -> {
            if (allGranted) {
                //去掃碼頁面
                CC.obtainBuilder(ComponentName.COMPONENT_SCAN)
                        .setActionName("openScanActivity")
                        .addParam("scanMode", BarcodeType.ONE_DIMENSION)
                        .build()
                        .callAsyncCallbackOnMainThread((cc, result) -> {
                            Object qrCodeResult = result.getDataItem("qrCodeResult");
                            if (qrCodeResult != null) {
                                String snCode = String.valueOf(qrCodeResult);
                                for (PurchaseFoodEncodeSn purchaseFoodEncodeSn : adapter.getData()) {
                                    if (purchaseFoodEncodeSn.getEncodeSnNo().equals(snCode)) {
                                        ToastUtils.show(getContext(), "商品已存在，不能重複添加");
                                        return;
                                    }
                                }
                                addSnCode(adapter, snCode);
                            }
                        });
            }
        });
    }

    public void setConfirmBtnState() {
        if (minCodeSize == -1 || newCodeSize == minCodeSize) {
            btnFoodIngredientsConfirm.setBackground(ContextCompat.getDrawable(getContext(), R.drawable.shape_app_btn));
        } else {
            btnFoodIngredientsConfirm.setBackground(ContextCompat.getDrawable(getContext(), R.drawable.shape_btn_unclick));
        }
    }

    private void commitSnCode() {
        if (TextUtil.isNotEmptyOrNullOrUndefined(edInputSn)) {
            String snCode = edInputSn.getText().toString();
            for (PurchaseFoodEncodeSn datum : adapter.getData()) {
                if (datum.getEncodeSnNo().equals(snCode)) {
                    ToastUtils.show(getContext(), "商品已存在，不能重複添加");
                    return;
                }
            }
            addSnCode(adapter, snCode);
        } else {
            ToastUtils.show(getContext(), "請輸入SN碼");
        }
    }

    /**
     * 添加sn码，內部新增sn統一使用
     */
    private void addSnCode(SnCodeAdapter adapter, String snCode) {
        PurchaseFoodEncodeSn purchaseFoodEncodeSn = new PurchaseFoodEncodeSn(snCode);
        purchaseFoodEncodeSn.newAdd = true;
        adapter.addData(0, purchaseFoodEncodeSn);
        adapter.notifyDataSetChanged();
        newCodeSize++;
        edInputSn.setText("");
        setConfirmBtnState();
        onSingerResultListener.onScanValue(true, purchaseFoodEncodeSn, adapter.getItemCount());
    }

    /**
     * 外部向內部新增sn碼
     */
    public ScanSnView addCode(String snCode) {
        PurchaseFoodEncodeSn purchaseFoodEncodeSn = new PurchaseFoodEncodeSn(snCode);
        purchaseFoodEncodeSn.newAdd = true;
        adapter.addData(purchaseFoodEncodeSn);
        onSingerResultListener.onScanValue(true, purchaseFoodEncodeSn, adapter.getItemCount());
        return this;
    }

    public ScanSnView removeCode(List<String> sns) {
        for (String sn : sns) {
            for (PurchaseFoodEncodeSn datum : adapter.getData()) {
                if (datum.getEncodeSnNo().equals(sn)) {
                    if (datum.newAdd) {
                        newCodeSize--;
                    }
                    adapter.remove(datum);
                    break;
                }
            }
        }
        setConfirmBtnState();
        return this;
    }

    public ScanSnView setMaxCodeSize(int maxCodeSize) {
        this.maxCodeSize = maxCodeSize;
        return this;
    }

    public ScanSnView setMinCodeSize(int minCodeSize) {
        this.minCodeSize = minCodeSize;
        return this;
    }

    public ScanSnView setShowScan(boolean showScan) {
        this.showScan = showScan;
        return this;
    }

    public ScanSnView setOnScanResultListener(ScanSnPopup.OnScanResultListener onScanResultListener) {
        this.onScanResultListener = onScanResultListener;
        return this;
    }

    public ScanSnView setOnCancelListener(OnCancelListener onCancelListener) {
        this.onCancelListener = onCancelListener;
        return this;
    }

    public ScanSnView setOnDeleteSnCodeListener(OnDeleteSnCodeListener onDeleteSnCodeListener) {
        this.onDeleteSnCodeListener = onDeleteSnCodeListener;
        return this;
    }

    public ScanSnView setOnSingerResultListener(OnSingerResultListener onSingerResultListener) {
        this.onSingerResultListener = onSingerResultListener;
        return this;
    }

    public interface OnSingerResultListener {
        /**
         * @param isAdd               true為新增，false為刪除
         * @param snCode              sn碼
         * @param currentSnCodeNumber 當前有多少個sn碼
         */
        void onScanValue(boolean isAdd, PurchaseFoodEncodeSn snCode, int currentSnCodeNumber);
    }

    public interface OnDeleteSnCodeListener {
        void onDelete(PurchaseFoodEncodeSn snCode, int position);
    }

    public interface OnCancelListener {
        void onCancel();
    }

    public int getSnSize() {
        if (adapter != null) {
            return adapter.getItemCount();
        } else {
            return 0;
        }
    }

    public static class SnCodeAdapter extends BaseQuickAdapter<PurchaseFoodEncodeSn, BaseViewHolder> {

        public SnCodeAdapter(int layoutResId, @org.jetbrains.annotations.Nullable List<PurchaseFoodEncodeSn> data) {
            super(layoutResId, data);
            addChildClickViewIds(R.id.iv_sn_code_delete);
        }

        @Override
        protected void convert(@NotNull BaseViewHolder viewHolder, PurchaseFoodEncodeSn s) {
            viewHolder.setText(R.id.tv_sn_code, String.valueOf(s.getEncodeSnNo()));
            viewHolder.setTextColor(R.id.tv_sn_code, ContextCompat.getColor(getContext(), R.color.color_3c));
            viewHolder.setTextColor(R.id.tv_serial_number, ContextCompat.getColor(getContext(), R.color.color_3c));
            viewHolder.setGone(R.id.iv_sn_code_delete, false);
            ImageView ivDelete = viewHolder.getView(R.id.iv_sn_code_delete);
            if (s.newAdd) {
                ivDelete.clearColorFilter();
            } else {
                ivDelete.setColorFilter(ContextCompat.getColor(getContext(), R.color.color_ccc));
            }
            viewHolder.setGone(R.id.it_sn_code_operating, true);
            viewHolder.setText(R.id.tv_serial_number, String.valueOf(viewHolder.getAdapterPosition() + 1));
            if (viewHolder.getAdapterPosition() % 2 == 0) {
                viewHolder.setBackgroundColor(R.id.layout_sn_code, ContextCompat.getColor(getContext(), R.color.color_f9));
            } else {
                viewHolder.setBackgroundColor(R.id.layout_sn_code, ContextCompat.getColor(getContext(), R.color.white));
            }
        }
    }
}
