package com.sw.mes.agv.dao;

import com.sw.mes.agv.entity.MonitorEquipmentRecharge;
import com.sw.mes.core.base.BaseDao;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;

public interface MonitorEquipmentRechargeDAO extends BaseDao<MonitorEquipmentRecharge, Long> {

    List<MonitorEquipmentRecharge> findByName(String deviceNo);

    List<MonitorEquipmentRecharge> findBySlingStateNotOrderByPreSlingTimeDesc(String state);

    @Modifying
    @Transactional
    @Query(value = "UPDATE monitor_equipment_recharge SET equipment_state =?2 WHERE name=?1", nativeQuery = true)
    void updateMonitor(String deviceNo, String state);

    @Query(value = "SELECT * FROM monitor_equipment_recharge " +
            "WHERE sling_state !=?2 AND name IN(?1) ORDER BY pre_sling_time ASC ", nativeQuery = true)
    List<MonitorEquipmentRecharge> findByEquipmentsAndSlingStateNotEqual(List<String> equipmentList, String state);

    @Query(value = "SELECT * FROM monitor_equipment_recharge " +
            "WHERE sling_state =?2 AND name IN(?1) ORDER BY pre_sling_time ASC ", nativeQuery = true)
    List<MonitorEquipmentRecharge> findByEquipmentsAndSlingState(List<String> equipmentList, String state);

    @Query(value = "SELECT * FROM monitor_equipment_recharge " +
            "WHERE store_code IS NULL AND sling_state !=?2 AND name IN(?1) ORDER BY pre_sling_time ASC ", nativeQuery = true)
    List<MonitorEquipmentRecharge> findByEquipmentsAndSlingStateNotEqualAndStoreCodeIsNull(List<String> equipmentList, String state);

    @Query(value = "SELECT * FROM monitor_equipment_recharge " +
            "WHERE store_code IS NOT NULL AND sling_state !=?2 AND name IN(?1) ORDER BY pre_sling_time ASC ", nativeQuery = true)
    List<MonitorEquipmentRecharge> findByEquipmentsAndSlingStateNotEqualAndStoreCodeIsNotNull(List<String> equipmentList, String state);

    @Query(value = "SELECT * FROM monitor_equipment_recharge " +
            "WHERE state=?1 AND area=?2 ORDER BY pre_sling_time ASC ", nativeQuery = true)
    List<MonitorEquipmentRecharge> findByStateAndArea(Integer state, String area);

    @Query(value = "SELECT * FROM monitor_equipment_recharge WHERE state=?1 ORDER BY pre_sling_time ASC ", nativeQuery = true)
    List<MonitorEquipmentRecharge> findByState(Integer state);

    @Modifying
    @Transactional
    @Query(value = "DELETE FROM monitor_equipment_recharge WHERE pre_sling_time<?1 ", nativeQuery = true)
    void deleteByPreSlingTime(Date date);

    @Modifying
    @Transactional
    @Query(value = "DELETE FROM monitor_equipment_recharge WHERE name=?1 ", nativeQuery = true)
    void deleteByName(String deviceNo);

    @Modifying
    @Transactional
    @Query(value = "UPDATE monitor_equipment_recharge SET recharge_start_time=?1 WHERE name=?2 ", nativeQuery = true)
    void updateRechargeStartTime(Date rechargeStartTime, String deviceNo);

    @Modifying
    @Transactional
    @Query(value = "UPDATE monitor_equipment_recharge SET recharge_end_time=?1 WHERE name=?2 ", nativeQuery = true)
    void updateRechargeEndTime(Date rechargeEndTime, String deviceNo);

    @Query(value = "SELECT * FROM monitor_equipment_recharge WHERE recharge_end_time IS NULL AND prepare_num<recharge_num" +
            " ORDER BY pre_sling_time ASC ", nativeQuery = true)
    List<MonitorEquipmentRecharge> findRechargeEndTimeIsNull();

