package com.baoshi.swms.activity;

import android.content.Context;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.text.Html;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

import com.baoshi.swms.R;
import com.baoshi.swms.adapter.CheckInventoryItem;
import com.baoshi.swms.bean.StocktakingItem;
import com.baoshi.swms.bean.User;
import com.baoshi.swms.bean.dto.StockingData;
import com.baoshi.swms.bean.dto.StocktakingData;
import com.baoshi.swms.net.callback.WasHandlerCallback;
import com.baoshi.swms.net.subscribe.WasSubscribe;
import com.baoshi.swms.util.DateUtil;
import com.kongzue.dialogx.DialogX;
import com.kongzue.dialogx.datepicker.DatePickerDialog;
import com.kongzue.dialogx.datepicker.interfaces.OnDateSelected;
import com.kongzue.dialogx.dialogs.InputDialog;
import com.kongzue.dialogx.dialogs.MessageDialog;
import com.kongzue.dialogx.dialogs.TipDialog;
import com.kongzue.dialogx.dialogs.WaitDialog;
import com.kongzue.dialogx.interfaces.DialogLifecycleCallback;
import com.kongzue.dialogx.interfaces.OnDialogButtonClickListener;
import com.kongzue.dialogx.interfaces.OnInputDialogButtonClickListener;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

public class CheckInventoryActivity extends AppCompatActivity implements View.OnClickListener, View.OnFocusChangeListener, View.OnKeyListener {
    private final String prefix = "stocktaking";
    private final String DATE_DEFAULT = "点此选择日期";
    private StocktakingData stocktakingData;
    private StocktakingItem stocktakingItem;
    private BaseAdapter adapter;
    private String oldLoc;
    private String oldBarcode;

