package top.gtb520.java.backend.apibackserver.db;

import org.yaml.snakeyaml.Yaml;

import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;

public class mysql {
    private String host;
    private int port;
    private String database;
    private String username;
    private String password;
    private Connection connection;

    public mysql() {
        loadOrCreateConfig();
        connect();
    }

    /**
     * 加载或创建数据库配置文件
     */
    private void loadOrCreateConfig() {
        String jarPath = getJarDirectory();
        String configPath = jarPath + "/config/db.yaml";
        
        Path configFilePath = Paths.get(configPath);
        
        // 如果配置文件不存在，则创建默认配置
        if (!Files.exists(configFilePath)) {
            createDefaultConfig(configFilePath);
        }
        
        // 读取配置文件
        try (FileInputStream fis = new FileInputStream(configPath)) {
            Yaml yaml = new Yaml();
            Map<String, Object> data = yaml.load(fis);
            
            @SuppressWarnings("unchecked")
            Map<String, Object> mysqlConfig = (Map<String, Object>) data.get("mysql");
            
            this.host = (String) mysqlConfig.get("host");
            this.port = ((Number) mysqlConfig.get("port")).intValue();
            this.database = (String) mysqlConfig.get("database");
            this.username = (String) mysqlConfig.get("username");
            this.password = (String) mysqlConfig.get("password");
            
        } catch (IOException e) {
            throw new RuntimeException("无法读取数据库配置文件", e);
        }
    }

    /**
     * 创建默认配置文件
     */
    private void createDefaultConfig(Path configFilePath) {
        try {
            // 确保目录存在
            Files.createDirectories(configFilePath.getParent());

            // 创建默认配置
            DbConfig defaultConfig = new DbConfig();

            // 创建YAML内容
            Map<String, Object> config = new HashMap<>();
            Map<String, Object> mysqlSection = new HashMap<>();
            mysqlSection.put("host", defaultConfig.host);
            mysqlSection.put("port", defaultConfig.port);
            mysqlSection.put("database", defaultConfig.database);
            mysqlSection.put("username", defaultConfig.username);
            mysqlSection.put("password", defaultConfig.password);
            config.put("mysql", mysqlSection);

            // 写入YAML文件
            Yaml yaml = new Yaml();
            String yamlContent = yaml.dump(config);

            Files.write(configFilePath, yamlContent.getBytes());

            System.out.println("已创建默认数据库配置文件: " + configFilePath);
        } catch (IOException e) {
            throw new RuntimeException("无法创建数据库配置文件", e);
        }
    }

    /**
     * 获取JAR包所在目录
     */
    private String getJarDirectory() {
        try {
            String path = getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath();
            if (path.startsWith("/")) {
                path = path.substring(1);
            }
            Path jarPath = Paths.get(path).getParent();
            return jarPath.toString();
        } catch (Exception e) {
            // 如果无法获取JAR路径，返回当前工作目录
            return System.getProperty("user.dir");
        }
    }

    /**
     * 连接到数据库
     */
    public void connect() {
        try {
            String url = String.format("jdbc:mysql://%s:%d/%s?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true",
                    host, port, database);
            connection = DriverManager.getConnection(url, username, password);

            System.out.println("Connecting to database: " + url + " with username: " + username + " and password: " + password);

            System.out.println("数据库连接成功！");
        } catch (SQLException e) {
            throw new RuntimeException("数据库连接失败", e);
        }
    }

    /**
     * 关闭数据库连接
     */
    public void close() {
        try {
            if (connection != null && !connection.isClosed()) {
                connection.close();
                System.out.println("数据库连接已关闭");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 执行查询语句
     */
    public ResultSet query(String sql) throws SQLException {
        if (connection == null || connection.isClosed()) {
            connect(); // 尝试重新连接
        }
        Statement statement = connection.createStatement();
        return statement.executeQuery(sql);
    }

    /**
     * 执行查询语句并返回PreparedStatement
     */
    public PreparedStatement prepareQuery(String sql) throws SQLException {
        if (connection == null || connection.isClosed()) {
            connect(); // 尝试重新连接
        }
        return connection.prepareStatement(sql);
    }

    /**
     * 执行更新语句（INSERT, UPDATE, DELETE）
     */
    public int update(String sql) throws SQLException {
        if (connection == null || connection.isClosed()) {
            connect(); // 尝试重新连接
        }
        Statement statement = connection.createStatement();
        return statement.executeUpdate(sql);
    }

    /**
     * 执行更新语句（带参数的PreparedStatement）
     */
    public int update(PreparedStatement pstmt) throws SQLException {
        if (connection == null || connection.isClosed()) {
            connect(); // 尝试重新连接
        }
        return pstmt.executeUpdate();
    }

    /**
     * 执行任意SQL语句
     */
    public boolean execute(String sql) throws SQLException {
        if (connection == null || connection.isClosed()) {
            connect(); // 尝试重新连接
        }
        Statement statement = connection.createStatement();
        return statement.execute(sql);
    }

    /**
     * 检查数据库连接是否有效
     */
    public boolean isConnected() {
        try {
            return connection != null && !connection.isClosed() && connection.isValid(5);
        } catch (SQLException e) {
            return false;
        }
    }

    public Connection getConnection() {
        return connection;
    }

    public static class DbConfig {
        public String host = "localhost";
        public int port = 3306;
        public String database = "test";
        public String username = "root";
        public String password = "root";
    }
}
