package com.baoshi.swms.fragment;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.InputType;
import android.view.Display;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import com.baoshi.swms.activity.changeView.ListViewFooterChange;
import com.baoshi.swms.activity.item.WaybillDispatchItemActivity;
import com.baoshi.swms.adapter.WaybillDispatchList;
import com.baoshi.swms.bean.Waybill;
import com.baoshi.swms.bean.dto.WaybillData;
import com.baoshi.swms.inter.OnRefreshListener;
import com.baoshi.swms.net.callback.WasHandlerCallback;
import com.baoshi.swms.net.subscribe.WasSubscribe;
import com.baoshi.swms.part.InputEditDialog;
import com.baoshi.swms.part.RefreshHeader;
import com.baoshi.swms.R;
import com.baoshi.swms.util.DateUtil;
import com.baoshi.swms.util.Hint;
import com.bigkoo.pickerview.builder.TimePickerBuilder;
import com.bigkoo.pickerview.listener.OnTimeSelectListener;
import com.bigkoo.pickerview.view.TimePickerView;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 运单调配Fragment
 *
 * @author Zhendong Zhou
 * @date   2021/12/6 11:37
 */
public class WaybillDispatch extends Fragment implements View.OnClickListener, TextView.OnEditorActionListener ,
        InputEditDialog.OnTextSendListener, AbsListView.OnScrollListener, OnRefreshListener ,
        AdapterView.OnItemClickListener, OnTimeSelectListener {
    private static final String ARG_KEY = "VIEW_ID";

    private int id;                                         //当前碎片视图ID
    private final List<Waybill> waybills = new ArrayList<>();     //listview数据池
    private final Map<String,Double> mapping = new HashMap<>();     //专线费映射
    private View rootView;                                  //当前视图
    //局部控件对象
    private TextView view;
    private TextView fee;
    //滚动元素节点
    private int topIndex;
    private int status;
    //软键盘文本框对象
    private InputEditDialog mInputEditDialog;

    private RefreshHeader listView;                              //ListView对象
    private WaybillDispatchList adapter;
    private ListViewFooterChange viewChange; //变更视图对象
    private boolean isNoneLoad = false;
    private final HashMap<String,String> params = new HashMap<String,String>(){{
        put("search","");
        put("deliver_at","");
        put("page","1");
        put("paginate","20");
    }};
    private int currentIndex;

    //构造方法传递目标fragment碎片视图
    public static WaybillDispatch newInstance(int param) {
        WaybillDispatch fragment = new WaybillDispatch();
        Bundle args = new Bundle();
        args.putInt(ARG_KEY, param);
        fragment.setArguments(args);
        return fragment;
    }

    /**
     * dispatch生命周期
     * */
    //初始化
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null){
            id = getArguments().getInt(ARG_KEY);
        }
    }
    //加载视图
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        if (rootView==null)rootView = inflater.inflate(id, container, false);
        return rootView;
    }
    //初始化activity 到此视图方才加载完毕
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        //渲染视图与加载局部变量
        rendingView();
        //视图渲染完毕才能加载视图更新对象
        viewChange = new ListViewFooterChange(getActivity(), listView);
        //加载数据
        loadListViewItem();
        //注册事件
        registerEvent();
    }
    //子ITEM返回时的携参
    @Override
    public void onActivityResult(int requestCode, int resultCode,@Nullable Intent data) {
        if (data==null || requestCode!=1)return;
        waybills.set(currentIndex-1,(Waybill) data.getSerializableExtra("waybill"));
        adapter.notifyDataSetChanged();
        Hint.toastShort(getContext(),"修改成功",Hint.COMMON);
    }

    /**
     * 初始化与全局行为
     * */
    //注册事件
    private void registerEvent() {
        ImageView imgView = getActivity().findViewById(R.id.date_picker_2);
        ImageView edit = getActivity().findViewById(R.id.edit_fee);
        ImageView back = getActivity().findViewById(R.id.waybill_back);
        EditText searchView = getActivity().findViewById(R.id.search_waybill);

        //回退
        back.setOnClickListener(this);
        //搜索
        searchView.setOnEditorActionListener(this);
        //时间控件监听
        view.setOnClickListener(this);
        imgView.setOnClickListener(this);
        //文本框控件监听
        edit.setOnClickListener(this);
        //滚动条监听
        listView.setOnScrollListener(this);
        //下拉刷新
        listView.setOnRefreshListener(this);
        //listview item点击
        listView.setOnItemClickListener(this);
    }
    //渲染视图
    private void rendingView() {
        mInputEditDialog = new InputEditDialog(getActivity(), R.style.InputDialog, "请输入按日专线费", InputType.TYPE_NUMBER_FLAG_SIGNED);
        listView = getActivity().findViewById(R.id.bill_list);
        adapter = new WaybillDispatchList(waybills,getActivity());
        view = getActivity().findViewById(R.id.date_picker_1);
        fee = getActivity().findViewById(R.id.fee);
        listView.setAdapter(adapter);
    }
    //初始化listview
    private void loadListViewItem() {
        if (isNoneLoad)return; //正确做法应该卸载监听器 暂时不知 所以用标记来跳过加载
        viewChange.addLoadFooter();
        isNoneLoad = true;
        requestData(false);
    }
    //加载数据
    private void requestData(boolean after)
    {
        String search = params.get("search");
        String deliverAt = params.get("deliver_at");
        int page = Integer.parseInt(params.get("page"));
        int paginate = Integer.parseInt(params.get("paginate"));
        WasSubscribe.getDispatchList(search, deliverAt, page, paginate, new WasHandlerCallback<WaybillData>() {
            @Override
            public void onSuccess(WaybillData result) {
                ArrayList<Waybill> currentData = result.getWaybills();
                if (currentData.size()>0)mapping.putAll(result.getMapping());//合并映射
                if (after)waybills.clear();
                waybills.addAll(currentData);
                if (waybills.size()==0){
                    view.setText("暂无");
                    fee.setText("");
                }else{
                    String date = currentData.get(0).getDeliverAt().substring(0,10);
                    view.setText(date);
                    fee.setText(mapping.get(date)==null ? "" : String.valueOf(mapping.get(date)));
                }
                super.onSuccess(result); //这里觉得何时执行onFinally
                if (currentData.size()<Integer.parseInt(params.get("paginate"))){
                    viewChange.addLoadStopFooter();
                    isNoneLoad = true; //如果本次加载数据不足N条 则标记加载完毕
                }else if (waybills.size()==0){ //如果加载完毕了 数据总量仍为0 那么属于没有数据 显示空数据视图
                    viewChange.addLoadNoneFooter();
                    isNoneLoad = true;
                }else isNoneLoad = false;
                if (after){
                    listView.setAdapter(adapter);
                    listView.onRefreshComplete();
                }else adapter.notifyDataSetChanged();
            }
            @Override
            public void onFinally() {
                listView.removeFooterView(viewChange.mLoadLayout);
                isNoneLoad = false;
            }
        });
    }

    /**
     * 控件获取与变更
     * */
    //专线费文本框控件
    private void showInputMsgDialog() {
        WindowManager windowManager = getActivity().getWindowManager();
        Display display = windowManager.getDefaultDisplay();
        WindowManager.LayoutParams lp = mInputEditDialog.getWindow().getAttributes();
        lp.width = (int) (display.getWidth()); //设置宽度
        mInputEditDialog.getWindow().setAttributes(lp);
        mInputEditDialog.setCancelable(true);
        mInputEditDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
        mInputEditDialog.show();
    }
    //初始化calender 时间选择器控件
    private void initCalendar() {
        String[] dateTxt = view.getText().toString().split("-");
        if (dateTxt.length!=3){
            Toast.makeText(getActivity(), "数据异常，无法处理", Toast.LENGTH_SHORT).show();
            return;
        }
        TimePickerView pvTime = new TimePickerBuilder(getActivity(), this).build();
        Calendar startDate = Calendar.getInstance();
        startDate.set(Integer.parseInt(dateTxt[0]), Integer.parseInt(dateTxt[1])-1,
                Integer.parseInt(dateTxt[2]));
        pvTime.setDate(startDate);
        pvTime.setTitleText("选择发货时间");
        pvTime.show();
    }

    /**
     * 事件监听实例
     * */
    @Override
    public void onClick(View v) {
        if (v.getId()==R.id.waybill_back){
            getActivity().finish();
        }else if (v.getId()==R.id.date_picker_1 || v.getId()==R.id.date_picker_2){
            initCalendar();
        }else if (v.getId()==R.id.edit_fee){
            showInputMsgDialog();
            mInputEditDialog.setmOnTextSendListener(this);
        }
    }
    @Override
    public boolean onEditorAction(TextView v, int i, KeyEvent keyEvent) {
        if (i == EditorInfo.IME_ACTION_SEARCH){
            InputMethodManager manager = ((InputMethodManager)getContext().getSystemService(Context.INPUT_METHOD_SERVICE));
            if (manager != null)
                manager.hideSoftInputFromWindow(view.getWindowToken(),InputMethodManager.HIDE_NOT_ALWAYS);
            String txt = v.getText().toString();
            if (!txt.equals(params.get("search"))){
                isNoneLoad = false;
                params.put("search", txt);
                params.put("deliver_at", "");
                params.put("page", "1");
                waybills.clear();
                adapter = new WaybillDispatchList(waybills,getActivity());
                listView.setAdapter(adapter);
                loadListViewItem();
            }
        }
        return false;
    }
    @Override
    public void onTextSend(String msg) {
        Double feeInfo = checkDailyBillingFee(msg);
        if (feeInfo==null){
            return;
        }
        String date = checkDailyBillingDate();
        if (date==null){
            return;
        }

        WasSubscribe.dailyBilling(date, feeInfo, new WasHandlerCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                if (result){
                    fee.setText(msg);
                    mapping.put(date,feeInfo);
                    Hint.toastShort(getContext(), "修改成功", Hint.COMMON);
                }else{
                    Hint.toastShort(getContext(), "专线费修改异常", Hint.ERROR);
                }
            }
        });
    }
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        status = scrollState;
    }
    @Override
    public void onScroll(AbsListView v, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        topIndex = firstVisibleItem;
        switch (this.status){
            case AbsListView.OnScrollListener.SCROLL_STATE_FLING:
                if (topIndex+visibleItemCount==totalItemCount){
                    if (!isNoneLoad)params.put("page",String.valueOf(Integer.parseInt(params.get("page"))+1));
                    loadListViewItem();
                }
                String date = waybills.get(topIndex).getDeliverAt().substring(0,10);
                if (!date.equals(view.getText())){
                    view.setText(date);
                    fee.setText(mapping.get(date)==null ? "" : String.valueOf(mapping.get(date)));
                }
                break;
            case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
                break;
            case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
        }
    }
    @Override
    public void refreshData() {
        if (topIndex==0){
            params.put("search","");
            params.put("deliver_at","");
            params.put("page","1");
            requestData(true);
        } else listView.onRefreshComplete();
    }
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        currentIndex = position;

        Intent intent = new Intent(getActivity(), WaybillDispatchItemActivity.class);
        Bundle bundle = new Bundle();
        bundle.putSerializable("waybill", waybills.get(position-1));
        intent.putExtras(bundle);
        intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
        startActivityForResult(intent,1);
    }
    @Override
    public void onTimeSelect(Date date, View v) {
        String deliverDate = DateUtil.getTime(date);
        if (!deliverDate.equals("") && !deliverDate.equals(params.get("deliver_at"))){
            view.setText(deliverDate);
            isNoneLoad = false;
            params.put("search", "");
            params.put("deliver_at", deliverDate);
            params.put("page", "1");
            waybills.clear();
            adapter = new WaybillDispatchList(waybills,getActivity());
            listView.setAdapter(adapter);
            loadListViewItem();
        }
    }

    /**
     * 参数校验与格式化
     * */
    private Double checkDailyBillingFee(String msg){
        double feeInfo;
        try {
            feeInfo = Double.parseDouble(msg);
        }catch (NumberFormatException e){
            Hint.toastShort(getContext(), "输入非法,非数字与科学计数法", Hint.COMMON);
            return null;
        }
        return feeInfo;
    }
    private String checkDailyBillingDate(){
        String date = view.getText().toString();
        if (date.split("-").length!=3){
            Toast.makeText(getActivity(), "请选择正确日期", Toast.LENGTH_SHORT).show();
            return null;
        }
        return date;
    }
}
