package com.example.iot_controlhost.ui.dialog;

import android.content.Context;

import androidx.recyclerview.widget.LinearLayoutManager;

import com.example.iot_controlhost.R;
import com.example.iot_controlhost.adapter.LogAdapter;
import com.example.iot_controlhost.base.BaseDialog;
import com.example.iot_controlhost.databinding.DialogLogBinding;
import com.example.iot_controlhost.databinding.ItemLogBinding;
import com.example.iot_controlhost.model.Log;
import com.example.iot_controlhost.ui.view.CustomSpinnerAdapter;
import com.example.iot_controlhost.utils.DialogUtil;
import com.example.iot_controlhost.utils.database.LogDBManager;
import com.example.iot_controlhost.utils.log.UserLog;
import com.xuexiang.rxutil2.rxjava.RxJavaUtils;
import com.xuexiang.rxutil2.rxjava.task.RxAsyncTask;

import java.util.Collections;
import java.util.List;

/**
 * 日志管理弹窗。
 */
public class LogDialog extends BaseDialog<DialogLogBinding> {

    private final LogAdapter adapter;
    private String currentFilter = UserLog.FILTER_ALL;
    private Log pageCursor;
    private boolean loading;
    private int queryGeneration;

    public LogDialog(Context context, List<Log> initialLogs) {
        super(context);
        List<Log> safeLogs = initialLogs == null ? Collections.emptyList() : initialLogs;
        adapter = new LogAdapter(safeLogs, ItemLogBinding.class);
        pageCursor = getLastLog(safeLogs);

        binding.rvLog.setLayoutManager(new LinearLayoutManager(context));
        binding.rvLog.setAdapter(adapter);
        binding.acInput.setHint(context.getString(R.string.select_log_tag));
        binding.acInput.setAdapter(new CustomSpinnerAdapter(
                context, UserLog.getUserQueryFilters().toArray(new String[0])));
        binding.acInput.setText(UserLog.FILTER_ALL, false);

        binding.refreshLayout.setOnRefreshListener(refreshLayout -> refreshLogs(false));
        binding.refreshLayout.setOnLoadMoreListener(refreshLayout -> loadNextPage());
        binding.btnQuery.setOnClickListener(view -> refreshLogs(true));
    }

    private void refreshLogs(boolean showLoading) {
        if (loading) {
            binding.refreshLayout.finishRefresh();
            return;
        }
        loading = true;
        int generation = ++queryGeneration;
        String requestedFilter = getSelectedFilter();
        binding.refreshLayout.resetNoMoreData();
        if (showLoading) {
            DialogUtil.showLoadingDialog(mContext, "正在读取日志...");
        }
        RxJavaUtils.executeAsyncTask(new RxAsyncTask<Object, List<Log>>(null) {
            @Override
            public List<Log> doInIOThread(Object o) {
                return LogDBManager.queryLatest(requestedFilter);
            }

            @Override
            public void doInUIThread(List<Log> logs) {
                if (generation == queryGeneration) {
                    currentFilter = requestedFilter;
                    pageCursor = getLastLog(logs);
                    adapter.setDataList(logs);
                    updateLoadMoreState(logs);
                }
                loading = false;
                binding.refreshLayout.finishRefresh();
                if (showLoading) {
                    DialogUtil.hideLoadingDialog();
                }
            }
        });
    }

    private void loadNextPage() {
        if (loading || pageCursor == null) {
            binding.refreshLayout.finishLoadMoreWithNoMoreData();
            return;
        }
        loading = true;
        int generation = queryGeneration;
        Log requestedCursor = pageCursor;
        String requestedFilter = currentFilter;
        RxJavaUtils.executeAsyncTask(new RxAsyncTask<Object, List<Log>>(null) {
            @Override
            public List<Log> doInIOThread(Object o) {
                return LogDBManager.queryNext(requestedFilter, requestedCursor);
            }

            @Override
            public void doInUIThread(List<Log> logs) {
                if (generation == queryGeneration) {
                    if (!logs.isEmpty()) {
                        adapter.addDataList(logs);
                        pageCursor = getLastLog(logs);
                    }
                    updateLoadMoreState(logs);
                } else {
                    binding.refreshLayout.finishLoadMore();
                }
                loading = false;
            }
        });
    }

    private void updateLoadMoreState(List<Log> logs) {
        if (LogDBManager.isFullPage(logs)) {
            binding.refreshLayout.finishLoadMore();
        } else {
            binding.refreshLayout.finishLoadMoreWithNoMoreData();
        }
    }

    private String getSelectedFilter() {
        String filter = binding.acInput.getText().toString().trim();
        return filter.isEmpty() ? UserLog.FILTER_ALL : filter;
    }

    private Log getLastLog(List<Log> logs) {
        return logs == null || logs.isEmpty() ? null : logs.get(logs.size() - 1);
    }
}
