package com.tzld.piaoquan.offline.job;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.tzld.piaoquan.growth.common.common.constant.MessageConstant;
import com.tzld.piaoquan.growth.common.common.enums.MessageAttachmentTypeEnum;
import com.tzld.piaoquan.growth.common.common.enums.PreSpecialStatusEnum;
import com.tzld.piaoquan.growth.common.dao.mapper.*;
import com.tzld.piaoquan.growth.common.model.po.*;
import com.tzld.piaoquan.growth.common.service.MessageAttachmentService;
import com.tzld.piaoquan.growth.common.service.MessageService;
import com.tzld.piaoquan.growth.common.service.WeComUserService;
import com.tzld.piaoquan.growth.common.utils.DateUtil;
import com.tzld.piaoquan.growth.common.utils.ToolUtils;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


@Component
public class WeComSpecialDataJob {

    @Autowired
    private WeComUserMapper weComUserMapper;

    @Autowired
    private StaffMapper staffMapper;

    @Autowired
    private SpecialSendMessageMapper specialSendMessageMapper;

    @Autowired
    private MessageService messageService;

    @Autowired
    private MessageAttachmentService messageAttachmentService;

    @Autowired
    private WeComUserService weComUserService;

    @Autowired
    private PreSpecialSendMessageMapper preSpecialSendMessageMapper;

    @Autowired
    UserWithTagMapper userWithTagMapper;

    //发送小程序标题限制字节数
    private static final int MAX_BYTES = 64;

