package org.dromara.app.mapper;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.dromara.app.domain.AppDevice;
import org.dromara.app.domain.bo.AppDeviceBo;
import org.dromara.app.domain.vo.AppDeviceVo;
import org.dromara.app.domain.vo.DashboardStatsVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;

import java.util.List;

/**
 * 设备信息
Mapper接口
 *
 * @author Lion Li
 * @date 2026-04-25
 */
public interface AppDeviceMapper extends BaseMapperPlus<AppDevice, AppDeviceVo> {

    @Select("""
        <script>
        select
            d.device_no,
            d.user_id,
            d.device_name,
            d.device_init_name,
            d.device_img,
            d.qrcode,
            d.status,
            d.work_status,
            d.power_level,
            d.power_level_updatatime,
            d.wifi_name,
            d.wifi_password,
            d.device_em,
            d.device_sn,
            d.fw_ver,
            d.mac_address,
            d.expiration_time,
            u.nick_name
        from app_device d
        left join sys_user u on u.user_id = d.user_id
        <where>
            <if test="bo.deviceNo != null and bo.deviceNo != ''">
                and d.device_no = #{bo.deviceNo}
            </if>
            <if test="bo.userId != null">
                and d.user_id = #{bo.userId}
            </if>
            <if test="bo.deviceName != null and bo.deviceName != ''">
                and d.device_name like concat('%', #{bo.deviceName}, '%')
            </if>
            <if test="bo.deviceInitName != null and bo.deviceInitName != ''">
                and d.device_init_name = #{bo.deviceInitName}
            </if>
            <if test="bo.deviceImg != null and bo.deviceImg != ''">
                and d.device_img = #{bo.deviceImg}
            </if>
            <if test="bo.qrcode != null and bo.qrcode != ''">
                and d.qrcode = #{bo.qrcode}
            </if>
            <if test="bo.status != null and bo.status != ''">
                and d.status = #{bo.status}
            </if>
            <if test="bo.powerLevel != null and bo.powerLevel != ''">
                and d.power_level = #{bo.powerLevel}
            </if>
            <if test="bo.powerLevelUpdatatime != null">
                and d.power_level_updatatime = #{bo.powerLevelUpdatatime}
            </if>
            <if test="bo.wifiName != null and bo.wifiName != ''">
                and d.wifi_name like concat('%', #{bo.wifiName}, '%')
            </if>
            <if test="bo.wifiPassword != null and bo.wifiPassword != ''">
                and d.wifi_password = #{bo.wifiPassword}
            </if>
            <if test="bo.deviceEm != null and bo.deviceEm != ''">
                and d.device_em = #{bo.deviceEm}
            </if>
            <if test="bo.deviceSn != null and bo.deviceSn != ''">
                and d.device_sn = #{bo.deviceSn}
            </if>
            <if test="bo.fwVer != null and bo.fwVer != ''">
                and d.fw_ver = #{bo.fwVer}
            </if>
            <if test="bo.macAddress != null and bo.macAddress != ''">
                and d.mac_address = #{bo.macAddress}
            </if>
            <if test="bo.expirationTime != null">
                and d.expiration_time = #{bo.expirationTime}
            </if>
        </where>
        order by d.device_no asc
        </script>
        """)
    Page<AppDeviceVo> selectDeviceVoPage(Page<AppDeviceVo> page, @Param("bo") AppDeviceBo bo);

