/*
 * 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.sysUserWxOpenSendLog.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
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 lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.xiaonuo.biz.api.wxapp.service.WxProcessApprovalPushService;
import vip.xiaonuo.biz.modular.depotGrain.entity.DepotGrain;
import vip.xiaonuo.biz.modular.depotGrain.service.DepotGrainService;
import vip.xiaonuo.biz.modular.depotGrainInfoWarn.entity.DepotGrainInfoWarn;
import vip.xiaonuo.biz.modular.sysUserWxOpenSendSet.service.SysUserWxOpenSendSetService;
import vip.xiaonuo.biz.modular.user.entity.UserWxOpen;
import vip.xiaonuo.biz.modular.user.service.UserWxOpenService;
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.page.CommonPageRequest;
import vip.xiaonuo.biz.modular.sysUserWxOpenSendLog.entity.SysUserWxOpenSendLog;
import vip.xiaonuo.biz.modular.sysUserWxOpenSendLog.mapper.SysUserWxOpenSendLogMapper;
import vip.xiaonuo.biz.modular.sysUserWxOpenSendLog.param.SysUserWxOpenSendLogAddParam;
import vip.xiaonuo.biz.modular.sysUserWxOpenSendLog.param.SysUserWxOpenSendLogEditParam;
import vip.xiaonuo.biz.modular.sysUserWxOpenSendLog.param.SysUserWxOpenSendLogIdParam;
import vip.xiaonuo.biz.modular.sysUserWxOpenSendLog.param.SysUserWxOpenSendLogPageParam;
import vip.xiaonuo.common.util.DatesUtil;
import vip.xiaonuo.sys.api.SysUserApi;
import vip.xiaonuo.sys.modular.user.entity.SysUser;
import vip.xiaonuo.sys.modular.user.service.SysUserService;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 用户微信推送消息表Service接口实现类
 *
 * @author xiang
 * @date 2023/12/11 17:47
 **/
@Slf4j
@Service
public class SysUserWxOpenSendLogService extends ServiceImpl<SysUserWxOpenSendLogMapper, SysUserWxOpenSendLog> {

    @Resource
    DepotGrainService depotGrainService;
    @Resource
    WxProcessApprovalPushService wxProcessApprovalPushService;
    @Resource
    SysUserWxOpenSendSetService sysUserWxOpenSendSetService;
    @Resource
    UserWxOpenService userWxOpenService;
    @Resource
    SysUserApi sysUserApi;
    @Resource
    SysUserService sysUserService;

    public Page<SysUserWxOpenSendLog> page(SysUserWxOpenSendLogPageParam sysUserWxOpenSendLogPageParam) {
        QueryWrapper<SysUserWxOpenSendLog> queryWrapper = new QueryWrapper<>();
        if (ObjectUtil.isNotEmpty(sysUserWxOpenSendLogPageParam.getUserId())) {
            queryWrapper.lambda().like(SysUserWxOpenSendLog::getUserId, sysUserWxOpenSendLogPageParam.getUserId());
        }
        if (ObjectUtil.isNotEmpty(sysUserWxOpenSendLogPageParam.getOpenId())) {
            queryWrapper.lambda().like(SysUserWxOpenSendLog::getOpenId, sysUserWxOpenSendLogPageParam.getOpenId());
        }
        if (ObjectUtil.isNotEmpty(sysUserWxOpenSendLogPageParam.getSendMsg())) {
            queryWrapper.lambda().like(SysUserWxOpenSendLog::getSendMsg, sysUserWxOpenSendLogPageParam.getSendMsg());
        }
        if (ObjectUtil.isNotEmpty(sysUserWxOpenSendLogPageParam.getBackMsg())) {
            queryWrapper.lambda().like(SysUserWxOpenSendLog::getBackMsg, sysUserWxOpenSendLogPageParam.getBackMsg());
        }
        if (ObjectUtil.isAllNotEmpty(sysUserWxOpenSendLogPageParam.getSortField(), sysUserWxOpenSendLogPageParam.getSortOrder())) {
            CommonSortOrderEnum.validate(sysUserWxOpenSendLogPageParam.getSortOrder());
            queryWrapper.orderBy(true, sysUserWxOpenSendLogPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
                    StrUtil.toUnderlineCase(sysUserWxOpenSendLogPageParam.getSortField()));
        } else {
            queryWrapper.lambda().orderByDesc(SysUserWxOpenSendLog::getId);
        }
        Page page = this.page(CommonPageRequest.defaultPage(), queryWrapper);
        putUserName(page.getRecords());
        return page;
    }

