package cn.iocoder.yudao.module.pms.dal.mysql;

import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.module.pms.controller.admin.vo.DeviceTdVO;
import cn.iocoder.yudao.module.pms.controller.admin.vo.DeviceVO;
import cn.iocoder.yudao.module.pms.dal.dataobject.TDDeviceDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotZHBD.TDLogDO;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import java.sql.Timestamp;
import java.util.List;

/**
 * @author yc
 * @version 1.0
 * @className TDDeviceMapper
 * @description
 */
@Mapper
public interface TDDeviceMapper extends BaseMapperX<TDDeviceDO> {
    @Select("SELECT * FROM iot_log.device_${deviceName} WHERE ts between #{ts} and #{ts1}")
    @DS("tdengine")
    @TenantIgnore
    List<DeviceVO> selectBySpan(@Param("deviceName") String tableName, @Param("ts") Timestamp ts,@Param("ts1") Timestamp ts1);


    @Select("SELECT * FROM iot_log.device_${deviceName}  ORDER BY read_time  DESC LIMIT 1;")
    @DS("tdengine")
    @TenantIgnore
    List<DeviceVO> selectNew(@Param("deviceName") String tableName);


    @Select("SELECT LAST(ts) as ts FROM iot_log.device_${deviceName} where identity not in ('lng','lat','today_distance','distance','todayoil','totaloil','online','oil1','oil2','oil3'," +
            "'oil4','vehicle_name') ")
    @DS("tdengine")
    @TenantIgnore
    List<DeviceVO> selectLastTime(@Param("deviceName") String tableName);

//    @Select("SELECT identity, LAST(log_value) as logValue FROM iot_log.device_${deviceName} where identity in ${params} group by identity")
    @Select({
            "<script>",
            "SELECT",
            "  identity,",
            "  LAST(log_value) AS logValue ",

            "FROM iot_log.device_log ",
            "WHERE serial_number = '${deviceName}' and identity IN ",
            "<foreach collection='params' item='value' open='(' close=')' separator=','>",
            "   #{value}",
            "</foreach>",
            "group BY identity",
            "</script>"
    })
    @DS("tdengine")
    @TenantIgnore
    List<DeviceVO> selectLastParam(@Param("deviceName") String tableName, @Param("params") List<String> params);

    @Select({"SELECT COUNT(*) FROM information_schema.ins_tables WHERE table_name = 'device_${deviceName}';"})
    @DS("tdengine")
    @TenantIgnore
    Integer tableIfExist(@Param("deviceName") String tableName);

    @Select("SELECT * FROM iot_log.device_${deviceName} WHERE ts = #{ts}")
    @DS("tdengine")
    @TenantIgnore
    List<DeviceVO> selectByTs(@Param("deviceName") String tableName, @Param("ts") Timestamp ts);

    @Select("SELECT\n" +
            "  FIRST(log_value  ) AS earliest_data,\n" +
            "  LAST(log_value ) AS latest_data\n" +
            "FROM iot_log.device_${deviceName} \n" +
            "WHERE\n" +
            "  ts BETWEEN #{ts}" +
            "  and #{ts1}"+
            "  and identity = #{colName}\n" +
            "  and log_value != 0.0"+
            "  AND _c0 IS NOT NULL")
    @DS("tdengine")
    @TenantIgnore
    DeviceVO getYesInfo(@Param("deviceName") String tableName, @Param("colName") String colName, @Param("ts") Timestamp ts,@Param("ts1")Timestamp ts1);

    // 7. 批量查询DeviceVO
    /*@Select("<script>" +
            "<foreach collection='queries' item='item' index='index' separator='UNION ALL'>" +
            "SELECT" +
            "  #{item.deviceName1} AS device_name," + // 关联入参表名
            "  #{item.colName} AS col_name," +     // 关联入参列名
            "  FIRST(log_value) AS earliest_data," +
            "  LAST(log_value) AS latest_data" +
            " FROM iot_log.device_${item.deviceName}" + // 表名动态拼接（注意SQL注入风险）
            " WHERE" +
            "  ts BETWEEN #{item.ts} AND #{item.ts1}" +
            "  AND identity = #{item.colName}" +
            "  AND log_value != 0.0" +
            "  AND _c0 IS NOT NULL" +
            "</foreach>" +
            "</script>")*/
    @Select("<script>" +
            "<foreach collection='queries' item='item' index='index' separator='UNION ALL'>" +
            "SELECT" +
            "  CONCAT('', #{item.deviceName1}) AS device_name," + // 强制拼接空字符串，确保单引号
            "  CONCAT('', #{item.colName}) AS col_name," +         // 同理，确保 col_name 带单引号
            "  FIRST(log_value) AS earliest_data," +
            "  LAST(log_value) AS latest_data" +
            " FROM iot_log.device_${item.deviceName}" + // 确认表名大小写与实际一致（必须完全匹配）
            " WHERE" +
            "  ts BETWEEN #{item.ts} AND #{item.ts1}" +
            "  AND log_value != 0.0" +
            "  AND _c0 IS NOT NULL" +
            "  <if test='item.colName != null and item.colName != \"\"'>" + // 增加空字符串判断
            "    AND identity = #{item.colName}" +
            "  </if>" +
            "  <if test='item.colName == null or item.colName == \"\"'>" + // 空字符串也按 IS NULL 处理
            "    AND identity IS NULL" +
            "  </if>" +
            "</foreach>" +
            "</script>")
    @DS("tdengine")
    @TenantIgnore
    List<DeviceTdVO> batchGetYesInfo(@Param("queries") List<DeviceTdVO> queries);


