package com.example.iot_controlhost.utils.log;

import android.util.Log;

import com.example.iot_controlhost.utils.database.LogDBManager;
import com.example.iot_controlhost.utils.network.TopicClass;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import timber.log.Timber;

/**
 * 日志用户查看用
 */
public class UserLog extends Timber.Tree {
    public static final String FILTER_ALL = "全部日志";
    public static final String FILTER_USER_ALL = "全部用户日志";
    public static final String FILTER_DIAGNOSTIC = "系统诊断日志";
    public static final String FILTER_DIAGNOSTIC_AUTO = "自动控制诊断";
    public static final String FILTER_DIAGNOSTIC_CONTROLLER = "控制器诊断";
    public static final String FILTER_DIAGNOSTIC_SENSOR = "传感器诊断";
    public static final String FILTER_DIAGNOSTIC_NETWORK = "网络诊断";
    public static final String FILTER_OPERATE = "操作日志";
    public static final String FILTER_USER_SENSOR = "用户传感器日志";
    public static final String FILTER_SENSOR = "传感器日志";
    public static final String FILTER_CONTROLLER = "控制器日志";
    public static final String FILTER_TASK = "作业日志";
    public static final String FILTER_SYSTEM = "用户系统日志";

    /**
     * 用户-操作类
     */
    public static final String TAG_USER_OPERATE = "用户-操作类";
    /**
     * 用户-传感器类
     */
    public static final String TAG_USER_SENSOR = "用户-传感器类";
    /**
     * 用户-人工作业类
     */
    public static final String TAG_USER_TASK = "用户-作业类";
    /**
     * 用户-系统类
     */
    public static final String TAG_USER_SYSTEM = "用户-系统类";

    public static List<String> getUserLogTags() {
        List<String> tags = new ArrayList<>();
        Collections.addAll(tags, TAG_USER_OPERATE, TAG_USER_SENSOR, TAG_USER_TASK, TAG_USER_SYSTEM);
        return tags;
    }

    public static List<String> getUserQueryFilters() {
        return Arrays.asList(FILTER_ALL, FILTER_USER_ALL, FILTER_OPERATE, FILTER_USER_SENSOR,
                FILTER_TASK, FILTER_SYSTEM, FILTER_DIAGNOSTIC, FILTER_DIAGNOSTIC_AUTO,
                FILTER_CONTROLLER, FILTER_SENSOR, FILTER_DIAGNOSTIC_NETWORK);
    }

    /**
     * 将界面筛选项转换为实际存储标签，成功和错误级别都包含在同一分类中。
     */
    public static List<String> getStorageTagsForFilter(String filter) {
        if (FILTER_DIAGNOSTIC.equals(filter)) {
            return MyLog.getSystemLogTags();
        }
        if (FILTER_DIAGNOSTIC_AUTO.equals(filter)) {
            return tagsWithError(MyLog.TAG_AUTO);
        }
        if (FILTER_DIAGNOSTIC_CONTROLLER.equals(filter) || FILTER_CONTROLLER.equals(filter)) {
            return tagsWithError(MyLog.TAG_CONTROLLER);
        }
        if (FILTER_DIAGNOSTIC_SENSOR.equals(filter) || FILTER_SENSOR.equals(filter)) {
            return tagsWithError(MyLog.TAG_SENSOR);
        }
        if (FILTER_DIAGNOSTIC_NETWORK.equals(filter)) {
            return tagsWithError(MyLog.TAG_NETWORK);
        }
        if (FILTER_OPERATE.equals(filter) || TAG_USER_OPERATE.equals(filter)) {
            return tagsWithError(TAG_USER_OPERATE);
        }
        if (FILTER_USER_SENSOR.equals(filter) || TAG_USER_SENSOR.equals(filter)) {
            return tagsWithError(TAG_USER_SENSOR);
        }
        if (FILTER_TASK.equals(filter) || TAG_USER_TASK.equals(filter)) {
            return tagsWithError(TAG_USER_TASK);
        }
        if (FILTER_SYSTEM.equals(filter) || TAG_USER_SYSTEM.equals(filter)) {
            return tagsWithError(TAG_USER_SYSTEM);
        }
        List<String> tags = new ArrayList<>();
        for (String userTag : getUserLogTags()) {
            tags.addAll(tagsWithError(userTag));
        }
        if (FILTER_ALL.equals(filter) || filter == null) {
            tags.addAll(MyLog.getSystemLogTags());
        }
        return tags;
    }

