package vip.xiaonuo.weixin.gongzhong.config;

import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import me.chanjar.weixin.mp.config.impl.WxMpMapConfigImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import vip.xiaonuo.coldchain.modular.alarmuser.entity.AlarmUser;
import vip.xiaonuo.coldchain.modular.alarmuser.service.AlarmUserService;
import vip.xiaonuo.coldchain.modular.push.config.PushConfigure;
import vip.xiaonuo.dev.modular.config.service.DevConfigService;
import vip.xiaonuo.weixin.gongzhong.service.WxMenuService;

import java.util.Map;
import java.util.Objects;

/**
 * WxJava 公众号配置
 */
@Slf4j
@Configuration
@RequiredArgsConstructor
public class WxMpConfiguration {

    private final PushConfigure properties;
    private final WxMenuService wxMenuService;
    private final AlarmUserService alarmUserService;
    private final DevConfigService devConfigService;

    @SneakyThrows
    @Bean
    public WxMpService wxMpService() {
        WxMpDefaultConfigImpl configStorage = new WxMpMapConfigImpl();
        configStorage.setAppId(properties.getAppId());
        configStorage.setSecret(properties.getSecret());
        configStorage.setUseStableAccessToken(true);

        WxMpService service = new WxMpServiceImpl();
        service.setWxMpConfigStorage(configStorage);
        String updateMenu = devConfigService.getValueByKey("wx_update_menu");
        if (Boolean.parseBoolean(updateMenu)) {
            //创建菜单
            service.getMenuService().menuCreate(wxMenuService.createMenu());
        }
        return service;
    }


    @Bean
    public WxMpMessageRouter wxMpMessageRouter() {
        WxMpMessageRouter router = new WxMpMessageRouter(wxMpService());

        // 关注事件
        router.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).event(WxConsts.EventType.SUBSCRIBE)
                .handler(new WxMpMessageHandler() {
                    @Override
                    public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
                        log.info("用户关注 {}", wxMessage);
                        AlarmUser alarmUser = alarmUserService.subscribe(wxMessage.getFromUser());
                        String msg;
                        //用户已授权
                        if (alarmUser != null && !Objects.equals("-1", alarmUser.getCreateOrg())) {
                            msg = devConfigService.getValueByKey("wx_authed_content");
                        } else {
                            msg = devConfigService.getValueByKey("wx_not_auth_content").replace("authUrl", wxMenuService.getAuthUrl());
                        }

                        return WxMpXmlOutMessage.TEXT()
                                .content(msg)
                                .fromUser(wxMessage.getToUser())
                                .toUser(wxMessage.getFromUser())
                                .build();
                    }
                })
                .end();

        // 取消关注事件
        router.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).event(WxConsts.EventType.UNSUBSCRIBE)
                .handler(new WxMpMessageHandler() {
                    @Override
                    public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) {
                        log.info("用户取消关注 {}", wxMessage);
                        alarmUserService.unsubscribe(wxMessage.getFromUser());
                        return null;
                    }
                })
                .end();

        // 点击菜单事件
        router.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).event(WxConsts.EventType.CLICK)
                .handler(new WxMpMessageHandler() {
                    @Override
                    public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) {
                        log.info("用户点击 {}", wxMessage);

                        //点击了关于我们
                        if (wxMessage.getEventKey().equals("aboutUs")) {
                            return WxMpXmlOutMessage.TEXT()
                                    .content(devConfigService.getValueByKey("wx_about_us"))
                                    .fromUser(wxMessage.getToUser())
                                    .toUser(wxMessage.getFromUser())
                                    .build();
                        }

                        return null;
                    }
                })
                .end();

        // 点击view事件
        router.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).event(WxConsts.EventType.VIEW)
                .handler(new WxMpMessageHandler() {
                    @Override
                    public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) {
                        log.info("用户打开view {}", wxMessage);
                        return null;
                    }
                })
                .end();

        // 发送文字事件
        router.rule().async(false).msgType(WxConsts.XmlMsgType.TEXT)
                .handler(new WxMpMessageHandler() {
                    @Override
                    public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) {
                        log.info("用户发送文字事件 {}", wxMessage);
                        log.info("用户[{}]发送了：{}", wxMessage.getFromUser(), wxMessage.getContent());
                        return null;
                    }
                })
                .end();

        return router;
    }
}
