package com.xjrsoft.module.oa.utils;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.mail.MailAccount;
import cn.hutool.extra.mail.MailUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference;
import com.xjrsoft.common.constant.GlobalConstant;
import com.xjrsoft.common.enums.MessageType;
import com.xjrsoft.common.enums.YesOrNoEnum;
import com.xjrsoft.common.sms.SmsSender;
import com.xjrsoft.common.utils.LocalDateTimeUtil;
import com.xjrsoft.common.utils.RedisUtil;
import com.xjrsoft.common.utils.WeChatUtil;
import com.xjrsoft.config.CommonPropertiesConfig;
import com.xjrsoft.module.oa.entity.Message;
import com.xjrsoft.module.oa.service.IMessageService;
import com.xjrsoft.module.organization.entity.User;
import com.xjrsoft.module.organization.service.IUserService;
import com.xjrsoft.module.workflow.model.NoticePolicyParam;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 发送信息工具类
 *
 * @Author: tzx
 * @Date: 2022/10/26 16:59
 */
@Slf4j
public class SendMessageUtil {

    public static final String SCHEDULE_CONTENT_TEMPLATE = "您有一则新的日程《{}》,请及时查看.";

    public static final String WORKFLOW_APPROVE_TEMPLATE = "《{}》等待审批。";


    public static final String WORKFLOW_CIRULATED_TEMPLATE = "《{}》等待查看。";

    public static final String WORKFLOW_TIMEOUT_TEMPLATE = "《{}》任务已超时,等待审批。";


    /**
     * 添加日程消息
     */
    public static void sendScheduleMessage(Long userId, String objectId, String title) {
        IMessageService messageService = SpringUtil.getBean(IMessageService.class);

        Message message = new Message();
        message.setMessageType(MessageType.SCHEDULE.getCode());
        message.setSendTime(LocalDateTime.now());
        message.setIsRead(YesOrNoEnum.NO.getCode());
        message.setUserId(userId);
        message.setObjectId(objectId);
        message.setMessageContent(StrUtil.format(SCHEDULE_CONTENT_TEMPLATE, title));

        messageService.save(message);
    }

    /**
     * 发送工作流审批微信消息
     */
    public static void sendWorkflowApproveWx(NoticePolicyParam param, String name) {
        IUserService userService = SpringUtil.getBean(IUserService.class);
        RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);

        WeChatUtil weChatUtil = SpringUtil.getBean(WeChatUtil.class);

        CommonPropertiesConfig cpConfig = SpringUtil.getBean(CommonPropertiesConfig.class);

        //获取用户相关信息
        List<User> userList = redisUtil.get(GlobalConstant.USER_CACHE_KEY, new TypeReference<List<User>>() {
        });
        //如果缓存中不存在用户信息，就直接去数据库查询,并保存到缓存中去
        if (userList.size() == 0) {
            userList = userService.list();
            redisUtil.set(GlobalConstant.USER_CACHE_KEY, userList);
        }

