package com.willalp.control.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.willalp.common.exception.base.BaseException;
import com.willalp.common.utils.DateUtils;
import com.willalp.common.utils.SecurityUtils;
import com.willalp.common.utils.StringUtils;
import com.willalp.control.domain.HsControlDeviceInfo;
import com.willalp.control.domain.HsControlLog;
import com.willalp.control.domain.HsControlUsenoConfig;
import com.willalp.control.domain.vo.OpenOrCloseVo;
import com.willalp.control.mapper.HsControlDeviceInfoMapper;
import com.willalp.control.service.IHsControlDeviceInfoService;
import com.willalp.control.service.IHsControlLogService;
import com.willalp.control.service.IHsControlTimingService;
import com.willalp.control.service.IHsControlUsenoConfigService;
import com.willalp.device.domain.Device;
import com.willalp.device.mapper.DeviceMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 控制设备状态信息Service业务层处理
 *
 * @author willalp
 * @date 2022-02-16
 */
@Transactional(rollbackFor = Exception.class)
@Service
public class HsControlDeviceInfoServiceImpl extends ServiceImpl<HsControlDeviceInfoMapper, HsControlDeviceInfo> implements IHsControlDeviceInfoService {
    private static final Logger log = LoggerFactory.getLogger(HsControlDeviceInfoServiceImpl.class);

    @Resource
    private HsControlDeviceInfoMapper deviceInfoMapper;

    @Resource
    private IHsControlTimingService controlTimingService;

    @Resource
    private IHsControlUsenoConfigService configService;

    @Resource
    private DeviceMapper deviceMapper;

    @Resource
    private IHsControlLogService logService;

    /**
     * 查询控制设备状态信息列表
     *
     * @param hsControlDeviceInfo 控制设备状态信息
     * @return 控制设备状态信息
     */
    @Override
    public List<HsControlDeviceInfo> selectHsControlDeviceInfoList(HsControlDeviceInfo hsControlDeviceInfo) {
        return deviceInfoMapper.selectHsControlDeviceInfoList(hsControlDeviceInfo);
    }

    @Override
    public List<HsControlDeviceInfo> appSelectHsControlDeviceInfoList(Long userId) {
        QueryWrapper<Device> qw1 = new QueryWrapper<>();
        qw1.like("device_use_id", userId);
        List<Device> devices = deviceMapper.selectList(qw1);
        if (0 == devices.size()) {
            throw new BaseException("请绑定一台您的设备");
        }
        List<HsControlDeviceInfo> hsControlDeviceInfos = new ArrayList<>();
        devices.forEach((d) -> {
            QueryWrapper<HsControlDeviceInfo> qw2 = new QueryWrapper<>();
            qw2.eq("device_id", d.getDeviceId());
            hsControlDeviceInfos.addAll(deviceInfoMapper.selectList(qw2));
        });
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        hsControlDeviceInfos.sort((a1, a2) -> {
            try {
                return df.parse(sdf.format(a2.getCreateTime())).compareTo(df.parse(sdf.format(a1.getCreateTime())));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return 1;
        });
        return hsControlDeviceInfos;
    }

    @Override
    public int addDeviceInfo(HsControlDeviceInfo deviceInfo) {
        String deviceName = deviceInfo.getDeviceName();
        String deviceUseNo = deviceInfo.getDeviceUseNo();
        if (StringUtils.isBlank(deviceName)) {
            throw new BaseException("设备名称不能为空");
        }
        if (StringUtils.isBlank(deviceUseNo)) {
            throw new BaseException("执行口ID不能为空");
        }
        HsControlDeviceInfo useNo = this.baseMapper.selectOne(
                new QueryWrapper<HsControlDeviceInfo>()
                        .eq("device_use_no", deviceUseNo));
        if (ObjectUtil.isNotNull(useNo)) {
            throw new BaseException("该执行口已被使用，无法再次添加");
        }
        HsControlUsenoConfig byId = configService.getById(deviceUseNo);
        if (ObjectUtil.isNull(byId)) {
            throw new BaseException("没有改执行口信息");
        }
        String deviceId = byId.getDeviceId();
        if (StringUtils.isBlank(deviceId)) {
            throw new BaseException("该执行口未绑定设备");
        }
        deviceInfo.setDeviceId(deviceId);
        deviceInfo.setDosage("0");
        deviceInfo.setStatTime((long) 0);
        deviceInfo.setDosagePct(0);
        deviceInfo.setDosageUnit("小时");
        deviceInfo.setUserId(SecurityUtils.getUserId());
        deviceInfo.setCreateBy(SecurityUtils.getUsername());
        deviceInfo.setCreateTime(DateUtils.getNowDate());
        return this.baseMapper.insert(deviceInfo);
    }

    @Override
    public void openOrCloseUpdateDeviceInfo(OpenOrCloseVo openOrCloseVo) {
        HsControlDeviceInfo deviceInfo = deviceInfoMapper.selectById(openOrCloseVo.getDeviceInfoId());
        int isOpenOrClose = openOrCloseVo.getIsOpenOrClose();
        String useNoId = openOrCloseVo.getUseNoId();
        setDeviceInfoStatus(deviceInfo, isOpenOrClose, useNoId);
    }

    @Override
    public void timingOpenOrCloseUpdateDeviceInfo(Long useNoId, int status) {
        HsControlDeviceInfo deviceInfo = this.baseMapper.selectOne(
                new QueryWrapper<HsControlDeviceInfo>()
                        .eq("device_use_no", useNoId));
        deviceInfo.setRunningStatus(status);
        setDeviceInfoStatus(deviceInfo, status, String.valueOf(useNoId));
    }

    private void setDeviceInfoStatus(HsControlDeviceInfo deviceInfo, int isOpenOrClose, String useNoId) {
        if (isOpenOrClose == 0) {
            deviceInfo.setRunningStatus(isOpenOrClose);
            deviceInfo.setDosagePct(isOpenOrClose);
            deviceInfo.setLastCloseTime(new Date());

        } else {
            deviceInfo.setRunningStatus(isOpenOrClose);
            deviceInfo.setDosagePct(100);
            deviceInfo.setLastOpenTime(new Date());
        }
        HsControlLog controlLog = null;
        if (null != useNoId) {
            controlLog = new HsControlLog();
            controlLog.setUseNoId(useNoId);
            String text = isOpenOrClose == 0 ? "关闭" : "打开";
            controlLog.setUseDescribe(text);
            controlLog.setCreateTime(new Date());
        }
        if (null != controlLog) {
            if (logService.saveOrUpdate(controlLog)) {
                log.info("异步生成{ " + deviceInfo.getDeviceName() + " }操作日志 - 成功");
            } else {
                log.info("异步生成{ " + deviceInfo.getDeviceName() + " }操作日志 - 失败");
            }
        }
        if (this.baseMapper.updateById(deviceInfo) > 0) {
            log.info("异步更新{ " + deviceInfo.getDeviceName() + " }开关信息 - 成功");
        } else {
            log.info("异步更新{ " + deviceInfo.getDeviceName() + " }开关信息 - 失败");
        }

    }
}
