package com.njcn.influxdb.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.text.StrPool;
import cn.hutool.core.util.StrUtil;
import com.njcn.influxdb.param.InfluxDBSqlConstant;
import com.njcn.influxdb.param.InfluxDBTableConstant;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author hongawen
 * @version 1.0.0
 * @date 2022年10月14日 14:29
 */
@Component
public class AssembleSqlUtil {

    private StringBuffer sql;

    /**
     * 组装对应表所有数据
     *
     * @param tabName 表名
     * @return 表数据
     */
    public AssembleSqlUtil select(String tabName) {
        if (StrUtil.isNotBlank(tabName)) {
            this.sql = new StringBuffer().append(InfluxDBSqlConstant.SELECT).append(InfluxDBSqlConstant.ALL).append(InfluxDBSqlConstant.FROM).append(tabName);
            return this;
        } else {
            return null;
        }
    }

    /**
     * 组装指定表对应各个属性的值
     *
     * @param fields  属性名
     * @param tabName 表名
     * @return sql语句
     */
    public AssembleSqlUtil selectField(List<String> fields, String tabName) {
        //未传属性时，组装查询所有属性
        if (CollectionUtil.isEmpty(fields)) {
            return this.select(tabName);
        }
        this.sql = new StringBuffer().append(InfluxDBSqlConstant.SELECT)
                .append(String.join(StrPool.COMMA, fields))
                .append(StrPool.C_SPACE)
                .append(InfluxDBSqlConstant.FROM)
                .append(tabName);
        return this;
    }

    /**
     * 组装查询条件
     *
     * @param andMap  AND 关系
     * @param orField OR 字段
     * @param orValue OR 值
     * @return sql语句
     */
    public AssembleSqlUtil where(Map<String, Object> andMap, String orField, List<String> orValue) {
        this.sql.append(InfluxDBSqlConstant.WHERE);
        if (MapUtil.isNotEmpty(andMap)) {
            for (String key : andMap.keySet()) {
                this.sql.append(key).append(InfluxDBSqlConstant.EQ).append(InfluxDBSqlConstant.QM).append(andMap.get(key)).append(InfluxDBSqlConstant.QM).append(InfluxDBSqlConstant.AND);
            }
            if (StrUtil.isBlank(orField)) {
                this.sql.delete(this.sql.lastIndexOf(InfluxDBSqlConstant.AND), this.sql.length());
            }
        }
        if (StrUtil.isNotBlank(orField)) {
            StringBuffer orData = new StringBuffer();
            for (String value : orValue) {
                orData.append(orField).append(InfluxDBSqlConstant.EQ).append(InfluxDBSqlConstant.QM).append(value).append(InfluxDBSqlConstant.QM).append(InfluxDBSqlConstant.OR);
            }
            this.sql.append(InfluxDBSqlConstant.LBK).append(StrUtil.removeSuffix(orData, InfluxDBSqlConstant.OR)).append(InfluxDBSqlConstant.RBK);
        }
        return this;
    }

    /**
     * 组装查询分组sql
     * @param field 属性
     * @param fieldList 属性集合
     * @return sql语句
     */
    public AssembleSqlUtil groupBy(String field, List<String> fieldList) {
        if (StrUtil.isNotBlank(field)) {
            this.sql.append(InfluxDBSqlConstant.GB).append(field);
        } else {
            if (!CollUtil.isEmpty(fieldList)) {
                for (String fieldValue : fieldList) {
                    this.sql.append(InfluxDBSqlConstant.GB).append(fieldValue).append(StrPool.C_COMMA);
                }
                this.sql.delete(this.sql.indexOf(StrPool.COMMA), this.sql.length());
            }
        }
        return this;
    }

    /**
     * 组装查询排序sql
     * @param field 字段
     * @param sortBy 排序
     * @return sql语句
     */
    public AssembleSqlUtil orderBy(String field, String sortBy) {
        if (StrUtil.isNotBlank(sortBy)) {
            this.sql.append(InfluxDBSqlConstant.OB).append(field).append(sortBy);
        } else {
            this.sql.append(InfluxDBSqlConstant.OB).append(field).append(InfluxDBSqlConstant.DESC);
        }
        return this;
    }


    /**
     * sql结束
     */
    public String over() {
        return sql.append(InfluxDBSqlConstant.TZ).toString();
    }

    /**
     * 调用案例，最后以over()方法结束
     */
    public static void main(String[] args) {
        AssembleSqlUtil assembleSqlUtil = new AssembleSqlUtil();
        Map<String,Object> map = new HashMap<>();
        map.put("字段1",100);
        map.put("字段2",200);
        String orField = "字段3";
        List<String> ia = new ArrayList<>();
        ia.add("1");
        ia.add("2");
        System.out.println(assembleSqlUtil.
                select(InfluxDBTableConstant.DAY_V)
                .where(map,orField,ia)
                .groupBy(orField,null)
                .orderBy(InfluxDBTableConstant.TIME,InfluxDBSqlConstant.DESC)
                .over()
        );
        System.out.println(assembleSqlUtil.
                selectField(Stream.of(InfluxDBTableConstant.DUE, InfluxDBTableConstant.REAL)
                        .collect(Collectors.toList()), InfluxDBTableConstant.DAY_V)
                .over());
    }
}
