/*
 * Copyright [2022] [https://www.xiaonuo.vip]
 *
 * Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：
 *
 * 1.请不要删除和修改根目录下的LICENSE文件。
 * 2.请不要删除和修改Snowy源码头部的版权声明。
 * 3.本项目代码可免费商业使用，商业使用请保留源码和相关描述文件的项目出处，作者声明等。
 * 4.分发源码时候，请注明软件出处 https://www.xiaonuo.vip
 * 5.不可二次分发开源参与同类竞品，如有想法可联系团队xiaonuobase@qq.com商议合作。
 * 6.若您的项目无法满足以上几点，需要更多功能代码，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
package vip.xiaonuo.biz.modular.depotDeviceWarn.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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 org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.xiaonuo.biz.core.Const.BizStr;
import vip.xiaonuo.biz.modular.depotAlarm.param.DepotAlarmAddParam;
import vip.xiaonuo.biz.modular.depotAlarm.service.DepotAlarmService;
import vip.xiaonuo.biz.modular.depotDeviceWarn.param.*;
import vip.xiaonuo.biz.modular.depotGrain.service.DepotGrainService;
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.page.CommonPageRequest;
import vip.xiaonuo.biz.modular.depotDeviceWarn.entity.DepotDeviceWarn;
import vip.xiaonuo.biz.modular.depotDeviceWarn.mapper.DepotDeviceWarnMapper;
import vip.xiaonuo.common.prop.CommonProperties;
import vip.xiaonuo.common.util.DatesUtil;
import vip.xiaonuo.dev.api.DevFileApi;
import vip.xiaonuo.dev.modular.file.util.MultipartFileUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * 离线报警Service接口实现类
 *
 * @author xiang
 * @date 2023/09/19 13:59
 **/
@Service
public class DepotDeviceWarnService extends ServiceImpl<DepotDeviceWarnMapper, DepotDeviceWarn> {

    @Resource
    DepotGrainService depotGrainService;
    @Resource
    DepotAlarmService alarmService;
    @Resource
    DevFileApi devFileApi;
    @Resource
    CommonProperties commonProperties;

    public Page<DepotDeviceWarn> page(DepotDeviceWarnPageParam param) {
        QueryWrapper<DepotDeviceWarn> wrapper = new QueryWrapper<>();
        List<String> depotIdLst = depotGrainService.lstOrgGrep();
        wrapper.lambda().in(CollUtil.isNotEmpty(depotIdLst), DepotDeviceWarn::getDepotId, depotIdLst);
        wrapper.and(Strings.isNotBlank(param.getSearchKey()), w ->
                w.lambda().like(DepotDeviceWarn::getDeviceName, param.getSearchKey())
                        .or().like(DepotDeviceWarn::getAlarmMsg, param.getSearchKey()));
        if (ObjectUtil.isNotEmpty(param.getDepotId())) {
            wrapper.lambda().eq(DepotDeviceWarn::getDepotId, param.getDepotId());
        }
        if (ObjectUtil.isNotEmpty(param.getDeviceName())) {
            wrapper.lambda().like(DepotDeviceWarn::getDeviceName, param.getDeviceName());
        }
        if (ObjectUtil.isNotEmpty(param.getDeviceTax())) {
            wrapper.lambda().like(DepotDeviceWarn::getDeviceTax, param.getDeviceTax());
        }
        if (ObjectUtil.isNotEmpty(param.getAlarmMsg())) {
            wrapper.lambda().like(DepotDeviceWarn::getAlarmMsg, param.getAlarmMsg());
        }
        if (ObjectUtil.isNotEmpty(param.getSaveState())) {
            wrapper.lambda().eq(DepotDeviceWarn::getSaveState, param.getSaveState());
        }
        if (ObjectUtil.isAllNotEmpty(param.getSortField(), param.getSortOrder())) {
            CommonSortOrderEnum.validate(param.getSortOrder());
            wrapper.orderBy(true, param.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
                    StrUtil.toUnderlineCase(param.getSortField()));
        } else {
            wrapper.lambda().orderByDesc(DepotDeviceWarn::getId);
        }
        Page page = this.page(CommonPageRequest.defaultPage(), wrapper);
        //匹配粮库名称
        depotGrainService.putDepotName(page.getRecords());
        return page;
    }

    public List<DepotDeviceWarn> lst(DepotDeviceWarnPageParam param) {
        return lst(BeanUtil.toBean(param, DepotDeviceWarn.class));
    }

    public List<DepotDeviceWarn> lst(DepotDeviceWarn param) {
        return list(new LambdaQueryWrapper<>(param));
    }

