package com.qiaoba.module.tenant.util;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.StrUtil;
import com.qiaoba.common.database.util.DbUtil;
import org.springframework.core.io.ClassPathResource;

import java.nio.charset.Charset;
import java.sql.Connection;
import java.util.List;

/**
 * 数据初始化工具类
 *
 * @author ailanyin
 * @version 1.0
 * @since 2023/6/5 16:28
 */
public class InitDataUtil {

    private InitDataUtil() {
    }

    /**
     * 角色-超管ID
     */
    private static final ThreadLocal<Long> ROLE_SUPER_ADMIN_ID = new ThreadLocal<>();

    /**
     * 用户-超管ID
     */
    private static final ThreadLocal<Long> USER_SUPER_ADMIN_ID = new ThreadLocal<>();

    public static void removeLocal() {
        ROLE_SUPER_ADMIN_ID.remove();
        USER_SUPER_ADMIN_ID.remove();
    }

    public static void handleSysConfig(Connection conn, String tenantId, String filePath) throws Exception {
        handleSql(conn, tenantId, filePath);
    }

    public static void handleSysPost(Connection conn, String tenantId, String filePath) throws Exception {
        handleSql(conn, tenantId, filePath);
    }

    public static void handleSysRole(Connection conn, String tenantId, String filePath) throws Exception {
        handleUserOrRole(conn, tenantId, filePath, true);
    }

    private static void handleUserOrRole(Connection conn, String tenantId, String filePath, Boolean isRole) throws Exception {
        ClassPathResource resource = new ClassPathResource(filePath);
        List<String> lines = FileUtil.readLines(resource.getFile(), Charset.defaultCharset());
        StringBuilder sb = new StringBuilder();
        long superAdminId = new Snowflake().nextId();
        if (isRole) {
            ROLE_SUPER_ADMIN_ID.set(superAdminId);
        } else {
            USER_SUPER_ADMIN_ID.set(superAdminId);
        }
        for (int i = 0; i < lines.size(); i++) {
            String line = lines.get(i);
            if (StrUtil.isBlank(line)) {
                continue;
            }
            if (i == 0) {
                // 第1行是超管
                line = StrUtil.format(line, superAdminId, tenantId);
            } else {
                Snowflake snowflake = new Snowflake();
                line = StrUtil.format(line, snowflake.nextId(), tenantId);
            }
            sb.append(line);
        }
        String sql = sb.toString();
        if (StrUtil.isNotBlank(sql)) {
            DbUtil.runSql(conn, sql);
        }
    }

    public static void handleSysUser(Connection conn, String tenantId, String filePath) throws Exception {
        handleUserOrRole(conn, tenantId, filePath, false);
    }

    public static void bindUserAndRole(Connection conn, String tenantId) throws Exception {
        // user_id role_id tenant_id
        String sql = StrUtil.format("INSERT INTO sys_user_role VALUES ('{}', '{}', '{}');",
                USER_SUPER_ADMIN_ID.get(),
                ROLE_SUPER_ADMIN_ID.get(), tenantId);
        DbUtil.runSql(conn, sql);
    }

    public static void bindRoleAndMenu(Connection conn, String tenantId) throws Exception {
        String sql = "INSERT INTO sys_role_menu VALUES ('{}', '{}', '{}');";
        StringBuilder sb = new StringBuilder();
        List<String> menuIds = MenuUtil.getAllMenuIdsByTenantId(conn, tenantId);
        for (String menuId : menuIds) {
            sb.append(StrUtil.format(sql, ROLE_SUPER_ADMIN_ID.get(), menuId, tenantId));
        }
        String sbStr = sb.toString();
        if (StrUtil.isNotBlank(sbStr)) {
            DbUtil.runSql(conn, sbStr);
        }
    }

    private static void handleSql(Connection conn, String tenantId, String filePath) throws Exception {
        ClassPathResource resource = new ClassPathResource(filePath);
        List<String> lines = FileUtil.readLines(resource.getFile(), Charset.defaultCharset());
        StringBuilder sb = new StringBuilder();
        for (String line : lines) {
            if (StrUtil.isNotBlank(line)) {
                Snowflake snowflake = new Snowflake();
                line = StrUtil.format(line, snowflake.nextId(), tenantId);
                sb.append(line);
            }
        }
        String sql = sb.toString();
        if (StrUtil.isNotBlank(sql)) {
            DbUtil.runSql(conn, sql);
        }
    }
}