    /**
     * 匹配用户名称
     *
     * @param logs 列表
     */
    private void putUserName(List<SysUserWxOpenSendLog> logs) {
        if (logs.isEmpty()) return;
        List<String> userIdLst = logs.stream().map(SysUserWxOpenSendLog::getUserId).distinct().collect(Collectors.toList());
        List<SysUser> sysUsers = sysUserService.listByIds(userIdLst);
        for (SysUserWxOpenSendLog log : logs) {
            for (SysUser user : sysUsers) {
                if (Objects.equals(log.getUserId(), user.getId())) {
                    log.setUserName(user.getName());
                    break;
                }
            }
        }
    }

    public void add(SysUserWxOpenSendLogAddParam sysUserWxOpenSendLogAddParam) {
        SysUserWxOpenSendLog sysUserWxOpenSendLog = BeanUtil.toBean(sysUserWxOpenSendLogAddParam, SysUserWxOpenSendLog.class);
        this.save(sysUserWxOpenSendLog);
    }

    public void edit(SysUserWxOpenSendLogEditParam sysUserWxOpenSendLogEditParam) {
        SysUserWxOpenSendLog sysUserWxOpenSendLog = this.queryEntity(sysUserWxOpenSendLogEditParam.getId());
        BeanUtil.copyProperties(sysUserWxOpenSendLogEditParam, sysUserWxOpenSendLog);
        this.updateById(sysUserWxOpenSendLog);
    }

    @Transactional(rollbackFor = Exception.class)
    public void delete(List<SysUserWxOpenSendLogIdParam> sysUserWxOpenSendLogIdParamList) {
        // 执行删除
        this.removeBatchByIds(CollStreamUtil.toList(sysUserWxOpenSendLogIdParamList, SysUserWxOpenSendLogIdParam::getId));
    }

    public SysUserWxOpenSendLog detail(SysUserWxOpenSendLogIdParam sysUserWxOpenSendLogIdParam) {
        return this.queryEntity(sysUserWxOpenSendLogIdParam.getId());
    }

    public SysUserWxOpenSendLog queryEntity(String id) {
        SysUserWxOpenSendLog sysUserWxOpenSendLog = this.getById(id);
        if (ObjectUtil.isEmpty(sysUserWxOpenSendLog)) {
            throw new CommonException("用户微信推送消息表不存在，id值为：{}", id);
        }
        return sysUserWxOpenSendLog;
    }

    /**
     * 推送消息 设备离线、飞行监管异常
     *
     * @param depotId 项目
     * @param thing1  类型
     * @param thing2  问题点
     * @param time3   日期
     * @author xiang
     * @date 2023/12/11 17:47
     **/
    @Async
    public void send(String depotId, String thing1, String thing2, String time3) {
        thing2 = StringUtils.join(thing1, " ", thing2);
        thing2 = thing2.length() > 20 ? thing2.substring(0, 19) + "…" : thing2;

        DepotGrain grain = depotGrainService.getOne(depotId);
        if (grain == null) return;
        //订阅角色
        List<String> userIds = sysUserWxOpenSendSetService.grepUser(thing1);
        //订阅用户
        List<UserWxOpen> userWxOpens = userWxOpenService.list(userIds);
        for (UserWxOpen userWxOpen : userWxOpens) {
            SysUserWxOpenSendLog sendLog = new SysUserWxOpenSendLog(userWxOpen.getUserId(), userWxOpen.getOpenId());
            try {
                if (Strings.isBlank(userWxOpen.getUserId()) || Strings.isBlank(userWxOpen.getOpenId())) continue;
                SysUser sysUser = sysUserService.getById(userWxOpen.getUserId());
                if (sysUser == null || Strings.isBlank(sysUser.getOrgId())) continue;
                List<String> orgIds = sysUserApi.ownOrgGrep(sysUser.getOrgId());
                if (!orgIds.contains(grain.getOrgId())) continue;
                wxProcessApprovalPushService.sendProcessApprovalMsg(sendLog, sendLog.getOpenId(), grain.getDepotGrainName(), thing2, time3);
            } catch (Exception e) {
                log.info(String.format("推送消息 设备离线、飞行监管异常; grain:%s;thing1:%s;thing2:%s;time3:%s;", grain.getDepotGrainName(), thing1, thing2, time3));
                e.printStackTrace();
                sendLog.setBackMsg(e.getMessage());
            }
            this.save(sendLog);
        }
    }

