package com.ruoyi.interfaces.service.impl;

import org.springframework.jdbc.core.JdbcTemplate;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.interfaces.database.DynamicDataSourceManager;
import com.ruoyi.interfaces.domain.vo.SysMetaQueryVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.interfaces.mapper.SysMetaDatasourceMapper;
import com.ruoyi.interfaces.domain.SysMetaDatasource;
import com.ruoyi.interfaces.service.ISysMetaDatasourceService;

import javax.sql.DataSource;

/**
 * 数据源管理Service业务层处理
 *
 * @author 朱得糠
 * @date 2025-08-02
 */
@Service
public class SysMetaDatasourceServiceImpl implements ISysMetaDatasourceService {
    @Autowired
    private SysMetaDatasourceMapper sysMetaDatasourceMapper;

    @Autowired
    private DynamicDataSourceManager dataSourceManager;


    /**
     * 查询数据源管理
     *
     * @param dsCode 数据源管理主键
     * @return 数据源管理
     */
    @Override
    public SysMetaDatasource selectSysMetaDatasourceByDsCode(String dsCode) {
        return sysMetaDatasourceMapper.selectSysMetaDatasourceByDsCode(dsCode);
    }

    /**
     * 查询数据源管理列表
     *
     * @param sysMetaDatasource 数据源管理
     * @return 数据源管理
     */
    @Override
    public List<SysMetaDatasource> selectSysMetaDatasourceList(SysMetaDatasource sysMetaDatasource) {
        return sysMetaDatasourceMapper.selectSysMetaDatasourceList(sysMetaDatasource);
    }

    /**
     * 新增数据源管理
     *
     * @param sysMetaDatasource 数据源管理
     * @return 结果
     */
    @Override
    public int insertSysMetaDatasource(SysMetaDatasource sysMetaDatasource) {
        sysMetaDatasource.setDsCode(IdUtils.fastUUID());
        return sysMetaDatasourceMapper.insertSysMetaDatasource(sysMetaDatasource);
    }

    /**
     * 修改数据源管理
     *
     * @param sysMetaDatasource 数据源管理
     * @return 结果
     */
    @Override
    public int updateSysMetaDatasource(SysMetaDatasource sysMetaDatasource) {
        return sysMetaDatasourceMapper.updateSysMetaDatasource(sysMetaDatasource);
    }

    /**
     * 批量删除数据源管理
     *
     * @param dsCodes 需要删除的数据源管理主键
     * @return 结果
     */
    @Override
    public int deleteSysMetaDatasourceByDsCodes(String[] dsCodes) {
        return sysMetaDatasourceMapper.deleteSysMetaDatasourceByDsCodes(dsCodes);
    }

    /**
     * 删除数据源管理信息
     *
     * @param dsCode 数据源管理主键
     * @return 结果
     */
    @Override
    public int deleteSysMetaDatasourceByDsCode(String dsCode) {
        return sysMetaDatasourceMapper.deleteSysMetaDatasourceByDsCode(dsCode);
    }

    /**
     * @param dsCode
     * @return 1 = 成功 ； 0 = 超时
     */
    @Override
    public Integer testConnection(String dsCode) {
        DataSource sysDataSource = dataSourceManager.getSysDataSource(sysMetaDatasourceMapper.selectSysMetaDatasourceByDsCode(dsCode));

        try (Connection conn = sysDataSource.getConnection()) {
            boolean valid = conn.isValid(5);// 5秒超时
            if (valid) return 1;
            return 0;
        } catch (SQLException e) {
            throw new RuntimeException("数据库连接测试失败: " + e.getMessage(), e);
        }
    }

    @Override
    public List<String> getTableNames(String dsCode) {

        List<String> tables = new ArrayList<>();
        DataSource dataSource = dataSourceManager.getSysDataSource(sysMetaDatasourceMapper.selectSysMetaDatasourceByDsCode(dsCode));
        try (Connection conn = dataSource.getConnection()) {
            DatabaseMetaData metaData = conn.getMetaData();
            ResultSet rs = metaData.getTables(null, null, "%", new String[]{"TABLE"});

            while (rs.next()) {
                tables.add(rs.getString("TABLE_NAME"));
            }
        } catch (SQLException e) {
            throw new RuntimeException("获取表名失败: " + e.getMessage(), e);
        }
        return tables;
    }

    /**
     * 查询指定表的数据
     */
    @Override
    public List<Map<String, Object>> queryTableData(SysMetaQueryVo queryVo) {

        SysMetaDatasource sysMetaDatasource = sysMetaDatasourceMapper.selectSysMetaDatasourceByDsCode(queryVo.getDsCode());
        DataSource dataSource = dataSourceManager.getSysDataSource(sysMetaDatasource);

        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

        String sql = DynamicDataSourceManager.buildPaginationSql(queryVo.getSql(), 1, 20, sysMetaDatasource.getDsType());


        return jdbcTemplate.query(sql, (rs, rowNum) -> {
            Map<String, Object> row = new HashMap<>();
            int columnCount = rs.getMetaData().getColumnCount();

            for (int i = 1; i <= columnCount; i++) {
                String columnName = rs.getMetaData().getColumnName(i);
                Object value = rs.getObject(i);
                row.put(columnName, value);
            }
            return row;
        });
    }
}