    @Select("SELECT   _WSTART AS ts, AVG(CAST(log_value AS FLOAT)) as log_value   FROM iot_log.device_${deviceName} " +
            "WHERE ts between #{start} and #{end} and identity = #{identifier}  INTERVAL(1m) " )
    @DS("tdengine")
    @TenantIgnore
    @InterceptorIgnore(tenantLine = "true")
    List<DeviceVO> selectAllBtTimeAndIdentifier(@Param("deviceName") String tableName, @Param("identifier") String identifier,@Param("start") Timestamp start,@Param("end") Timestamp end);

    @Select("SELECT ts, CAST(log_value AS FLOAT) as log_value   FROM iot_log.device_${deviceName} " +
            "WHERE ts between #{start} and #{end} and identity = #{identifier} " )
    @DS("tdengine")
    @TenantIgnore
    @InterceptorIgnore(tenantLine = "true")
    List<DeviceVO> selectAllBtTimeAndIdentifierNoInterval(@Param("deviceName") String tableName, @Param("identifier") String identifier,@Param("start") Timestamp start,@Param("end") Timestamp end);

    @Select("SELECT   ts, CAST(log_value AS FLOAT) as log_value,identity   FROM iot_log.device_${deviceName} " +
            "WHERE ts between #{start} and #{end} and identity not in ('online','todayoil','totaloil','distance','vehicle_name','oil1','lng','lat','today_distance','oil4','oil3','oil2')  ORDER BY ts DESC LIMIT #{pageSize} " )
    @DS("tdengine")
    @TenantIgnore
    @InterceptorIgnore(tenantLine = "true")
    List<DeviceVO> selectAllBtTime(@Param("deviceName") String tableName,@Param("start") Timestamp start,@Param("end") Timestamp end, @Param("pageSize") Integer pageSize);

    @Select("SELECT   ts, CAST(log_value AS FLOAT) as log_value,identity   FROM iot_log.device_${deviceName} " +
            "WHERE ts between #{start} and #{end} and identity = #{identifier} and identity not in ('online','todayoil','totaloil','distance','vehicle_name','oil1','lng','lat','today_distance','oil4','oil3','oil2') ORDER BY ts DESC LIMIT #{pageSize} " )
    @DS("tdengine")
    @TenantIgnore
    @InterceptorIgnore(tenantLine = "true")
    List<DeviceVO> selectAllBtTimeAndidentifierAll(@Param("deviceName") String tableName,@Param("identifier") String identifier,@Param("start") Timestamp start,@Param("end") Timestamp end, @Param("pageSize") Integer pageSize);


    @InterceptorIgnore(tenantLine = "true")
    @DS("tdengine")
    @Insert({
            "<script>",
            "INSERT INTO iot_log.device_${data.tableName} USING iot_log.device_log\n" +
                    "        TAGS (${data.serialNumber}) VALUES ",
            "<foreach collection='data.list' item='device' separator=','>",
            "(now,"+
            " #{device.logValue},"+
            "#{device.isMonitor},"+
            "#{device.logType},"+
            "#{device.identity},"+
            "#{device.mode},"+
            "now,"+
            "#{device.remark},"+
            "#{device.batchId})"+
            "</foreach>",
            "</script>"
    })
    int batchInsert(@Param("data") TDLogDO data);

    @Select("SELECT count(*) FROM iot_log.device_${deviceName} " +
            "WHERE ts between #{start} and #{end} and identity = #{identifier} and log_value between #{min} and #{max}" )
    @DS("tdengine")
    @TenantIgnore
    @InterceptorIgnore(tenantLine = "true")
    Integer selectRangeCount(@Param("deviceName") String tableName, @Param("identifier") String identifier,@Param("start") Timestamp start,@Param("end") Timestamp end,
                                    @Param("max") String max,@Param("min") String min);
}