        if (param.getNoticeUserIds().size() > 0) {
            for (Long userId : param.getNoticeUserIds()) {
                User user = userList.stream().filter(u -> userId.equals(u.getId())).findFirst().orElse(new User());
                String openId = user.getOpenId();

                if (StrUtil.isEmpty(openId)) {
                    break;
                }

                JSONObject data = new JSONObject();
                // 任务名称
                data.put("thing8", new JSONObject() {{
                    put("value", param.getSchemaName());
                }});
                // 事项名称
                data.put("thing2", new JSONObject() {{
                    put("value", name);
                }});
                // 申请人
                data.put("thing6", new JSONObject() {{
                    put("value", param.getStartUserName());
                }});
                // 时间
                data.put("time3", new JSONObject() {{
                    put("value", LocalDateTimeUtil.format(LocalDateTime.now(), LocalDateTimeUtil.LOCAL_DATE_TIME_FORMAT));
                }});

                JSONObject object = new JSONObject();
                object.put("touser", openId);
                object.put("template_id", "sHsmz7LRj7HLd7GSTS3r2jCLvK-4Wp19iGzEvYK8n_I");
//                object.put("miniprogram", new JSONObject() {{
//                    put("appid", weChatUtil.getAppletAppKey());
//                    put("pagepath", StrUtil.format("{}/xjrsoft/pages/workflow/approval?taskId={}&processId={}&type=todo",cpConfig.getDomainApp(), param.getTaskId(), param.getProcessId()));
//                }});
                object.put("url", StrUtil.format("{}/xjrsoft/pages/workflow/approval?taskId={}&processId={}&type=todo",cpConfig.getDomainApp(), param.getTaskId(), param.getProcessId()));
                object.put("client_msg_id", param.getTaskId());
                object.put("data", data);
                weChatUtil.sendTemplateMessage(object);
            }
        }
    }

    /**
     * 发送工作流未审批微信消息
     */
    public static void sendWorkflowUnapprovedWx(Map<String, StringBuilder> message) {
        IUserService userService = SpringUtil.getBean(IUserService.class);
        RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);

        WeChatUtil weChatUtil = SpringUtil.getBean(WeChatUtil.class);

        CommonPropertiesConfig cpConfig = SpringUtil.getBean(CommonPropertiesConfig.class);

        //获取用户相关信息
        List<User> userList = redisUtil.get(GlobalConstant.USER_CACHE_KEY, new TypeReference<List<User>>() {
        });
        //如果缓存中不存在用户信息，就直接去数据库查询,并保存到缓存中去
        if (userList.size() == 0) {
            userList = userService.list();
            redisUtil.set(GlobalConstant.USER_CACHE_KEY, userList);
        }

        for (Map.Entry<String, StringBuilder> entry : message.entrySet()) {
            String key = entry.getKey();
            StringBuilder value = entry.getValue();
//            System.out.println(key + "--" + value);
            // 处理每个用户
            User user = userList.stream().filter(u -> key.equals(u.getId())).findFirst().orElse(new User());
            String openId = user.getOpenId();
//            System.err.println(openId);
            if (StrUtil.isEmpty(openId)) {
                continue;
            }

            JSONObject data = new JSONObject();
            // 任务名称
            data.put("thing8", new JSONObject() {{
                put("value", value.toString());
            }});
            // 事项名称
            data.put("thing2", new JSONObject() {{
                put("value", value.toString());
            }});
            // 申请人
            data.put("thing6", new JSONObject() {{
                put("value", "");
            }});
            // 时间
            data.put("time3", new JSONObject() {{
                put("value", LocalDateTimeUtil.format(LocalDateTime.now(), LocalDateTimeUtil.LOCAL_DATE_TIME_FORMAT));
            }});

            JSONObject object = new JSONObject();
            object.put("touser", openId);
            object.put("template_id", "sHsmz7LRj7HLd7GSTS3r2jCLvK-4Wp19iGzEvYK8n_I");
//                object.put("miniprogram", new JSONObject() {{
//                    put("appid", weChatUtil.getAppletAppKey());
//                    put("pagepath", StrUtil.format("{}/xjrsoft/pages/workflow/approval?taskId={}&processId={}&type=todo",cpConfig.getDomainApp(), param.getTaskId(), param.getProcessId()));
//                }});
            object.put("url", StrUtil.format("{}/xjrsoft/pages/home/home",cpConfig.getDomainApp()));
//            object.put("client_msg_id", param.getTaskId());
            object.put("data", data);
            Boolean isSuccess = weChatUtil.sendTemplateMessage(object);
            //System.err.println(isSuccess);
        }
    }

    /**
     * 添加工作流审批消息
     */
    public static void sendWorkflowApproveMessage(NoticePolicyParam param) {
        IMessageService messageService = SpringUtil.getBean(IMessageService.class);

        List<Message> messageList = new ArrayList<>();
        for (Long userId : param.getNoticeUserIds()) {
            Message message = new Message();
            message.setMessageType(MessageType.APPROVE.getCode());
            message.setSendTime(LocalDateTime.now());
            message.setIsRead(YesOrNoEnum.NO.getCode());
            message.setUserId(userId);
            message.setObjectId(param.getTaskId());
            message.setMessageContent(StrUtil.format(WORKFLOW_APPROVE_TEMPLATE, param.getTaskName()));
            message.setProcessId(param.getProcessId());
            message.setSchemaId(param.getSchemaId());

            messageList.add(message);
        }

        messageService.saveBatch(messageList);
    }


    /**
     * 发送工作流审批短信
     */
    public static void sendWorkflowApproveSms(NoticePolicyParam param, String name) {
        IUserService userService = SpringUtil.getBean(IUserService.class);
        RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);

        SmsSender smsSender = SpringUtil.getBean(SmsSender.class);

        //获取用户相关信息
        List<User> userList = redisUtil.get(GlobalConstant.USER_CACHE_KEY, new TypeReference<List<User>>() {
        });
        //如果缓存中不存在用户信息，就直接去数据库查询,并保存到缓存中去
        if (userList.size() == 0) {
            userList = userService.list();
            redisUtil.set(GlobalConstant.USER_CACHE_KEY, userList);
        }
        //构造短信参数，调用短信服务进行短信发送
        if (param.getNoticeUserIds().size() > 0) {
            //获取用户id对应的手机号，用户名
            for (Long userId : param.getNoticeUserIds()) {
                User user = userList.stream().filter(u -> userId.equals(u.getId())).findFirst().orElse(new User());
                String mobile = user.getMobile();
                //调用短信接口服务
                smsSender.sendTimeout(mobile, name);
            }
        }
    }


    /**
     * 添加工作流传阅消息
     */
    public static void sendWorkflowCirculatedMessage(NoticePolicyParam param) {
        IMessageService messageService = SpringUtil.getBean(IMessageService.class);

        List<Message> messageList = new ArrayList<>();
        for (Long userId : param.getNoticeUserIds()) {
            Message message = new Message();
            message.setMessageType(MessageType.CIRCULATED.getCode());
            message.setSendTime(LocalDateTime.now());
            message.setIsRead(YesOrNoEnum.NO.getCode());
            message.setUserId(userId);
            message.setObjectId(param.getTaskId());
            message.setMessageContent(StrUtil.format(WORKFLOW_CIRULATED_TEMPLATE, param.getTaskName()));
            message.setProcessId(param.getProcessId());
            message.setSchemaId(param.getSchemaId());
            messageList.add(message);
        }

        messageService.saveBatch(messageList);
    }

    /**
     * 发送工作流传阅短信
     */
    public static void sendWorkflowCirculatedSms(NoticePolicyParam param, String name) {
        IUserService userService = SpringUtil.getBean(IUserService.class);
        RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);

        SmsSender smsSender = SpringUtil.getBean(SmsSender.class);

        //获取用户相关信息
        List<User> userList = redisUtil.get(GlobalConstant.USER_CACHE_KEY, new TypeReference<List<User>>() {
        });
        //如果缓存中不存在用户信息，就直接去数据库查询,并保存到缓存中去
        if (userList.size() == 0) {
            userList = userService.list();
            redisUtil.set(GlobalConstant.USER_CACHE_KEY, userList);
        }
        //构造短信参数，调用短信服务进行短信发送
        if (param.getNoticeUserIds().size() > 0) {
            //获取用户id对应的手机号，用户名
            for (Long userId : param.getNoticeUserIds()) {
                User user = userList.stream().filter(u -> userId.equals(u.getId())).findFirst().orElse(new User());
                String mobile = user.getMobile();
//                //构建参数,您有一个 %s - %s 创建的《%s》任务已超时,请及时处理.StrUtil.format():使用占位符进行替换
//                String text = StrUtil.format(SendMessageUtil.WORKFLOW_TIMEOUT_TEMPLATE, param.getStartUserName(), LocalDateTime.now().format(DateTimeFormatter.ofPattern(GlobalConstant.YYYY_MM_DD_HH_MM_SS_24)), param.getSchemaName());
                //调用短信接口服务
                smsSender.sendCirculated(mobile, name);
            }
        }
    }


    /**
     * 添加工作流超时
     */
    public static void sendWorkflowTimeoutMessage(NoticePolicyParam param) {
        IMessageService messageService = SpringUtil.getBean(IMessageService.class);

        List<Message> messageList = new ArrayList<>();
        for (Long userId : param.getNoticeUserIds()) {
            Message message = new Message();
            //将超时提醒显示在工作流审批消息中
            message.setMessageType(MessageType.APPROVE.getCode());
            message.setSendTime(LocalDateTime.now());
            message.setIsRead(YesOrNoEnum.NO.getCode());
            message.setUserId(userId);
            message.setObjectId(param.getTaskId());
            String format = StrUtil.format(WORKFLOW_TIMEOUT_TEMPLATE, param.getTaskName());
            message.setMessageContent(format);
            message.setProcessId(param.getProcessId());
            message.setSchemaId(param.getSchemaId());
            messageList.add(message);
        }

        messageService.saveBatch(messageList);
    }

    /**
     * 添加工作流超时短信提醒服务
     */
    public static void sendWorkflowTimeoutSms(NoticePolicyParam param, String name) {
        IUserService userService = SpringUtil.getBean(IUserService.class);
        RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);

        SmsSender smsSender = SpringUtil.getBean(SmsSender.class);

        //获取用户相关信息
        List<User> userList = redisUtil.get(GlobalConstant.USER_CACHE_KEY, new TypeReference<List<User>>() {
        });
        //如果缓存中不存在用户信息，就直接去数据库查询,并保存到缓存中去
        if (userList.size() == 0) {
            userList = userService.list();
            redisUtil.set(GlobalConstant.USER_CACHE_KEY, userList);
        }
        //构造短信参数，调用短信服务进行短信发送
        if (param.getNoticeUserIds().size() > 0) {
            //获取用户id对应的手机号，用户名
            for (Long userId : param.getNoticeUserIds()) {
                User user = userList.stream().filter(u -> userId.equals(u.getId())).findFirst().orElse(new User());
                String mobile = user.getMobile();
//                //构建参数,您有一个 %s - %s 创建的《%s》任务已超时,请及时处理.StrUtil.format():使用占位符进行替换
//                String text = StrUtil.format(SendMessageUtil.WORKFLOW_TIMEOUT_TEMPLATE, param.getStartUserName(), LocalDateTime.now().format(DateTimeFormatter.ofPattern(GlobalConstant.YYYY_MM_DD_HH_MM_SS_24)), param.getSchemaName());
                //调用短信接口服务
                smsSender.sendTimeout(mobile, name);
            }
        }
    }


    /**
     * 添加工作流超时 断行
     */
    public static void sendWorkflowTimeoutEmail(NoticePolicyParam param) {
        MailAccount mailAccount = SpringUtil.getBean(MailAccount.class);
        RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);


        //获取到需要提醒的人员
        List<User> allUser = redisUtil.get(GlobalConstant.USER_CACHE_KEY, new TypeReference<List<User>>() {
        });

        List<String> allEmail = allUser.stream().filter(u -> param.getNoticeUserIds().contains(u.getId())).map(User::getEmail).collect(Collectors.toList());

        String content = StrUtil.format(SendMessageUtil.WORKFLOW_TIMEOUT_TEMPLATE, param.getStartUserName(), LocalDateTime.now().format(DateTimeFormatter.ofPattern(GlobalConstant.YYYY_MM_DD_HH_MM_SS_24)), param.getSchemaName());
        MailUtil.send(mailAccount, allEmail, "超时消息提醒", content, false);

    }


    /**
     * 添加工作流超时 断行
     */
    public static void sendWorkflowApproveEmail(NoticePolicyParam param) {
        MailAccount mailAccount = SpringUtil.getBean(MailAccount.class);
        RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);


        //获取到需要提醒的人员
        List<User> allUser = redisUtil.get(GlobalConstant.USER_CACHE_KEY, new TypeReference<List<User>>() {
        });

        List<String> allEmail = allUser.stream().filter(u -> param.getNoticeUserIds().contains(u.getId())).map(User::getEmail).collect(Collectors.toList());

        String content = StrUtil.format(SendMessageUtil.WORKFLOW_TIMEOUT_TEMPLATE, param.getStartUserName(), LocalDateTime.now().format(DateTimeFormatter.ofPattern(GlobalConstant.YYYY_MM_DD_HH_MM_SS_24)), param.getSchemaName());
        MailUtil.send(mailAccount, allEmail, "用户审批", content, false);
    }

    /**
     * 添加工作流超时 断行
     */
    public static void sendWorkflowCirculatedEmail(NoticePolicyParam param) {
        MailAccount mailAccount = SpringUtil.getBean(MailAccount.class);
        RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);


        //获取到需要提醒的人员
        List<User> allUser = redisUtil.get(GlobalConstant.USER_CACHE_KEY, new TypeReference<List<User>>() {
        });

        List<String> allEmail = allUser.stream().filter(u -> param.getNoticeUserIds().contains(u.getId())).map(User::getEmail).collect(Collectors.toList());

        String content = StrUtil.format(SendMessageUtil.WORKFLOW_TIMEOUT_TEMPLATE, param.getStartUserName(), LocalDateTime.now().format(DateTimeFormatter.ofPattern(GlobalConstant.YYYY_MM_DD_HH_MM_SS_24)), param.getSchemaName());
        MailUtil.send(mailAccount, allEmail, "用户传阅", content, false);
    }
}
