package com.ruoyi.system.service;
import org.springframework.stereotype.Service;
import java.sql.*;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;


@Service
public class TDegnineAlarm {

    private static ExecutorService threadPool= Executors.newCachedThreadPool();
    // 静态变量保证全局唯一
    private static Statement stmt = null;
    private static Connection conn = null;
    // 静态代码块 - 项目启动时自动执行且仅执行一次
    static {
        ConnectionLibrary();
    }

    /**
     * 初始化数据库连接（仅执行一次）
     */
    private static void ConnectionLibrary() {
        // 避免重复初始化
        if (conn != null) {
            return;
        }
        String url = "jdbc:TAOS://localhost:6030/fault?user=root&password=taosdata";
        Properties properties = new Properties();
        properties.setProperty("charset", "UTF-8");
        properties.setProperty("locale", "en_US.UTF-8");
        properties.setProperty("timezone", "Asia/Shanghai");
        try {
            // 手动加载3.2.3驱动
            Class.forName("com.taosdata.jdbc.TSDBDriver");
            conn = DriverManager.getConnection(url, properties);
            TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
            stmt = conn.createStatement();
            System.out.println("TDengine 3.2.3 驱动连接成功！");
        } catch (ClassNotFoundException e) {
            System.err.println("未找到TDengine 3.2.3驱动，请检查Maven依赖是否正确");
            e.printStackTrace();
        } catch (SQLException e) {
            System.err.println("TDengine 连接失败，错误信息：" + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 获取全局唯一的Statement对象
     */
    public static Statement getStatement() {
        // 双重检查，防止连接失效
        if (stmt == null || conn == null) {
            ConnectionLibrary();
        }
        return stmt;
    }

    /**
     * 获取全局唯一的Connection对象
     */
    public static Connection getConnection() {
        // 双重检查，防止连接失效
        if (conn == null) {
            ConnectionLibrary();
        }
        return conn;
    }

    /**
     * 关闭数据库连接，释放资源
     */
    public static void closeConnection() {
        try {
            if (stmt != null) {
                stmt.close();
            }
            if (conn != null) {
                conn.close();
            }
            System.out.println("TDengine 连接已关闭");
        } catch (SQLException e) {
            System.err.println("关闭TDengine连接失败：" + e.getMessage());
            e.printStackTrace();
        } finally {
            stmt = null;
            conn = null;
        }
    }


    /**
     * 根据标签获取表的名称
     * 添加数据到TDengine时序数据中
     * */
    public void shibaihou(Map<String, Object> shuzi, String supertablename, String table, String deviceid) throws SQLException {
        //  解析数据value
        String value=shuzi.values().stream()
                .map(obj -> "\'" + obj.toString() + "\'") // 在每个元素前后加上单引号
                .collect(Collectors.joining(","));
        //解析数据key       （这里的key用于创建表）
        String key=shuzi.keySet().stream()
                .map(obj -> "`" + obj.toString() + "`") // 在每个元素前后加上单引号
                .collect(Collectors.joining(","));
        //解析数据key       （这里的可以用于添加数据时使用）
        String inkey=shuzi.keySet().stream()
                .map(obj -> obj.toString()) // 在每个元素前后加上单引号
                .collect(Collectors.joining(","));
        //给每个key添加数据的类型
        StringBuilder tia=new StringBuilder();
        for (int i=0;i<key.split(",").length;i++){
            tia.append(key.split(",")[i]).append(" VARCHAR(255)");
            if (i<key.split(",").length-1){
                tia.append(",");
            }
        }
        //子表名称
        List<String> zibiaoname = new ArrayList();
        //接收数据库中的列的名称
        List<String> columnNames = new ArrayList<>();
        // 接收数据库中列的值然后进行拼接
        StringBuilder u = new StringBuilder();
//——————————————————————————————————————————————————————————分隔  查询超级表是否存在———————————————————————————————————————————————
        //进入数据库中
        boolean s=false;
        List<String> tableNamesc = new ArrayList<>();
        try{
            stmt.executeUpdate("use fault");
            ResultSet resultSet = stmt.executeQuery("SHOW stables");
            while (resultSet.next()) {
                tableNamesc.add(resultSet.getString(1));
            }
        }catch (SQLException e){
            e.printStackTrace();
        }
        for (String ta:tableNamesc) {
            if (supertablename.equalsIgnoreCase(ta)) {
                s=true;
            }
        }
//——————————————————————————————————————————————————————————分隔      查看子表是否存在——————————————————————————————————————————————————
        if (s==true) {
            ResultSet rsc = stmt.executeQuery("select distinct tbname from " + table + " where location='"+supertablename+"'");
            while (rsc.next()) {
                zibiaoname.add(rsc.getString(1));
            }
            boolean zibiaobu = zibiaoname.isEmpty();
//——————————————————————————————————————————————————————————分隔      添加数据到数据库中（根据以上判断进行校验）——————————————————————————————————————————————————
            try {
                if (zibiaobu == false) {
                    //根据标签获取
                    ResultSet resultSet = stmt.executeQuery("describe " + table);
                    int columnNameIndex = resultSet.findColumn("field");
                    //循环存储数据
                    while (resultSet.next()) {
                        //需要存储一个列的名称
                        columnNames.add(resultSet.getString(columnNameIndex));
                    }
                    for (int z = 0; z < columnNames.size(); z++) {
                        u.append(columnNames.get(z));
                        if (z < columnNames.size() - 1) {
                            u.append(",");
                        }
                    }
                    String commaSeparatedString = u.toString();
                    String[] itemsArry = commaSeparatedString.split(",");
                    List<String> itemsList = Arrays.stream(itemsArry)
                            .collect(Collectors.toList());
                    //获取新子表列和就子表列不同的列
                    String[] stringArray = key.split(",");
                    List<String> qq = new ArrayList<>(Arrays.asList(stringArray));

                    List<String> setCopy = new ArrayList<>(qq);
                    setCopy.removeAll(itemsList);
                    //新增列
                    String[] setCopys = key.split(",");
                    if (setCopys.length > 0) {
                        for (int ar = 0; ar < setCopys.length; ar++) {
                            try {
                                stmt.executeUpdate("ALTER TABLE " + supertablename + " ADD COLUMN " + setCopys[ar]);
                            } catch (Exception e) {
//                                    System.out.println("已经没有要添加的字段了"+e+topic+ tt[q]);
                            }
                        }
                    }
                    //插入数据
                    stmt.executeUpdate("insert into " + table + "(ts," + inkey + ") values(now()," + value + ")");
                } else if (zibiaobu == true) {
                    //创建子表
//                    stmt.executeUpdate("CREATE TABLE IF NOT EXISTS `" + table + "` (ts timestamp,surfacename VARCHAR(100)," + tia + ")");
                    stmt.executeUpdate("create table " + table + " using " + supertablename + " tags('" + supertablename + "')");
                    //查询超级表的列
                    ResultSet resultSet = stmt.executeQuery("describe `" + supertablename + "`");
                    int columnNameIndex = resultSet.findColumn("field");
                    //循环存储数据
                    while (resultSet.next()) {
                        //需要存储一个列的名称
                        columnNames.add(resultSet.getString(columnNameIndex));
                    }
                    for (int z = 0; z < columnNames.size(); z++) {
                        if (z < columnNames.size() - 1) {
                            u.append(",");
                        }
                        u.append(columnNames.get(z));
                    }
                    String commaSeparatedString = u.toString();
                    String[] itemsArry = commaSeparatedString.split(",");
                    List<String> itemsList = Arrays.stream(itemsArry)
                            .collect(Collectors.toList());
                    //获取新子表列和就子表列不同的列
                    String[] stringArray = key.split(",");
                    List<String> qq = new ArrayList<>(Arrays.asList(stringArray));
                    List<String> setCopy = new ArrayList<>(qq);
                    setCopy.removeAll(itemsList);
                    //插入数据
                    stmt.executeUpdate("insert into " + table + "(ts," + inkey + ")values(now(),"+value + ")");
                }
            } catch (SQLException e) {
                System.out.println(e);
            }
        }else if (s == false) {
            try {
                //创建超级表
                stmt.executeUpdate("create stable "+supertablename+" (ts timestamp," + tia + " ) TAGS (location binary(64))");
                //创建子表
                stmt.executeUpdate("create table " + table + " using " + supertablename + " tags('"+supertablename+"')");
                //将数据插入到表中
                System.out.println("insert into " + table + "(ts," + inkey + ")values(now(),"+value + ")");
                stmt.executeUpdate("insert into " + table + "(ts," + inkey + ")values(now(),"+value + ")");
            } catch (SQLException e) {
                System.out.println(e);
            }
        }
    }

}