    @Query(value = "SELECT r.* FROM (SELECT * FROM monitor_equipment_recharge WHERE recharge_end_time IS NULL " +
            " AND prepare_num<recharge_num ) r " +
            " JOIN (SELECT binding_equipment FROM zhxx_workstation_configuration WHERE ip_address=?1) c " +
            " ON FIND_IN_SET(r.name, c.binding_equipment) ORDER BY r.pre_sling_time ASC  ", nativeQuery = true)
    List<MonitorEquipmentRecharge> findRechargeEndTimeIsNull(String userIp);

    @Query(value = "SELECT r.* FROM (SELECT * FROM monitor_equipment_recharge WHERE pare_weight<recharge_weight OR recharge_weight=0) r " +
            " JOIN (SELECT binding_equipment FROM zhxx_workstation_configuration WHERE ip_address=?1) c " +
            " ON FIND_IN_SET(r.name, c.binding_equipment) ORDER BY r.pre_sling_time ASC  ", nativeQuery = true)
    List<MonitorEquipmentRecharge> findRechargeChangeWeight(String userIp);

    @Query(value = "SELECT * FROM monitor_equipment_recharge WHERE pare_weight<recharge_weight OR recharge_weight=0 " +
            "ORDER BY pre_sling_time ASC ", nativeQuery = true)
    List<MonitorEquipmentRecharge> findRechargeChangeWeight();

    @Query(value = "SELECT r.* FROM (SELECT * FROM monitor_equipment_recharge WHERE pare_weight<recharge_weight " +
            " AND IF(pare_num=4, prepare_num>=3, 1=1)) r " +
            " JOIN (SELECT binding_equipment FROM zhxx_workstation_configuration WHERE ip_address=?1) c " +
            " ON FIND_IN_SET(r.name, c.binding_equipment) ORDER BY r.pre_sling_time ASC  ", nativeQuery = true)
    List<MonitorEquipmentRecharge> findRechargeCall(String userIp);

    @Query(value = "SELECT r.* FROM (SELECT * FROM monitor_equipment_recharge WHERE pare_weight<recharge_weight " +
            "AND `name` =?2" +
            " AND IF(pare_num=4, prepare_num>=3, 1=1)) r " +
            " JOIN (SELECT binding_equipment FROM zhxx_workstation_configuration WHERE ip_address=?1) c " +
            " ON FIND_IN_SET(r.name, c.binding_equipment) ORDER BY r.pre_sling_time ASC  ", nativeQuery = true)
    List<MonitorEquipmentRecharge> findRechargeCall(String userIp, String deviceCode);

    @Query(value = "SELECT * FROM monitor_equipment_recharge WHERE pare_weight<recharge_weight " +
            " AND IF(pare_num=4, prepare_num>=3, 1=1) " +
            " ORDER BY pre_sling_time ASC ", nativeQuery = true)
    List<MonitorEquipmentRecharge> findRechargeCall();

    @Query(value = "SELECT * FROM monitor_equipment_recharge WHERE pare_weight<recharge_weight " +
            "AND `name` =?1" +
            " AND IF(pare_num=4, prepare_num>=3, 1=1) " +
            " ORDER BY pre_sling_time ASC ", nativeQuery = true)
    List<MonitorEquipmentRecharge> findRechargeCallBydeviceCode(String deviceCode);

//    @Query(value = "SELECT * FROM `monitor_equipment_recharge` WHERE ((`init_weight` = 0) AND " +
//            "(CASE `recharge_type` WHEN '初始复投' THEN (timestampdiff(MINUTE,`pre_sling_time`, now()) <= 60) " +
//            "WHEN '复投' THEN (timestampdiff(MINUTE,`pre_sling_time`,now()) <= 80) ELSE FALSE END)) ", nativeQuery = true)

    @Query(value = "SELECT * FROM monitor_recharge_init_weight_view ", nativeQuery = true)
    List<MonitorEquipmentRecharge> findByInitWeightAndPreSlingTime();

