package com.njcn.gather.freqConverter.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.gather.freqConverter.mapper.PqFreqConverterConfigMapper;
import com.njcn.gather.freqConverter.pojo.param.PqFreqConverterParam;
import com.njcn.gather.freqConverter.pojo.po.PqFreqConverterConfig;
import com.njcn.gather.freqConverter.service.IPqFreqConverterConfigService;
import com.njcn.gather.storage.mapper.TableGenMapper;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author caozehui
 * @data 2026-04-08
 */
@Service
@AllArgsConstructor
public class PqFreqConverterConfigServiceImpl extends ServiceImpl<PqFreqConverterConfigMapper, PqFreqConverterConfig> implements IPqFreqConverterConfigService {
    private final TableGenMapper tableGenMapper;

    /**
     * 表名前缀
     */
    public static final String PQ_FREQ_CONVERTER_STATUS_TB_PREFIX = "pq_freq_converter_status_";
    public static final String PQ_DIP_DATA_TB_PREFIX = "pq_dip_data_";
    public static final String PQ_FREQ_CONVERTER_TEST_RES_TB_PREFIX = "pq_freq_converter_test_res_";

    @Override
    public Page<PqFreqConverterConfig> listPqFreqConverterConfigs(PqFreqConverterParam.QueryParam queryParam) {
        QueryWrapper wrapper = new QueryWrapper<>();
        wrapper.like(StrUtil.isNotBlank(queryParam.getName()), "name", queryParam.getName());
        wrapper.eq("state", 1);
        return this.page(new Page<>(queryParam.getPageNum(), queryParam.getPageSize()), wrapper);
    }

    @Override
    public Integer getSuffix(String converterId) {
        PqFreqConverterConfig freqConverterConfig = this.lambdaQuery().eq(PqFreqConverterConfig::getId, converterId).one();
        return freqConverterConfig.getSuffix();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addPqFreqConverterConfig(PqFreqConverterParam param) {
        // 建表
        PqFreqConverterConfig freqConverterConfig = this.lambdaQuery().orderByDesc(PqFreqConverterConfig::getSuffix)
                .last("limit 1").one();
        Integer maxSuffix = 1;
        if (ObjectUtil.isNotNull(freqConverterConfig)) {
            maxSuffix = freqConverterConfig.getSuffix() + 1;
        }

        String tableSql = "CREATE TABLE `" + PQ_FREQ_CONVERTER_STATUS_TB_PREFIX + maxSuffix + "`(" +
                "  `id` char(32) NOT NULL COMMENT '主键ID'," +
                "  `slave_address` int(11) DEFAULT NULL COMMENT '从机地址'," +
                "  `status_word1` int(11) DEFAULT NULL COMMENT '状态字1'," +
                "  `status_word1_hex` varchar(20) DEFAULT NULL COMMENT '状态字1十六进制'," +
                "  `timestamp` datetime(3) NOT NULL COMMENT '状态记录时刻（时间戳）'," +
                "   PRIMARY KEY (`id`) USING BTREE" +
                ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='变频器状态表';";
        tableGenMapper.genTable(tableSql);

        tableSql = "CREATE TABLE `" + PQ_DIP_DATA_TB_PREFIX + maxSuffix + "` (" +
                "   `id` char(32) NOT NULL COMMENT '主键ID'," +
                "   `start_time` datetime(3) NOT NULL COMMENT '起始时间戳'," +
                "   `residual_voltage` decimal(6,2) NOT NULL COMMENT '残余电压(%Ur)'," +
                "   `duration_ms` int(11) NOT NULL COMMENT '持续时间(ms)'," +
                "    PRIMARY KEY (`id`)" +
                ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='电压暂降数据表';";
        tableGenMapper.genTable(tableSql);

        tableSql = "CREATE TABLE `" + PQ_FREQ_CONVERTER_TEST_RES_TB_PREFIX + maxSuffix + "` (" +
                "   `id` char(32) NOT NULL COMMENT '主键ID'," +
                "   `residual_voltage` decimal(6,2) NOT NULL COMMENT '残余电压(%Ur)'," +
                "   `duration_ms` int(11) NOT NULL COMMENT '持续时间(ms)'," +
                "   `tolerant` tinyInt(1) NOT NULL COMMENT '0为不耐受，1为耐受，2为特征点'," +
                "    `time` datetime(3) DEFAULT NULL COMMENT '时间',"+
                "    PRIMARY KEY (`id`)" +
                ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='变频器耐受实验结果';";
        tableGenMapper.genTable(tableSql);

        PqFreqConverterConfig pqFreqConverterConfig = BeanUtil.copyProperties(param, PqFreqConverterConfig.class);
        pqFreqConverterConfig.setSuffix(maxSuffix);
        pqFreqConverterConfig.setTestStatus(0);
        pqFreqConverterConfig.setState(DataStateEnum.ENABLE.getCode());
        return this.save(pqFreqConverterConfig);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updatePqFreqConverterConfig(PqFreqConverterParam.UpdateParam param) {
        PqFreqConverterConfig pqFreqConverterConfig = BeanUtil.copyProperties(param, PqFreqConverterConfig.class);
        return this.updateById(pqFreqConverterConfig);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deletePqFreqConverterConfig(List<String> ids) {
        StringBuffer sql = new StringBuffer();
        sql.append("drop table if exists ");

        List<PqFreqConverterConfig> pqFreqConverterConfigs = this.listByIds(ids);
        for (PqFreqConverterConfig pqFreqConverterConfig : pqFreqConverterConfigs) {
            Integer suffix = pqFreqConverterConfig.getSuffix();
            sql.append(PQ_FREQ_CONVERTER_STATUS_TB_PREFIX + suffix + ",")
                    .append(PQ_DIP_DATA_TB_PREFIX + suffix + ",")
                    .append(PQ_FREQ_CONVERTER_TEST_RES_TB_PREFIX + suffix + ",");
        }

        sql.deleteCharAt(sql.length() - 1);
        // 删除表
        tableGenMapper.genTable(sql.toString());
        return this.lambdaUpdate()
                .in(CollectionUtil.isNotEmpty(ids), PqFreqConverterConfig::getId, ids)
                .set(PqFreqConverterConfig::getState, 0).update();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateTestStatus(String converterId, Integer testStatus) {
        return this.lambdaUpdate()
                .eq(PqFreqConverterConfig::getId, converterId)
                .set(PqFreqConverterConfig::getTestStatus, testStatus)
                .update();
    }
}