    /**
     * 推送消息 客户风险
     *
     * @param warns   风险信息
     * @param logType 类型
     * @param time3   日期
     * @author xiang
     * @date 2023/12/11 17:47
     **/
    @Async
    public void send(List<DepotGrainInfoWarn> warns, String logType, String time3) {
        DepotGrain grain = new DepotGrain();
        List<SysUserWxOpenSendLog> logs = new ArrayList<>();
        depotGrainService.putDepotName(warns);

        //订阅角色
        List<String> userIds = sysUserWxOpenSendSetService.grepUser(logType);
        //订阅用户
        List<UserWxOpen> userWxOpens = userWxOpenService.list(userIds);
        for (UserWxOpen userWxOpen : userWxOpens) {
            if (Strings.isBlank(userWxOpen.getUserId()) || Strings.isBlank(userWxOpen.getOpenId())) continue;
            SysUser sysUser = sysUserService.getById(userWxOpen.getUserId());
            if (sysUser == null || Strings.isBlank(sysUser.getOrgId())) continue;
            List<String> orgIds = sysUserApi.ownOrgGrep(sysUser.getOrgId());
            for (DepotGrainInfoWarn warn : warns) {
                SysUserWxOpenSendLog sendLog = new SysUserWxOpenSendLog(userWxOpen.getUserId(), userWxOpen.getOpenId());
                try {
                    if (!warn.getDepotId().equals(grain.getDepotId()))
                        grain = depotGrainService.getOne(warn.getDepotId());
                    if (!orgIds.contains(grain.getOrgId())) continue;
                    String thing2 = StringUtils.join(logType, " ", warn.getWarnType());
                    thing2 = thing2.length() > 20 ? thing2.substring(0, 19) + "…" : thing2;
                    wxProcessApprovalPushService.sendProcessApprovalMsg(sendLog, sendLog.getOpenId()
                            , grain.getDepotGrainName(), thing2, time3);
                } catch (Exception e) {
                    log.info(String.format("推送消息 客户风险; warns:%s;time3:%s;", warns, time3));
                    e.printStackTrace();
                    sendLog.setBackMsg(e.getMessage());
                }
                logs.add(sendLog);
            }
        }
        if (!logs.isEmpty())
            this.saveBatch(logs);
    }

    /**
     * 推送消息 项目离线
     *
     * @param depotGrains 项目
     * @param logType     分类
     * @author xiang
     * @date 2023/12/11 17:47
     **/
    @Async
    public void send(List<DepotGrain> depotGrains, String logType) {
        List<SysUserWxOpenSendLog> logs = new ArrayList<>();

        //订阅角色
        List<String> userIds = sysUserWxOpenSendSetService.grepUser(logType);
        //订阅用户
        List<UserWxOpen> userWxOpens = userWxOpenService.list(userIds);
        for (UserWxOpen userWxOpen : userWxOpens) {
            if (Strings.isBlank(userWxOpen.getUserId()) || Strings.isBlank(userWxOpen.getOpenId())) continue;
            SysUser sysUser = sysUserService.getById(userWxOpen.getUserId());
            if (sysUser == null || Strings.isBlank(sysUser.getOrgId())) continue;
            List<String> orgIds = sysUserApi.ownOrgGrep(sysUser.getOrgId());
            for (DepotGrain depotGrain : depotGrains) {
                if (!orgIds.contains(depotGrain.getOrgId())) continue;
                SysUserWxOpenSendLog sendLog = new SysUserWxOpenSendLog(userWxOpen.getUserId(), userWxOpen.getOpenId());
                try {
                    String thing2 = depotGrain.getDepotGrainName();
                    thing2 = thing2 != null && thing2.length() > 20 ? thing2.substring(0, 19) + "…" : thing2;
                    wxProcessApprovalPushService.sendProcessApprovalMsg(sendLog, sendLog.getOpenId()
                            , thing2, logType, DatesUtil.forDateTime(depotGrain.getUpdateTime()));
                } catch (Exception e) {
                    log.info(String.format("推送消息 项目离线; depotGrains:%s;", depotGrains));
                    e.printStackTrace();
                    sendLog.setBackMsg(e.getMessage());
                }
                logs.add(sendLog);
            }
        }
        if (!logs.isEmpty())
            this.saveBatch(logs);
    }

