package com.huiju.estateagents.task;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.huiju.estateagents.common.CommConstant;
import com.huiju.estateagents.common.DateUtils;
import com.huiju.estateagents.common.StringUtils;
import com.huiju.estateagents.common.WxUtils;
import com.huiju.estateagents.entity.TaMpTemplate;
import com.huiju.estateagents.entity.TaOrg;
import com.huiju.estateagents.property.service.ITaUserVerifyService;
import com.huiju.estateagents.service.ITaMpTemplateService;
import com.huiju.estateagents.service.ITaOrgService;
import com.huiju.estateagents.service.ITpMessageEventService;
import com.huiju.estateagents.third.service.ITaMpInfoService;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Component
public class MpMessageEvent {

    @Value("${wx.mp.festivalH5}")
    String festivalH5;

    @Value("${wx.mp.birthdayH5}")
    String birthdayH5;

    @Autowired
    WxUtils wxUtils;

    @Autowired
    ITaMpInfoService iTaMpInfoService;

    @Autowired
    ITpMessageEventService iTpMessageEventService;

    @Autowired
    ITaMpTemplateService iTaMpTemplateService;

    @Autowired
    ITaOrgService iTaOrgService;

    @Autowired
    ITaUserVerifyService iTaUserVerifyService;

    // 农历工具
    LunarUtils lunarUtils;