    @XxlJob("sendSpecialPushMessageJob")
    public ReturnT<String> getAndAddSpecialAssembleSendMessage(String param) {
        String thatDayDateString = DateUtil.getThatDayDateString();
        PreSpecialSendMessageExample example = new PreSpecialSendMessageExample();
        example.createCriteria().andPreSendDateEqualTo(thatDayDateString).andIsSendEqualTo(0);
        List<PreSpecialSendMessage> preSpecialSendMessages = preSpecialSendMessageMapper.selectByExample(example);
        List<PreSpecialSendMessage> defaultPreSpecialSendMessage = preSpecialSendMessages.stream()
                .filter(e -> Objects.equals(e.getStatus(), PreSpecialStatusEnum.DEFAULT.getStatus())).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(defaultPreSpecialSendMessage)) {
            for (PreSpecialSendMessage preSpecialSendMessage : defaultPreSpecialSendMessage) {
                defaultSpecialAssembleSendMessage(preSpecialSendMessage.getId(), preSpecialSendMessage.getStaffId(),
                        preSpecialSendMessage.getPageNum(), preSpecialSendMessage.getPageSize(),
                        preSpecialSendMessage.getGroupMsgDisabled().byteValue(), preSpecialSendMessage.getAttachmentIds(),
                        preSpecialSendMessage.getContent(), preSpecialSendMessage.getPreSendDate());
            }
        }
        List<PreSpecialSendMessage> tagPreSpecialSendMessage = preSpecialSendMessages.stream()
                .filter(e -> Objects.equals(e.getStatus(), PreSpecialStatusEnum.TAG.getStatus())).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(tagPreSpecialSendMessage)) {
            for (PreSpecialSendMessage preSpecialSendMessage : tagPreSpecialSendMessage) {
                tagSpecialAssembleSendMessage(preSpecialSendMessage.getId(), preSpecialSendMessage.getStaffId(), preSpecialSendMessage.getAttachmentIds(),
                        preSpecialSendMessage.getContent(), preSpecialSendMessage.getPreSendDate(), preSpecialSendMessage.getTagId(), preSpecialSendMessage.getGender());
            }
        }

        List<PreSpecialSendMessage> genderPreSpecialSendMessage = preSpecialSendMessages.stream()
                .filter(e -> Objects.equals(e.getStatus(), PreSpecialStatusEnum.GENDER.getStatus())).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(genderPreSpecialSendMessage)) {
            for (PreSpecialSendMessage preSpecialSendMessage : genderPreSpecialSendMessage) {
                genderSpecialAssembleSendMessage(preSpecialSendMessage.getId(), preSpecialSendMessage.getStaffId(),
                        preSpecialSendMessage.getGroupMsgDisabled().byteValue(), preSpecialSendMessage.getAttachmentIds(),
                        preSpecialSendMessage.getContent(), preSpecialSendMessage.getPreSendDate(), preSpecialSendMessage.getGender());
            }
        }
        //发送拼装好的消息
        sendSpecialPushMessage();

        for (PreSpecialSendMessage preSpecialSendMessage : preSpecialSendMessages) {
            PreSpecialSendMessage updatePreSpecialSendMessage = new PreSpecialSendMessage();
            updatePreSpecialSendMessage.setId(preSpecialSendMessage.getId());
            updatePreSpecialSendMessage.setIsSend(1);
            preSpecialSendMessageMapper.updateByPrimaryKeySelective(updatePreSpecialSendMessage);
        }
        return ReturnT.SUCCESS;
    }


    public void defaultSpecialAssembleSendMessage(Long preId, Long staffId, Integer pageNum, Integer pageSize,
                                                  byte groupMsgDisabled, String attachmentIds, String content, String date) {
        List<Long> filterTagId = weComUserService.getFilterTagId();
        List<Long> filterUserList = userWithTagMapper.selectFilterUserList();
        List<WeComUser> weComUserList = weComUserMapper.selectUserList(staffId, groupMsgDisabled, filterTagId, (pageNum - 1) * pageSize, pageSize);
        //落库逻辑
        for (WeComUser weComUser : weComUserList) {
            if (filterUserList.contains(weComUser.getId())) {
                continue;
            }
            SpecialSendMessage specialSendMessage = new SpecialSendMessage();
            specialSendMessage.setStaffId(staffId);
            specialSendMessage.setUserId(weComUser.getId());
            specialSendMessage.setGroup(preId.intValue());
            specialSendMessage.setAttachmentIds(attachmentIds);
            if (content.contains("${name}")) {
                specialSendMessage.setContent(content.replace("${name}", weComUser.getName()));
            } else {
                specialSendMessage.setContent(content);
            }
            specialSendMessage.setPreSendDate(date);
            specialSendMessageMapper.insertSelective(specialSendMessage);
        }
    }

    public void tagSpecialAssembleSendMessage(Long preId, Long staffId, String attachmentIds, String content, String date, Long tagId, Integer gender) {
        List<Long> filterUserList = userWithTagMapper.selectFilterUserList();
        List<WeComUser> weComUsers = weComUserMapper.selectByTagUserList(tagId);
        if (CollectionUtils.isEmpty(weComUsers)) {
            return;
        }
        for (WeComUser weComUser : weComUsers) {
            if (filterUserList.contains(weComUser.getId())) {
                continue;
            }
            if (gender != null && !gender.equals(weComUser.getGender())) {
                continue;
            }
            List<Staff> staffs = weComUserService.getStaffByUserId(weComUser.getId());
            if (CollectionUtils.isEmpty(staffs)) {
                continue;
            }
            for (Staff staff : staffs) {
                if (staffId != null && !Objects.equals(staff.getId(), staffId)) {
                    continue;
                }
                SpecialSendMessage specialSendMessage = new SpecialSendMessage();
                specialSendMessage.setStaffId(staff.getId());
                specialSendMessage.setUserId(weComUser.getId());
                specialSendMessage.setGroup(preId.intValue());
                specialSendMessage.setAttachmentIds(attachmentIds);
                if (content.contains("${name}")) {
                    specialSendMessage.setContent(content.replace("${name}", weComUser.getName()));
                } else {
                    specialSendMessage.setContent(content);
                }
                specialSendMessage.setPreSendDate(date);
                specialSendMessageMapper.insertSelective(specialSendMessage);
            }

        }
    }

    public void genderSpecialAssembleSendMessage(Long preId, Long staffId, byte groupMsgDisabled, String attachmentIds,
                                                 String content, String date, Integer gender) {
        List<Long> filterTagId = weComUserService.getFilterTagId();
        List<Long> filterUserList = userWithTagMapper.selectFilterUserList();
        List<WeComUser> weComUserList = weComUserMapper.selectByGenderUserList(staffId, groupMsgDisabled, filterTagId, gender);
        //落库逻辑
        for (WeComUser weComUser : weComUserList) {
            if (filterUserList.contains(weComUser.getId())) {
                continue;
            }
            SpecialSendMessage specialSendMessage = new SpecialSendMessage();
            specialSendMessage.setStaffId(staffId);
            specialSendMessage.setUserId(weComUser.getId());
            specialSendMessage.setGroup(preId.intValue());
            specialSendMessage.setAttachmentIds(attachmentIds);
            if (content.contains("${name}")) {
                specialSendMessage.setContent(content.replace("${name}", weComUser.getName()));
            } else {
                specialSendMessage.setContent(content);
            }
            specialSendMessage.setPreSendDate(date);
            specialSendMessageMapper.insertSelective(specialSendMessage);
        }
    }


    public void sendSpecialPushMessage() {
        String thatDayDateString = DateUtil.getThatDayDateString();
        List<SpecialSendMessage> groupList = specialSendMessageMapper.getGroupList(thatDayDateString);
        for (SpecialSendMessage specialSendMessage : groupList) {
            List<String> externalUserIds = specialSendMessageMapper.selectExternalUserId(specialSendMessage.getStaffId(),
                    specialSendMessage.getContent(), specialSendMessage.getGroup(), thatDayDateString);
            System.out.println(externalUserIds);
            boolean flag = specialPushMessage(externalUserIds, specialSendMessage);
            if (flag) {
                SpecialSendMessage updateSpecialSendMessage = new SpecialSendMessage();
                updateSpecialSendMessage.setIsSend(1);
                SpecialSendMessageExample example = new SpecialSendMessageExample();
                SpecialSendMessageExample.Criteria criteria = example.createCriteria()
                        .andStaffIdEqualTo(specialSendMessage.getStaffId())
                        .andGroupEqualTo(specialSendMessage.getGroup())
                        .andContentEqualTo(specialSendMessage.getContent())
                        .andPreSendDateEqualTo(thatDayDateString);
                if (StringUtils.isNotEmpty(specialSendMessage.getAttachmentIds())) {
                    criteria.andAttachmentIdsEqualTo(specialSendMessage.getAttachmentIds());
                }
                specialSendMessageMapper.updateByExampleSelective(updateSpecialSendMessage, example);
            }
        }
    }

    private boolean specialPushMessage(List<String> sendUserList, SpecialSendMessage specialSendMessage) {
        List<JSONObject> pushList = new ArrayList<>();
        StaffExample staffExample = new StaffExample();
        staffExample.createCriteria().andIdEqualTo(specialSendMessage.getStaffId());
        List<Staff> staffList = staffMapper.selectByExample(staffExample);
        Staff staff = staffList.get(0);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("chat_type", "single");
        JSONObject text = new JSONObject();
        if (StringUtils.isNotEmpty(specialSendMessage.getContent())) {
            text.put("content", specialSendMessage.getContent());
        } else {
            text.put("content", messageService.getMessageText(staff.getId()));
        }
        jsonObject.put("text", text);
        jsonObject.put("sender", staff.getCarrierId());
        String attachmentIds = specialSendMessage.getAttachmentIds();
        JSONArray attachments = new JSONArray();
        if (StringUtils.isNotEmpty(attachmentIds)) {
            List<Long> attachmentIdList = JSONArray.parseArray(attachmentIds, Long.class);
            if (!CollectionUtils.isEmpty(attachmentIdList)) {
                List<MessageAttachment> messageAttachments = messageAttachmentService.getMessageAttachment(attachmentIdList);
                if (!CollectionUtils.isEmpty(messageAttachments)) {
                    for (MessageAttachment messageAttachment : messageAttachments) {
                        Integer type = messageAttachment.getType();
                        if (Objects.equals(MessageAttachmentTypeEnum.MINI_PROGRAM.getCode(), type)) {
                            JSONObject miniprogramAttachment = new JSONObject();
                            JSONObject miniprogram = new JSONObject();
                            if (StringUtils.isNotEmpty(messageAttachment.getAppid())) {
                                miniprogram.put("appid", messageAttachment.getAppid());
                            } else {
                                miniprogram.put("appid", MessageConstant.appid);
                            }
                            String title = messageAttachment.getTitle();
                            if (title.getBytes(StandardCharsets.UTF_8).length > MAX_BYTES) {
                                title = ToolUtils.truncateString(title, MAX_BYTES - 3) + "...";
                            }
                            miniprogram.put("title", title);
                            String picMediaId = messageAttachment.getMediaId();
                            if (StringUtils.isEmpty(picMediaId)) {
                                return false;
                            }
                            miniprogram.put("pic_media_id", picMediaId);
                            String page = messageAttachment.getPage();
                            if (StringUtils.isEmpty(page)) {
                                return false;
                            }
                            miniprogram.put("page", page);
                            miniprogramAttachment.put("msgtype", "miniprogram");
                            miniprogramAttachment.put("miniprogram", miniprogram);
                            attachments.add(miniprogramAttachment);
                        }

                        if (Objects.equals(MessageAttachmentTypeEnum.LINK.getCode(), type)) {
                            JSONObject linkAttachment = new JSONObject();
                            JSONObject link = new JSONObject();
                            link.put("title", messageAttachment.getTitle());
                            link.put("picurl", messageAttachment.getPicUrl());
                            link.put("desc", messageAttachment.getDesc());
                            link.put("url", messageAttachment.getUrl());
                            linkAttachment.put("msgtype", "link");
                            linkAttachment.put("link", link);
                            attachments.add(linkAttachment);
                        }

                        if (Objects.equals(MessageAttachmentTypeEnum.IMAGE.getCode(), type)) {
                            JSONObject imageAttachment = new JSONObject();
                            JSONObject image = new JSONObject();
                            image.put("media_id", messageAttachment.getMediaId());
                            imageAttachment.put("msgtype", "image");
                            imageAttachment.put("image", image);
                            attachments.add(imageAttachment);
                        }

                        if (Objects.equals(MessageAttachmentTypeEnum.VIDEO.getCode(), type)) {
                            JSONObject videoAttachment = new JSONObject();
                            JSONObject image = new JSONObject();
                            image.put("media_id", messageAttachment.getMediaId());
                            videoAttachment.put("msgtype", "video");
                            videoAttachment.put("video", image);
                            attachments.add(videoAttachment);
                        }
                    }

                }
            }
        }
        if (!attachments.isEmpty()) {
            jsonObject.put("attachments", attachments);
        }
        List<List<String>> lists = Lists.partition(sendUserList, 10000);
        for (List<String> list : lists) {
            JSONArray externalUserIds = JSONArray.parseArray(JSON.toJSONString(list));
            JSONObject newJSONObject = new JSONObject();
            newJSONObject.putAll(jsonObject);
            newJSONObject.put("external_userid", externalUserIds);
            pushList.add(newJSONObject);
        }
        if (CollectionUtils.isEmpty(pushList)) {
            return false;
        }
        for (JSONObject pushJsonObject : pushList) {
            boolean flag = messageService.pushWeComMessage(pushJsonObject, 1L);
            if (!flag) {
                return flag;
            }
        }
        return true;
    }
}
