package com.phlx.wool.ui.inventory;

import android.annotation.SuppressLint;
import android.app.Application;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.SparseIntArray;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.databinding.ObservableArrayList;
import androidx.databinding.ObservableField;
import androidx.databinding.ObservableList;

import com.phlx.wool.App;
import com.phlx.wool.BR;
import com.phlx.wool.Configs;
import com.phlx.wool.R;
import com.phlx.wool.data.Repository;
import com.phlx.wool.db.DbUtil;
import com.phlx.wool.entity.Label;
import com.phlx.wool.entity.LabelDao;
import com.phlx.wool.event.EventMsg;
import com.phlx.wool.event.EventTag;
import com.phlx.wool.rfid.ModuleManager;
import com.phlx.wool.ui.base.BackBarVM;
import com.phlx.wool.ui.work.harmless.HarmlessActivity;
import com.phlx.wool.ui.work.mark.MarkingActivity;
import com.phlx.wool.ui.work.quarantine.QuarantineActivity;
import com.phlx.wool.util.TextUtil;
import com.uhf.structures.InventoryData;
import com.uhf.structures.OnInventoryListener;

import org.greenrobot.greendao.query.QueryBuilder;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import me.goldze.mvvmhabit.binding.command.BindingAction;
import me.goldze.mvvmhabit.binding.command.BindingCommand;
import me.goldze.mvvmhabit.bus.RxBus;
import me.goldze.mvvmhabit.bus.RxSubscriptions;
import me.goldze.mvvmhabit.bus.event.SingleLiveEvent;
import me.goldze.mvvmhabit.http.ResponseThrowable;
import me.goldze.mvvmhabit.utils.KLog;
import me.goldze.mvvmhabit.utils.RxUtils;
import me.goldze.mvvmhabit.utils.SPUtils;
import me.goldze.mvvmhabit.utils.StringUtils;
import me.goldze.mvvmhabit.utils.ToastUtils;
import me.tatarka.bindingcollectionadapter2.ItemBinding;

public class InventoryVM extends BackBarVM<Repository> implements OnInventoryListener {