    private static List<String> tagsWithError(String tag) {
        return Arrays.asList(tag, tag + MyLog.TAG_ERROR);
    }

    public static String getCategoryName(String tag) {
        return tag == null ? "未知" : tag;
    }

    public static void operate(String msg) {
        Timber.tag(TAG_USER_OPERATE).i(msg);
    }

    public static void operate(String source, String msg) {
        operate(formatSource(source, msg));
    }

    public static void operateError(String msg) {
        Timber.tag(TAG_USER_OPERATE + MyLog.TAG_ERROR).e(msg);
    }

    public static void operateError(String source, String msg) {
        operateError(formatSource(source, msg));
    }

    public static void task(String msg) {
        Timber.tag(TAG_USER_TASK).i(msg);
    }

    public static void taskError(String msg) {
        Timber.tag(TAG_USER_TASK + MyLog.TAG_ERROR).e(msg);
    }

    public static void sensor(String msg) {
        Timber.tag(TAG_USER_SENSOR).i(msg);
    }

    public static void sensorError(String msg) {
        Timber.tag(TAG_USER_SENSOR + MyLog.TAG_ERROR).e(msg);
    }

    public static void system(String msg) {
        Timber.tag(TAG_USER_SYSTEM).i(msg);
    }

    public static void system(String source, String msg) {
        system(formatSource(source, msg));
    }

    public static void systemError(String msg) {
        Timber.tag(TAG_USER_SYSTEM + MyLog.TAG_ERROR).e(msg);
    }

    public static void systemError(String source, String msg) {
        systemError(formatSource(source, msg));
    }

    /**
     * 崩溃场景使用非阻塞入口，防止数据库繁忙时阻断进程重启。
     */
    public static void systemErrorImmediately(String msg) {
        persistAndUpload(TAG_USER_SYSTEM + MyLog.TAG_ERROR, Log.ERROR, msg, new Date());
    }

    private static String formatSource(String source, String msg) {
        return "[来源=" + source + "] " + msg;
    }

    @Override
    protected void log(int priority, String tag, String message, Throwable t) {
        //只有特定UserLog日志才能处理
        if (tag == null || !isUserLogTag(tag)) {
            return;
        }
        persistAndUpload(tag, priority, message, new Date());
    }

    private static boolean isUserLogTag(String tag) {
        return tag.contains(TAG_USER_OPERATE)
                || tag.contains(TAG_USER_SENSOR)
                || tag.contains(TAG_USER_TASK)
                || tag.contains(TAG_USER_SYSTEM);
    }

    private static void persistAndUpload(String tag, int priority, String message, Date datetime) {
        com.example.iot_controlhost.model.Log entry =
                new com.example.iot_controlhost.model.Log(tag, priority, datetime, message);
        Log.println(priority, tag, message);
        LogDBManager.insertLog(entry, saved -> {
            if (!saved) {
                Log.e(TAG_USER_SYSTEM, "用户日志本地落库失败，已取消上传以避免两端数据不一致");
                return;
            }
            TopicClass.uploadLog(toServerTag(tag), toServerPriority(tag), message, datetime);
        });
    }

    private static int toServerTag(String tag) {
        if (tag.contains(TAG_USER_OPERATE)) {
            return 1;
        }
        if (tag.contains(TAG_USER_SENSOR)) {
            return 2;
        }
        if (tag.contains(TAG_USER_TASK)) {
            return 3;
        }
        return 4;
    }

    private static int toServerPriority(String tag) {
        // 服务端：1调试、2信息、3警告
        return tag.contains(MyLog.TAG_ERROR) ? 3 : 2;
    }

}