    private TextView userName;
    private TextView taskCount;
    private TextView offStockCount;
    private TextView taskId;
    private TextView startDate;
    private EditText currentLoc;
    private EditText barcode;
    private EditText number;
    private TextView quality;
    private TextView prodDate;
    private TextView attrWarehouse;
    private TextView expiryDate;
    private EditText lot;
    private ListView list;
    private TextView stockRatio;
    private Button btn;
    private TextView type;
    private MediaPlayer mediaPlayer;
    private MediaPlayer mediaPlayerErr;
    private Vibrator vibrator;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_check_inventory);

        registerLocalVar();

        DialogX.init(this);
        inquiryBill();
        registerEvent();
    }

    private void registerEvent() {
        prodDate.setOnClickListener(this);
        findViewById(R.id.back).setOnClickListener(this);
        expiryDate.setOnClickListener(this);
        currentLoc.setOnFocusChangeListener(this);
        barcode.setOnFocusChangeListener(this);
        btn.setOnClickListener(this);
        btn.setOnKeyListener(this);
        currentLoc.setOnKeyListener(this);
        barcode.setOnKeyListener(this);
        number.setOnKeyListener(this);
    }

    /**
     * 问询单据
     * */
    private void inquiryBill() {
        new InputDialog("盘点单据号",null,"开始盘点","返回")
                .setAutoShowInputKeyboard(true)
                .setCancelButton(new OnInputDialogButtonClickListener<InputDialog>() {
                    @Override
                    public boolean onClick(InputDialog baseDialog, View v, String inputStr) {
                        finish();
                        return false;
                    }
                })
                .setCancelable(false).setOkButton(new OnInputDialogButtonClickListener<InputDialog>() {
            @Override
            public boolean onClick(InputDialog baseDialog, View v, String inputStr) {
                if(inputStr.isEmpty()){
                    TipDialog.show("请输入单据号!",WaitDialog.TYPE.WARNING);
                    return true;
                }
                loadingBillInfo(inputStr);
                return false;
            }
        }).setMaskColor(getResources().getColor(R.color.dark_gray,null)).show();
    }
    /**
     * 加载单据信息
     * */
    private void loadingBillInfo(String stocktakingId){
        WaitDialog.show("获取单据中~");
        WasSubscribe.getStocktaking(stocktakingId, new WasHandlerCallback<StocktakingData>() {
            @Override
            public void onSuccess(StocktakingData result) {
                stocktakingData = result;
                initData();
                super.onSuccess(result);
            }
            @Override
            public void onFault(int code, String errorMsg) {
                super.onFault(code, errorMsg);
                inquiryBill();
            }
            @Override
            public void onError(Throwable e) {
                super.onError(e);
                inquiryBill();
            }
            @Override
            public void onFinally() {
                WaitDialog.dismiss();
            }
        });
    }

    private void registerLocalVar() {
        userName = findViewById(R.id.user_name);
        taskCount = findViewById(R.id.task_count);
        offStockCount = findViewById(R.id.off_stock_count);
        taskId = findViewById(R.id.task_id);
        startDate = findViewById(R.id.start_date);
        currentLoc = findViewById(R.id.current_loc);
        stockRatio = findViewById(R.id.stock_ratio);
        barcode = findViewById(R.id.barcode);
        number = findViewById(R.id.number);
        quality = findViewById(R.id.quality);
        prodDate = findViewById(R.id.prod_date);
        attrWarehouse = findViewById(R.id.attr_warehouse);
        expiryDate = findViewById(R.id.expiry_date);
        lot = findViewById(R.id.lot);
        list = findViewById(R.id.list);
        btn = findViewById(R.id.check_btn);
        type = findViewById(R.id.task_type);

        InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(currentLoc.getWindowToken(),0);
        imm.hideSoftInputFromWindow(barcode.getWindowToken(),0);
        imm.hideSoftInputFromWindow(number.getWindowToken(),0);

        prodDate.setText(DATE_DEFAULT);
        expiryDate.setText(DATE_DEFAULT);

        if (mediaPlayer==null){
            mediaPlayer = MediaPlayer.create(this,R.raw.tip);
        }
        if (mediaPlayerErr==null){
            mediaPlayerErr = MediaPlayer.create(this,R.raw.error);
        }
        if (vibrator==null){
            vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
        }
    }
    private void setVibrator(){
        mediaPlayerErr.start();
        vibrator.vibrate(VibrationEffect.createOneShot(1000, -1));
    }

    private void initData() {
        //设置一些label的颜色标签
        String[] labels = new String[]{
                "current_loc","barcode","number","quality","prod_date",
                "attr_warehouse","expiry_date","lot"
        };
        //通过反射设置label资源,默认规则：资源加stocking前缀  id加label后缀
        for (String val: labels) {
            ((TextView) findViewById(getResources().getIdentifier(val+"_label","id",this.getPackageName()))).setText(
                    Html.fromHtml(getString(getResources().getIdentifier(prefix+"_"+val,"string",this.getPackageName())),Html.FROM_HTML_MODE_COMPACT)
            );
        }
        //一些需要组合赋值的显示数据
        userName.setText(
                Html.fromHtml(
                        getString(R.string.stocktaking_user_name, User.getLocalUser().getName()),
                        Html.FROM_HTML_MODE_COMPACT)
        );
        startDate.setText(
                Html.fromHtml(
                        getString(R.string.stocktaking_start_date, DateUtil.getCurrentFormat(DateUtil.DATE_DATE_TIME_CN)),
                        Html.FROM_HTML_MODE_COMPACT)
        );

        taskCount.setText(
                Html.fromHtml(
                        getString(R.string.stocktaking_task_count,stocktakingData.getStocktaking().getTotal()-stocktakingData.getStocktaking().getProcessed()),
                        Html.FROM_HTML_MODE_COMPACT)
        );
        offStockCount.setText(
                Html.fromHtml(
                        getString(R.string.stocktaking_off_stock_count,stocktakingData.getTodayWorkNumber()),
                        Html.FROM_HTML_MODE_COMPACT)
        );
        taskId.setText(
                Html.fromHtml(
                        getString(R.string.stocktaking_task_id,"PD"+stocktakingData.getStocktaking().getId()),
                        Html.FROM_HTML_MODE_COMPACT)
        );
        type.setText(stocktakingData.getStocktaking().getType());
        adapter = new CheckInventoryItem(stocktakingData.getNotStocktakingList(),CheckInventoryActivity.this);
        list.setAdapter(adapter);
        currentLoc.requestFocus();
    }

    @Override
    public void onClick(View v) {
        if (v.getId()==R.id.prod_date || v.getId()==R.id.expiry_date){
            datePicker(v.getId());
        }
        if (v.getId()==R.id.check_btn){
            stocktaking();
        }
        if (v.getId()==R.id.back){
            finish();
        }
    }

    private void stocktaking() {
        if (stocktakingItem==null || stocktakingItem.getId()==null || number.getText().toString().isEmpty()){
            TipDialog.show("单据获取失败或数量未填写!",WaitDialog.TYPE.WARNING);
            return;
        }
        WaitDialog.show("提交盘点信息中...");
        WasSubscribe.stocktaking(stocktakingParamFormat(), new WasHandlerCallback<StockingData>() {
            @Override
            public void onSuccess(StockingData data) {
                super.onSuccess(data);
                if (data.isDiff()){
                    AtomicBoolean cancelSign = new AtomicBoolean(false);
                    MessageDialog.show("盘点信息", "存在差异,是否重盘？", "重盘","取消")
                            .setOkButtonClickListener(new OnDialogButtonClickListener<MessageDialog>() {
                                @Override
                                public boolean onClick(MessageDialog baseDialog, View v) {
                                    cancelSign.set(true);
                                    return false;
                                }
                            });
                    if (cancelSign.get()){
                        number.setText("");
                        number.requestFocus();
                        return;
                    }
                }
                ArrayList<HashMap<String, String>> result = data.getList();
                mediaPlayer.start();
                //没有待盘项结束该盘单
                if (result.size()==0){
                    TipDialog.show("盘点完毕!",WaitDialog.TYPE.SUCCESS).setDialogLifecycleCallback(new DialogLifecycleCallback<WaitDialog>() {
                        @Override
                        public void onDismiss(WaitDialog dialog) {
                            clearInfo();
                            currentLoc.setText("");
                            stockRatio.setText("已/总");
                            inquiryBill();//唤起询单
                        }
                    });
                    return;
                }
                //还有待盘 重设待盘列表
                stocktakingData.getNotStocktakingList().clear();
                stocktakingData.getNotStocktakingList().addAll(result);
                adapter.notifyDataSetChanged();

                //当前库位未盘完
                AtomicBoolean breakSign = new AtomicBoolean(false);
                AtomicInteger count = new AtomicInteger(0);
                result.forEach(item->{
                    if (item.get("location").equals(currentLoc.getText().toString())){
                        breakSign.set(true);
                        String[] all=stockRatio.getText().toString().split("/");
                        String ratio = String.valueOf(((int)Integer.parseInt(all[1]))-((int)Integer.parseInt(item.get("count"))))+"/"+all[1];
                        stockRatio.setText(ratio);
                    }
                    count.set(count.get()+Integer.parseInt(item.get("count")));
                });
                //重置未盘数
                taskCount.setText(
                        Html.fromHtml(
                                getString(R.string.stocktaking_task_count,count.get()),
                                Html.FROM_HTML_MODE_COMPACT));
                clearInfo();
                //改变已盘数
                stocktakingData.setTodayWorkNumber(stocktakingData.getTodayWorkNumber()+1);
                offStockCount.setText(
                        Html.fromHtml(
                                getString(R.string.stocktaking_off_stock_count,stocktakingData.getTodayWorkNumber()),
                                Html.FROM_HTML_MODE_COMPACT));
                if(breakSign.get()){
                    barcode.requestFocus();
                    return;
                }
                //当前库位已盘完
                currentLoc.setText("");
                stockRatio.setText("已/总");
            }
            @Override
            public void onFinally() {
                WaitDialog.dismiss();
            }
        });
    }

    private void clearInfo(){
        number.setText("");
        barcode.setText("");
        quality.setText("");
        attrWarehouse.setText("");
        prodDate.setText(DATE_DEFAULT);
        expiryDate.setText(DATE_DEFAULT);
        lot.setText("");
    }
    private HashMap<String,Object> stocktakingParamFormat(){
        return new HashMap<String,Object>(){{
            put("task_item_id",stocktakingItem.getId());
            put("verified_amount",number.getText().toString());
            if (!(stocktakingItem.getProdAt()==null && prodDate.getText().toString().isEmpty()) &&
                    !prodDate.getText().toString().equals(DATE_DEFAULT) &&
                    !DateUtil.getTime(stocktakingItem.getProdAt()).contentEquals(prodDate.getText())){
                put("produced_at",prodDate.getText().toString());
            }
            if (!(stocktakingItem.getExpiryDate()==null && expiryDate.getText().toString().isEmpty()) &&
                    !expiryDate.getText().toString().equals(DATE_DEFAULT) &&
                    !DateUtil.getTime(stocktakingItem.getExpiryDate()).contentEquals(expiryDate.getText())){
                put("valid_at",expiryDate.getText().toString());
            }
            if (!(stocktakingItem.getLotNum()==null && lot.getText().toString().isEmpty()) &&
                    !stocktakingItem.getLotNum().equals(lot.getText().toString())){
                put("batch_number",lot.getText().toString());
            }
        }};
    }
    private void datePicker(int id){
        Calendar cal = Calendar.getInstance();
        int day = cal.get(Calendar.DATE);
        int month = cal.get(Calendar.MONTH) + 1;
        int year = cal.get(Calendar.YEAR);
        DatePickerDialog picker = DatePickerDialog.build().setDefaultSelect(year,month,day);
        if (id==R.id.expiry_date){
            picker.setTitle("失效日期").setMinTime(year,month,day);
        }else{
            picker.setTitle("生产日期").setMaxTime(year,month,day);
        }
        picker.show(new OnDateSelected() {
                    @Override
                    public void onSelect(String text, int year, int month, int day) {
                        if(id==R.id.expiry_date){
                            expiryDate.setText(text);
                        }else{
                            prodDate.setText(text);
                        }
                    }
                });
    }

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (v.getId()==R.id.current_loc){
            getLocRatio();
        }
        if (v.getId()==R.id.barcode){
            getLocGoodsInfo();
        }
    }

    private void getLocGoodsInfo() {
        String locStr = currentLoc.getText().toString();
        String barcodeStr = barcode.getText().toString();
        if (locStr.isEmpty() || barcodeStr.isEmpty()){
            return;
        }
        if (oldLoc!=null && oldBarcode!=null && oldLoc.equals(locStr) && oldBarcode.equals(barcodeStr)){
            return;
        }
        oldLoc = locStr;
        oldBarcode = barcodeStr;
        WasSubscribe.getLocGoodsInfo(stocktakingData.getStocktaking().getId(), locStr, barcodeStr, new WasHandlerCallback<StocktakingItem>() {
            @Override
            public void onSuccess(StocktakingItem result) {
                stocktakingItem = result;
                if (result.getVerifiedAmount()!=null){
                    number.setText(String.valueOf(result.getVerifiedAmount()));
                }
                if (result.getQuality()!=null){
                    quality.setText(result.getQuality());
                }
                if (result.getProdAt()!=null){
                    prodDate.setText(DateUtil.getTime(result.getProdAt()));
                }
                if (result.getExpiryDate()!=null){
                    expiryDate.setText(DateUtil.getTime(result.getExpiryDate()));
                }
                lot.setText(result.getLotNum());
                attrWarehouse.setText(result.getAttrWarehouse());
                number.requestFocus();
            }

            @Override
            public void onFault(int code, String errorMsg) {
                super.onFault(code, errorMsg);
                barcode.requestFocus();
                mediaPlayerErr.start();
                setVibrator();
            }

            @Override
            public void onError(Throwable e) {
                super.onError(e);
                barcode.requestFocus();
                mediaPlayerErr.start();
                setVibrator();
            }

            @Override
            public void onFinally() {
                oldLoc = null;
                oldBarcode = null;
                barcode.setText("");
            }
        });
    }

    private void getLocRatio() {
        String loc = currentLoc.getText().toString();
        if (loc.isEmpty()){
            return;
        }
        if (oldLoc!=null && oldLoc.equals(loc)){
            return;
        }
        oldLoc = loc;
        WasSubscribe.getLocStocktakingRatio(stocktakingData.getStocktaking().getId(), loc, new WasHandlerCallback<HashMap<String,String>>(){
            @Override
            public void onSuccess(HashMap<String, String> result) {
                stockRatio.setText(result.get("invCount")+"/"+result.get("total"));
                barcode.requestFocus();
            }
            @Override
            public void onFault(int code, String errorMsg) {
                super.onFault(code, errorMsg);
                currentLoc.requestFocus();
                mediaPlayerErr.start();
                setVibrator();
            }
            @Override
            public void onError(Throwable e) {
                super.onError(e);
                currentLoc.requestFocus();
                mediaPlayerErr.start();
                setVibrator();
            }
            @Override
            public void onFinally() {
                oldLoc = null;
                currentLoc.setText("");
            }
        });
    }

    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_ENTER){
            if (event.getAction()==KeyEvent.ACTION_UP){
                switch (v.getId()){
                    case R.id.current_loc:
                        getLocRatio();
                        break;
                    case R.id.barcode:
                        getLocGoodsInfo();
                        break;
                }
            }
            if (event.getAction()==KeyEvent.ACTION_DOWN){
                if (v.getId()==R.id.number){
                    btn.requestFocus();
                    btn.requestFocusFromTouch();
                }
                if (v.getId()==R.id.check_btn){
                    stocktaking();
                }
            }
        }
        return false;
    }
}