    @Query(value = "SELECT r.`name` AS name, r.pre_sling_time AS preSlingTime, r.recharge_type AS rechargeType " +
            " FROM (SELECT * FROM monitor_equipment_recharge WHERE pad_send=1) r " +
            " JOIN (SELECT binding_equipment FROM zhxx_workstation_configuration WHERE ip_address=?1) c " +
            " ON FIND_IN_SET(r.name, c.binding_equipment) ORDER BY r.pre_sling_time ASC  ", nativeQuery = true)
    List<Map<String, Object>> findPadSend(String userIp);

    @Query(value = "SELECT r.`name` AS name, r.pre_sling_time AS preSlingTime, r.recharge_type AS rechargeType " +
            " FROM (SELECT * FROM monitor_equipment_recharge WHERE pad_send=1 AND `name` LIKE concat(?2, '%')) r " +
            " JOIN (SELECT binding_equipment FROM zhxx_workstation_configuration WHERE ip_address=?1) c " +
            " ON FIND_IN_SET(r.name, c.binding_equipment) ORDER BY r.pre_sling_time ASC ", nativeQuery = true)
    List<Map<String, Object>> findPadSend(String userIp, String deviceCode);

//    @Query(value = "SELECT new com.sw.mes.monitor.entity.RechargeInfoDto(name, preSlingTime, rechargeType)" +
//            " FROM MonitorEquipmentRecharge WHERE padSend=1 " +
//            " ORDER BY preSlingTime ASC ")
//    List<RechargeInfoDto> findPadSend();
//
//    @Query(value = "SELECT new com.sw.mes.monitor.entity.RechargeInfoDto(name, preSlingTime, rechargeType) " +
//            "FROM MonitorEquipmentRecharge WHERE padSend=1 AND name LIKE concat(?1, '%') " +
//            " ORDER BY preSlingTime ASC ")
//    List<RechargeInfoDto> findPadSendByName(String deviceCode);

    @Query(value = "SELECT r.* FROM (SELECT * FROM monitor_equipment_recharge WHERE mix_time IS NOT NULL AND pare_weight<recharge_weight " +
            " AND IF(pare_num=4, prepare_num>=3, 1=1)) r " +
            " JOIN (SELECT binding_equipment FROM zhxx_workstation_configuration WHERE ip_address=?1) c " +
            " ON FIND_IN_SET(r.name, c.binding_equipment) ORDER BY r.pre_sling_time ASC  ", nativeQuery = true)
    List<MonitorEquipmentRecharge> findRechargeInfoByMixTime(String userIp);

    @Query(value = "SELECT r.* FROM (SELECT * FROM monitor_equipment_recharge WHERE mix_time IS NOT NULL AND pare_weight<recharge_weight " +
            "AND `name` =?2" +
            " AND IF(pare_num=4, prepare_num>=3, 1=1)) r " +
            " JOIN (SELECT binding_equipment FROM zhxx_workstation_configuration WHERE ip_address=?1) c " +
            " ON FIND_IN_SET(r.name, c.binding_equipment) ORDER BY r.pre_sling_time ASC  ", nativeQuery = true)
    List<MonitorEquipmentRecharge> findRechargeInfoByMixTime(String userIp, String deviceCode);

    @Query(value = "SELECT * FROM monitor_equipment_recharge WHERE mix_time IS NOT NULL AND pare_weight<recharge_weight " +
            " AND IF(pare_num=4, prepare_num>=3, 1=1) " +
            " ORDER BY pre_sling_time ASC ", nativeQuery = true)
    List<MonitorEquipmentRecharge> findRechargeInfoByMixTime();

    @Query(value = "SELECT * FROM monitor_equipment_recharge WHERE mix_time IS NOT NULL AND pare_weight<recharge_weight " +
            "AND `name` =?1" +
            " AND IF(pare_num=4, prepare_num>=3, 1=1) " +
            " ORDER BY pre_sling_time ASC ", nativeQuery = true)
    List<MonitorEquipmentRecharge> findRechargeInfoByMixTimeAndDeviceNo(String deviceCode);

}