    public DepotDeviceWarn getOneNoProcess(DepotDeviceWarn param) {
        LambdaQueryWrapper<DepotDeviceWarn> wrapper = new LambdaQueryWrapper<>(param);
        wrapper.ne(DepotDeviceWarn::getSaveState, BizStr.STATE_PROCESS_Y);
        return getOne(wrapper.last("limit 1"));
    }

    public DepotDeviceWarn add(DepotDeviceWarnAddParam param) {
        DepotAlarmAddParam alarmAddParam = new DepotAlarmAddParam(param.getDepotId(), BizStr.ALARM_DEVICE, StringUtils.join(param.getDeviceName(), param.getAlarmMsg()));
        alarmService.add(alarmAddParam);
        DepotDeviceWarn depotDeviceWarn = BeanUtil.toBean(param, DepotDeviceWarn.class);
        depotDeviceWarn.setUnionAlarmId(alarmAddParam.getId());
        this.save(depotDeviceWarn);
        return depotDeviceWarn;
    }

    public void edit(DepotDeviceWarnEditParam param) {
        DepotDeviceWarn depotDeviceWarn = this.queryEntity(param.getId());
        BeanUtil.copyProperties(param, depotDeviceWarn);
        this.updateById(depotDeviceWarn);
    }

    @Transactional(rollbackFor = Exception.class)
    public void delete(List<DepotDeviceWarnIdParam> depotDeviceWarnIdParamList) {
        List<String> ids = CollStreamUtil.toList(depotDeviceWarnIdParamList, DepotDeviceWarnIdParam::getId);
        List<DepotDeviceWarn> alarms = listByIds(ids);
        // 联动删除
        alarmService.deleteByIds(CollStreamUtil.toList(alarms, DepotDeviceWarn::getUnionAlarmId));
        // 执行删除
        this.removeBatchByIds(ids);
    }

    public DepotDeviceWarn detail(DepotDeviceWarnIdParam depotDeviceWarnIdParam) {
        DepotDeviceWarn warn = this.queryEntity(depotDeviceWarnIdParam.getId());
        warn.setDepotGrainName(depotGrainService.getNameByDepotId(warn.getDepotId()));
        if (Strings.isNotBlank(warn.getSavePicUrl()))
            warn.setSavePicUrl(commonProperties.getBackendUrl() + warn.getSavePicUrl());
        return warn;
    }

    public DepotDeviceWarn queryEntity(String id) {
        DepotDeviceWarn depotDeviceWarn = this.getById(id);
        if (ObjectUtil.isEmpty(depotDeviceWarn)) {
            throw new CommonException("设备离线报警不存在，id值为：{}", id);
        }
        return depotDeviceWarn;
    }

    /**
     * 离线报警处理
     *
     * @author xiang
     * @date 2023/09/19 13:59
     **/
    public void editStateOnLine(String depotId, String deviceId) {
        List<DepotDeviceWarn> list = lst(new DepotDeviceWarnPageParam(depotId, deviceId, BizStr.STATE_PROCESS_N));
        if (list.isEmpty()) return;
        for (DepotDeviceWarn warn : list) {
            warn.setSaveState(BizStr.STATE_PROCESS_Y);
            alarmService.processById(warn.getUnionAlarmId());
        }
        updateBatchById(list);
    }

    /**
     * 处理
     *
     * @author xiang
     * @date 2023/09/19 13:59
     **/
    @Transactional(rollbackFor = Exception.class)
    public void processTo(DepotDeviceWarnProcessParam param) {
        DepotDeviceWarn one = getById(param.getId());
        one.setSaveState(param.getSaveState());
        if ("已忽略".equals(param.getSaveState())) {
            one.setSaveState(BizStr.STATE_PROCESS_Y);
            one.setSaveMsg("已忽略");
        } else {
            if (Strings.isBlank(param.getSaveMsg()))
                throw new CommonException("处理信息不能为空!");
            one.setSaveMsg(param.getSaveMsg());
            //处理图片
            if (Strings.isNotBlank(param.getSavePicUrl()) && !Objects.equals(param.getSavePicUrl(), one.getSavePicUrl())) {
                if (param.getSavePicUrl().length() != 19)
                    param.setSavePicUrl(devFileApi.storageFileWithReturnIdLocal(MultipartFileUtils.base64ToMultipart(param.getSavePicUrl())));
                if (param.getSavePicUrl().length() == 19)
                    param.setSavePicUrl(devFileApi.storageFilePathReturnUrlById(param.getSavePicUrl()));
            }
            one.setSavePicUrl(param.getSavePicUrl());
        }
        one.setSaveTime(DatesUtil.forDateTime());
        updateById(one);
        alarmService.processById(one.getUnionAlarmId(), one.getSaveState());
    }

}