    /**
     * 推送消息 出库入库
     *
     * @param depotId     项目
     * @param address     位置
     * @param logType     类型
     * @param car_number1 车牌号
     * @param phrase4     作业类型
     * @param thing5      报警原因
     * @param time7       提交时间
     * @author xiang
     * @date 2023/12/11 17:47
     **/
    @Async
    public void send(String depotId, String address, String logType, String car_number1, String phrase4, String thing5, String time7) {
        DepotGrain grain = depotGrainService.getOne(depotId);
        if (grain == null) return;
        String thing6 = StringUtils.join(grain.getDepotGrainName(), " ", address).trim();
        thing6 = thing6.length() > 20 ? thing6.substring(0, 19) + "…" : thing6;
        phrase4 = phrase4.length() > 5 ? phrase4.substring(0, 5) : phrase4;
        if (thing5 != null) {
            if (Strings.isNotBlank(car_number1))
                thing5 = thing5.replaceAll(car_number1, "");

            thing5 = thing5.replaceAll(",禁止上磅称重,请管理员及时处理预警信息", "");
            thing5 = thing5.replaceAll(",暂不可通行,请管理员及时处理预警信息", "");
            thing5 = thing5.replaceAll(",请管理员及时处理预警信息", "");
            thing5 = thing5.replaceAll(",禁止通行", "");
            thing5 = thing5.replaceAll(",不允许通行", "");
            thing5 = thing5.replaceAll("系统", "");
            thing5 = thing5.replaceAll("车辆", "");
            thing5 = thing5.length() > 20 ? thing5.substring(0, 19) + "…" : thing5;
        }
        //订阅角色
        List<String> userIds = sysUserWxOpenSendSetService.grepUser(logType);
        //订阅用户
        List<UserWxOpen> userWxOpens = userWxOpenService.list(userIds);
        for (UserWxOpen userWxOpen : userWxOpens) {
            SysUserWxOpenSendLog sendLog = new SysUserWxOpenSendLog(userWxOpen.getUserId(), userWxOpen.getOpenId());
            try {
                if (Strings.isBlank(userWxOpen.getUserId()) || Strings.isBlank(userWxOpen.getOpenId())) continue;
                SysUser sysUser = sysUserService.getById(userWxOpen.getUserId());
                if (sysUser == null || Strings.isBlank(sysUser.getOrgId())) continue;
                List<String> orgIds = sysUserApi.ownOrgGrep(sysUser.getOrgId());
                if (!orgIds.contains(grain.getOrgId())) continue;
                wxProcessApprovalPushService.sendProcessApprovalMsg(sendLog, sendLog.getOpenId(), car_number1, phrase4, thing5, time7, thing6);
            } catch (Exception e) {
                log.info(String.format("推送消息 出库入库异常; grain:%s;car_number1:%s;phrase4:%s;thing5:%s;thing6:%s;time7:%s;", grain.getDepotGrainName(), car_number1, phrase4, thing5, thing6, time7));
                e.printStackTrace();
                sendLog.setBackMsg(e.getMessage());
            }
            this.save(sendLog);
        }
    }

    public void send(String depotId, String logType, String car_number1, String phrase4, String thing5, String time7) {
        send(depotId, "", logType, car_number1, phrase4, thing5, time7);
    }

}