    private SoundPool soundPool;//盘点到标签时的提示音
    private SparseIntArray musicId;
    public ObservableField<String> unitName = new ObservableField<>("");
    public ObservableField<String> labelNum = new ObservableField<>("");
    public ObservableField<String> tipDesc = new ObservableField<>("");
    public ObservableField<Integer> tipDescVis = new ObservableField<>(View.VISIBLE);
    public ObservableField<Integer> invBtnVis = new ObservableField<>(View.GONE);
    public SingleLiveEvent<InventoryItem> deleteItemLiveData = new SingleLiveEvent<>();
    public SingleLiveEvent<Boolean> inventoryBtnEvent = new SingleLiveEvent<>();
    public SingleLiveEvent<String> labelCheckEvent = new SingleLiveEvent<>();
    private Disposable inventoryBus;
    private int labelCount = 0;
    private ArrayList<Label> mList;
    private ArrayList<Label> checkList;
    private int legalCount;
    private static Map<String, Integer> map;//去重
    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 0x333) {
                InventoryData inventoryData = (InventoryData) msg.obj;
                if (inventoryData.dataLength > 0 && inventoryData.epcLength > 0) {
                    String epc = TextUtil.byteToHexString(inventoryData.EPC_Data, 6);
                    String tid = TextUtil.byteToHexString(inventoryData.data, inventoryData.dataLength);
                    String tag = epc + tid;
                    if (!map.containsKey(tag)) {
                        Label label = new Label();
                        label.setEpc(epc);
                        label.setTid(tid);
                        mList.add(label);
                        InventoryItem itemViewModel = new InventoryItem(InventoryVM.this, label);
                        observableList.add(itemViewModel);
                        labelCount++;
                        labelNum.set(String.valueOf(labelCount));
                        soundPool.play(musicId.get(1), 1, 1, 0, 0, 1);
                        map.put(tag, mList.size() - 1);
                    }
                }
            }

        }
    };


    public void setType(String type) {
        this.type = type;
    }

    private String type;

    public InventoryVM(@NonNull Application application, Repository repository) {
        super(application, repository);
        map = new HashMap<>();
        mList = new ArrayList<>();
        unitName.set(SPUtils.getInstance().getString(Configs.SP_UNIT_NAME, ""));
        soundPool = new SoundPool(2, AudioManager.STREAM_MUSIC, 5);
        musicId = new SparseIntArray();
        musicId.put(1, soundPool.load(getApplication(), R.raw.readcard, 1));
        musicId.put(2, soundPool.load(getApplication(), R.raw.failure, 1));

        tipDescVis.set(Configs.FREQUENCY_CONFIG.equals("0") ? View.GONE : View.VISIBLE);
        invBtnVis.set(Configs.FREQUENCY_CONFIG.equals("0") ? View.VISIBLE : View.GONE);
        App.getInstance().getLinkage().setOnInventoryListener(this);
    }

    //初始化ToolBar
    public void initToolbar(String type) {
        this.type = type;
        if (type.equals(Configs.WORK_TYPE_M)) {
            setBackTitleText("打标记录");
        } else if (type.equals(Configs.WORK_TYPE_Q)) {
            setBackTitleText("检疫记录");
        } else if (type.equals(Configs.WORK_TYPE_H)) {
            setBackTitleText("无害化处理");
        }

    }


    @Override
    public void registerRxBus() {
        super.registerRxBus();
        inventoryBus =
                RxBus.getDefault().toObservable(EventMsg.class).subscribe(eventType -> {
                    if (eventType.getAction().equals(EventTag.EVENT_INVENTORY_DATA)) {


                    }
                });
        RxSubscriptions.add(inventoryBus);
    }

    @Override
    public void removeRxBus() {
        super.removeRxBus();
        RxSubscriptions.remove(inventoryBus);
    }

    //给RecyclerView添加ObservableList
    public ObservableList<InventoryItem> observableList = new ObservableArrayList<>();
    //给RecyclerView添加ItemBinding
    public ItemBinding<InventoryItem> itemBinding = ItemBinding.of(BR.viewModel,
            R.layout.item_inventory_rv);

    /**
     * 删除条目
     */
    public void deleteItem(InventoryItem inventoryItem) {
        //点击确定，在 observableList 绑定中删除，界面立即刷新
        observableList.remove(inventoryItem);
    }

    /**
     * 获取条目下标
     */
    public int getItemPosition(InventoryItem inventoryItem) {
        return observableList.indexOf(inventoryItem);
    }

    /**
     * 删除换行
     */
    public void trim() {
        tipDesc.set(tipDesc.get().trim());
    }

    /**
     * 添加按钮
     */
    public BindingCommand onAddClickCommand = new BindingCommand(new BindingAction() {
        @Override
        public void call() {

            if("".equals(tipDesc.get().trim())){
                ToastUtils.showShort("请扫描标签");
                return;
            }

            if (mList.size() >= 20) {
                ToastUtils.showShort("单次标签扫描已达20上限");
                return;
            }

            String epc = tipDesc.get();
            String tid = tipDesc.get();
            String tag = epc + tid;
            if (!map.containsKey(tag)) {
                Label label = new Label();
                label.setEpc(epc);
                label.setTid(tid);
                mList.add(label);
                InventoryItem itemViewModel = new InventoryItem(InventoryVM.this, label);
                observableList.add(itemViewModel);
                labelCount++;
                labelNum.set(String.valueOf(labelCount));
                soundPool.play(musicId.get(1), 1, 1, 0, 0, 1);
                map.put(tag, mList.size() - 1);
            } else {
                ToastUtils.showShort("重复标签");
            }
            tipDesc.set("");
        }
    });

    /**
     * 确定
     */
    public BindingCommand onFixedClickCommand = new BindingCommand(new BindingAction() {
        @Override
        public void call() {
            //如果是低频
//            if ("1".equals(Configs.FREQUENCY_CONFIG)) {
//                mList.clear();
//                String epcStr = tipDesc.get();
//                if (!StringUtils.isEmpty(epcStr)) {
//                    Label label = new Label();
//                    label.setEpc(epcStr);
//                    label.setTid(epcStr);
//                    mList.add(label);
//                }
//            }

            if (mList != null && mList.size() > 0) {

                showDialog("正在验证标签...");
                addSubscribe(Observable.create((ObservableOnSubscribe<List<Label>>) emitter -> {
                    try {

                        checkList = new ArrayList<>();
                        legalCount = 0;
                        KLog.e(mList.toString());
                        for (int i = 0; i < mList.size(); i++) {
                            QueryBuilder<Label> builder =
                                    DbUtil.getInstance().getQueryBuilder(Label.class)
                                            .where(LabelDao.Properties.Epc.eq(mList.get(i).getEpc()));
                            List<Label> labels = DbUtil.getInstance().queryAll(Label.class, builder);
                            //合法状态 0 非法 1 合法
                            if (labels.size() == 0) {
                                mList.get(i).setIsLegalStatus("0");
                                legalCount++;
                            } else {
                                mList.get(i).setIsLegalStatus("1");
                            }
                            checkList.add(mList.get(i));
                        }
                        emitter.onNext(checkList);
                    } catch (Exception e) {
                        emitter.onError(e);
                    }

                }).compose(RxUtils.bindToLifecycle(getLifecycleProvider()))
                        .compose(RxUtils.schedulersTransformer()).compose(RxUtils.exceptionTransformer())
                        .doOnSubscribe(disposable -> {
                        })
                        .subscribe((Consumer<List<Label>>) response -> {
                            dismissDialog();
                            if (legalCount > 0) {
                                labelCheckEvent.setValue("" + legalCount);
                            } else {
                                jumpToActivity();
                            }
                        }, (Consumer<ResponseThrowable>) throwable -> {
                            dismissDialog();
                            ToastUtils.showShort(throwable.message);
                        }));
            } else {
                ToastUtils.showShort("请扫描耳标");
            }
        }
    });

    public void jumpToActivity() {
        if (checkList != null && checkList.size() > 0) {
            Bundle mBundle = new Bundle();
            mBundle.putParcelableArrayList("list", checkList);
            if (type.equals(Configs.WORK_TYPE_M)) {
                startActivity(MarkingActivity.class, mBundle);
            } else if (type.equals(Configs.WORK_TYPE_Q)) {
                startActivity(QuarantineActivity.class, mBundle);
            } else if (type.equals(Configs.WORK_TYPE_H)) {
                startActivity(HarmlessActivity.class, mBundle);
            }
            finish();
        } else {
            ToastUtils.showShort("请扫描耳标");
        }


    }

    /**
     * 清空
     */
    public BindingCommand onClearClickCommand = new BindingCommand(new BindingAction() {
        @Override
        public void call() {
            observableList.clear();
            labelCount = 0;
            mList.clear();
            labelNum.set("");
            map.clear();
            tipDesc.set("");
        }
    });

    /**
     * 盘点
     */
    public BindingCommand onInventoryClickCommand = new BindingCommand(new BindingAction() {
        @Override
        public void call() {
            inventoryBtnEvent.call();
        }
    });

    @Override
    public void onDestroy() {
        super.onDestroy();
        ModuleManager.powerOff();
    }

    @Override
    public void getInventoryData(InventoryData inventoryData) {
        if (inventoryData != null) {

            Message messenger = handler.obtainMessage();
            messenger.what = 0x333;
            messenger.obj = inventoryData;
            handler.sendMessage(messenger);
        }
    }
}