    // 发送生日祝福
    @Scheduled(cron = "0 0 8 * * ?")
    public void sendBirthdayMessage() {
        String today = DateUtils.today();
        String monDayCompact = today.replaceAll("-", "").substring(4);
        String firstTxt = "来自物业的祝福";
        String remarkTxt = "感谢您对我们工作的支持!";
        List<TaOrg> orgList = iTaOrgService.list();
        for (TaOrg org: orgList) {
            // 没有微信服务的
            WxMpService mpService = wxUtils.getMpService(org.getOrgId());
            if (null == mpService) {
                continue;
            }

            // 没有开启生日祝福或者设置生日模板的
            List<TaMpTemplate> mpTemplateList = iTaMpTemplateService.getAvailableList(org.getOrgId(), CommConstant.TP_MESSAGE_BIRTHDAY);
            if (null == mpTemplateList || mpTemplateList.size() < 1) {
                continue;
            }
            TaMpTemplate mpTemplate = mpTemplateList.get(0);

            long pageNum = 1L;
            long pageSize = 10L;
            long total = 0L;

            while (true) {
                Page<Map<String, String>> page = new Page<>(pageNum, pageSize);
                Page<Map<String, String>> result = iTaUserVerifyService.getPropUserByBirday(page, org.getOrgId(), monDayCompact);

                for (Map<String, String> user: result.getRecords()) {
                    Map<String, String> idProps = parseID(user.get("idCard"));
                    if (null == idProps) {
                        continue;
                    }

                    String gender = idProps.get("sex").equals("2") ? "女士" : "先生";
                    String name = user.get("ownerName") + "(" + gender + ")";
                    String content = String.format("尊敬的业主 %s: %s 携全体员工 %s", name, org.getName(), mpTemplate.getWishes());
                    String url = birthdayH5 + "?name=" + StringUtils.urlEncode(name) + "&org=" + StringUtils.urlEncode(org.getName()) + "&date=" + today;

                    try {
                        WxUtils.sendTemplateMessage(mpService,
                                user.get("mpOpenid"),
                                mpTemplate.getTemplateCode(),
                                url,
                                new ArrayList<WxMpTemplateData>(){{
                                    add(new WxMpTemplateData("first", firstTxt));
                                    add(new WxMpTemplateData("keyword1", "生日快乐"));
                                    add(new WxMpTemplateData("keyword2", today));
                                    add(new WxMpTemplateData("keyword3", content));
                                    add(new WxMpTemplateData("remark", remarkTxt));
                                }}
                        );
                    } catch (WxErrorException e) {
                        e.printStackTrace();
                    }

                    // 每间隔1秒发送一条消息
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                pageNum = result.getCurrent();
                total = result.getTotal();
                if ((pageNum - 1) * pageSize >= total) {
                    break;
                } else {
                    pageNum += 1;
                }
            }

        }
    }

    // 发送节日祝福
    @Scheduled(cron = "0 0 8 * * ?")
    public void sendFestivalMessage() {
        String today = DateUtils.today();
        String todayCompact = today.replaceAll("-", "");
        try {
            lunarUtils = new LunarUtils(today);
        } catch (IOException | NoSuchAlgorithmException | KeyStoreException | KeyManagementException e) {
            e.printStackTrace();
        }

        String firstTxt = "来自物业的祝福";
        String remarkTxt = "感谢您对我们工作的支持!";
        List<TaOrg> orgList = iTaOrgService.list();
        for (TaOrg org: orgList) {
            // 没有微信服务的
            WxMpService mpService = wxUtils.getMpService(org.getOrgId());
            if (null == mpService) {
                continue;
            }

            // 没有开启设置的
            List<TaMpTemplate> mpTemplateListTmp = iTaMpTemplateService.getAvailableList(org.getOrgId(), CommConstant.TP_MESSAGE_FESTIVAL);
            if (null == mpTemplateListTmp || mpTemplateListTmp.size() < 1) {
                continue;
            }

            // 过滤掉不是今天需要发送的
            List<TaMpTemplate> mpTemplateList = new ArrayList<>();
            for (TaMpTemplate item: mpTemplateListTmp) {
                // 默认阳历
                boolean isSolar = null == item.getIsSolar() ? true : item.getIsSolar();
                if (isSolar) {
                    // 2020-
                    String yearPrefix = today.substring(0, 5);
                    if (today.equals(yearPrefix + item.getEvtDate())) {
                        mpTemplateList.add(item);
                    }
                } else {
                    if (lunarUtils.is(item.getEvtDate())) {
                        mpTemplateList.add(item);
                    }
                }
            }
            if (mpTemplateList.size() < 1) {
                continue;
            }

            long pageNum = 1L;
            long pageSize = 10L;
            long total = 0L;

            while (true) {
                Page<Map<String, String>> page = new Page<>(pageNum, pageSize);
                Page<Map<String, String>> result = iTaUserVerifyService.getPropUserByPaged(page, org.getOrgId());

                for (Map<String, String> user: result.getRecords()) {
                    Map<String, String> idProps = parseID(user.get("idCard"));
                    if (null == idProps) {
                        continue;
                    }

                    String gender = Integer.parseInt(idProps.get("sex")) % 2 == 0 ? "女士" : "先生";
                    String name = user.get("ownerName") + "(" + gender + ")";

                    for (TaMpTemplate mpTemplate: mpTemplateList) {
                        String content = String.format("尊敬的业主 %s: %s 携全体员工 %s", name, org.getName(), mpTemplate.getWishes());
                        String url = festivalH5 + "?name=" + StringUtils.urlEncode(name)
                                + "&org=" + StringUtils.urlEncode(org.getName())
                                + "&date=" + today
                                + "&festival=" + mpTemplate.getEvtName();

                        try {
                            WxUtils.sendTemplateMessage(mpService,
                                    user.get("mpOpenid"),
                                    mpTemplate.getTemplateCode(),
                                    url,
                                    new ArrayList<WxMpTemplateData>(){{
                                        add(new WxMpTemplateData("first", firstTxt));
                                        add(new WxMpTemplateData("keyword1", mpTemplate.getEvtName() + "快乐"));
                                        add(new WxMpTemplateData("keyword2", today));
                                        add(new WxMpTemplateData("keyword3", content));
                                        add(new WxMpTemplateData("remark", remarkTxt));
                                    }}
                            );
                        } catch (WxErrorException e) {
                            e.printStackTrace();
                        }
                    }

                    // 每间隔1秒发送一条消息
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                pageNum = result.getCurrent();
                total = result.getTotal();
                if ((pageNum - 1) * pageSize >= total) {
                    break;
                } else {
                    pageNum += 1;
                }
            }

        }
    }

    private Map<String, String> parseID(String idNum) {
        String pattern = "(\\d{6})(\\d{8})(\\d{2})(\\d)(.)";
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(idNum);

        if (m.find()) {
            return new HashMap<String, String>(){{
                put("area", m.group(1));
                put("birthday", m.group(2));
                put("serial", m.group(3));
                put("sex", m.group(4));
                put("checksum", m.group(5));
            }};
        }

        return null;
    }

}