    @Select("""
        <script>
        select
            d.device_no,
            d.user_id,
            d.device_name,
            d.device_init_name,
            d.device_img,
            d.qrcode,
            d.status,
            d.work_status,
            d.power_level,
            d.power_level_updatatime,
            d.wifi_name,
            d.wifi_password,
            d.device_em,
            d.device_sn,
            d.fw_ver,
            d.mac_address,
            d.expiration_time,
            u.nick_name
        from app_device d
        left join sys_user u on u.user_id = d.user_id
        <where>
            <if test="bo.deviceNo != null and bo.deviceNo != ''">
                and d.device_no = #{bo.deviceNo}
            </if>
            <if test="bo.userId != null">
                and d.user_id = #{bo.userId}
            </if>
            <if test="bo.deviceName != null and bo.deviceName != ''">
                and d.device_name like concat('%', #{bo.deviceName}, '%')
            </if>
            <if test="bo.deviceInitName != null and bo.deviceInitName != ''">
                and d.device_init_name = #{bo.deviceInitName}
            </if>
            <if test="bo.deviceImg != null and bo.deviceImg != ''">
                and d.device_img = #{bo.deviceImg}
            </if>
            <if test="bo.qrcode != null and bo.qrcode != ''">
                and d.qrcode = #{bo.qrcode}
            </if>
            <if test="bo.status != null and bo.status != ''">
                and d.status = #{bo.status}
            </if>
            <if test="bo.powerLevel != null and bo.powerLevel != ''">
                and d.power_level = #{bo.powerLevel}
            </if>
            <if test="bo.powerLevelUpdatatime != null">
                and d.power_level_updatatime = #{bo.powerLevelUpdatatime}
            </if>
            <if test="bo.wifiName != null and bo.wifiName != ''">
                and d.wifi_name like concat('%', #{bo.wifiName}, '%')
            </if>
            <if test="bo.wifiPassword != null and bo.wifiPassword != ''">
                and d.wifi_password = #{bo.wifiPassword}
            </if>
            <if test="bo.deviceEm != null and bo.deviceEm != ''">
                and d.device_em = #{bo.deviceEm}
            </if>
            <if test="bo.deviceSn != null and bo.deviceSn != ''">
                and d.device_sn = #{bo.deviceSn}
            </if>
            <if test="bo.fwVer != null and bo.fwVer != ''">
                and d.fw_ver = #{bo.fwVer}
            </if>
            <if test="bo.macAddress != null and bo.macAddress != ''">
                and d.mac_address = #{bo.macAddress}
            </if>
            <if test="bo.expirationTime != null">
                and d.expiration_time = #{bo.expirationTime}
            </if>
        </where>
        order by d.device_no asc
        </script>
        """)
    List<AppDeviceVo> selectDeviceVoList(@Param("bo") AppDeviceBo bo);

    @Update("""
            <script>
            update app_device
            <set>
                user_id = #{userId},
                <if test="deviceName != null and deviceName != ''">
                    device_name = #{deviceName},
                </if>
                <if test="status != null and status != ''">
                    status = #{status},
                </if>
                <if test="workStatus != null and workStatus != ''">
                    work_status = #{workStatus},
                </if>
                <if test="wifiName != null and wifiName != ''">
                    wifi_name = #{wifiName},
                </if>
                <if test="wifiPassword != null and wifiPassword != ''">
                wifi_password = #{wifiPassword},
                </if> 
            </set>
            where device_no = #{deviceNo}
              and (user_id is null or user_id = #{userId})
            </script>
            """)
    int bindIfAvailable(@Param("deviceNo") String deviceNo,
                        @Param("userId") Long userId,
                        @Param("deviceName") String deviceName,
                        @Param("status") String status,
                        @Param("workStatus") String workStatus,
                        @Param("wifiName") String wifiName,
                        @Param("wifiPassword") String wifiPassword);

    @Update("""
        update app_device
        set work_status = #{workStatus}
        where device_no = #{deviceNo}
          and user_id = #{userId}
        """)
    int updateWorkStatusByUser(@Param("deviceNo") String deviceNo,
                               @Param("userId") Long userId,
                               @Param("workStatus") String workStatus);

    @Select("""
        select *
       from app_device
        where lower(mac_address) = lower(#{macAddress})
        """)
    AppDevice selectByMac(@Param("macAddress") String macAddress);

    @Select("""
        select *
        from app_device
        where device_init_name = #{deviceInitName}
        """)
    AppDevice selectByDeviceInitName(@Param("deviceInitName") String deviceInitName);

    /**
     * 仪表盘统计 — 单条 SQL 条件聚合，一次查询返回全部 8 个指标。
     */
    @Select("""
        select
            count(*)                                                         as totalDevices,
            sum(case when status      = '1' then 1 else 0 end)               as onlineDevices,
            sum(case when status      = '2' then 1 else 0 end)               as standbyDevices,
            sum(case when status      = '0' then 1 else 0 end)               as offlineDevices,
            sum(case when status      = '3' then 1 else 0 end)               as faultDevices,
            sum(case when work_status = '1' then 1 else 0 end)               as workingDevices,
            sum(case when work_status = '0' then 1 else 0 end)               as idleDevices,
            sum(case when user_id is null     then 1 else 0 end)             as unboundDevices
        from app_device
        """)
    DashboardStatsVo selectDashboardStats();

}
