package org.dromara.mp.service.impl;

import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutTextMessage;
import org.dromara.mp.service.WxMpMessageService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * 微信公众号消息处理服务实现类
 *
 * @author pengles
 */
@Service
public class WxMpMessageServiceImpl implements WxMpMessageService {

    private static final Logger logger = LoggerFactory.getLogger(WxMpMessageServiceImpl.class);

    // 自动回复关键词映射
    private static final Map<String, String> AUTO_REPLY_MAP = new HashMap<>();

    static {
        AUTO_REPLY_MAP.put("帮助", "您好！我是智能客服助手，可以为您提供以下服务：\n\n1. 输入\"联系客服\"获取人工客服\n2. 输入\"常见问题\"查看FAQ\n3. 输入\"产品介绍\"了解我们的产品\n4. 输入\"使用教程\"获取使用指南");
        AUTO_REPLY_MAP.put("联系客服", "客服工作时间：周一至周五 9:00-18:00\n\n如需人工客服，请拨打：400-123-4567\n或发送邮件至：service@example.com");
        AUTO_REPLY_MAP.put("常见问题", "常见问题：\n\n1. 如何注册账号？\n2. 忘记密码怎么办？\n3. 如何修改个人信息？\n4. 如何联系客服？\n\n更多问题请输入具体问题关键词。");
        AUTO_REPLY_MAP.put("产品介绍", "我们的产品特色：\n\n✅ 功能强大，操作简单\n✅ 安全可靠，数据保护\n✅ 7x24小时技术支持\n✅ 持续更新，免费升级\n\n了解更多请访问官网或联系客服。");
        AUTO_REPLY_MAP.put("使用教程", "使用教程：\n\n📖 新手入门指南\n📖 功能操作说明\n📖 常见问题解答\n📖 视频教程\n\n详细教程请访问帮助中心或联系客服获取。");
    }

    @Override
    public WxMpXmlOutMessage handleTextMessage(WxMpXmlMessage inMessage) {
        String content = inMessage.getContent();
        String openId = inMessage.getFromUser();

        logger.info("收到文本消息: openId={}, content={}", openId, content);

        // 保存用户消息
        saveUserMessage(inMessage);

        // 获取自动回复内容
        String replyContent = getAutoReplyContent(content, openId);

        // 构建回复消息
        WxMpXmlOutTextMessage outMessage = WxMpXmlOutMessage.TEXT()
                .content(replyContent)
                .fromUser(inMessage.getToUser())
                .toUser(openId)
                .build();

        // 保存回复消息
        saveReplyMessage(outMessage, openId);

        return outMessage;
    }

    @Override
    public WxMpXmlOutMessage handleImageMessage(WxMpXmlMessage inMessage) {
        String openId = inMessage.getFromUser();
        logger.info("收到图片消息: openId={}, mediaId={}", openId, inMessage.getMediaId());

        saveUserMessage(inMessage);

        String replyContent = "感谢您发送的图片！如需帮助，请输入\"帮助\"查看可用功能。";

        WxMpXmlOutTextMessage outMessage = WxMpXmlOutMessage.TEXT()
                .content(replyContent)
                .fromUser(inMessage.getToUser())
                .toUser(openId)
                .build();

        saveReplyMessage(outMessage, openId);
        return outMessage;
    }

    @Override
    public WxMpXmlOutMessage handleVoiceMessage(WxMpXmlMessage inMessage) {
        String openId = inMessage.getFromUser();
        logger.info("收到语音消息: openId={}, mediaId={}", openId, inMessage.getMediaId());

        saveUserMessage(inMessage);

        String replyContent = "收到您的语音消息！目前暂不支持语音识别，请发送文字消息或输入\"帮助\"查看可用功能。";

        WxMpXmlOutTextMessage outMessage = WxMpXmlOutMessage.TEXT()
                .content(replyContent)
                .fromUser(inMessage.getToUser())
                .toUser(openId)
                .build();

        saveReplyMessage(outMessage, openId);
        return outMessage;
    }

    @Override
    public WxMpXmlOutMessage handleVideoMessage(WxMpXmlMessage inMessage) {
        String openId = inMessage.getFromUser();
        logger.info("收到视频消息: openId={}, mediaId={}", openId, inMessage.getMediaId());

        saveUserMessage(inMessage);

        String replyContent = "感谢您发送的视频！如需帮助，请输入\"帮助\"查看可用功能。";

        WxMpXmlOutTextMessage outMessage = WxMpXmlOutMessage.TEXT()
                .content(replyContent)
                .fromUser(inMessage.getToUser())
                .toUser(openId)
                .build();

        saveReplyMessage(outMessage, openId);
        return outMessage;
    }

    @Override
    public WxMpXmlOutMessage handleLocationMessage(WxMpXmlMessage inMessage) {
        String openId = inMessage.getFromUser();
        logger.info("收到位置消息: openId={}, location=({}, {})",
                openId, inMessage.getLocationX(), inMessage.getLocationY());

        saveUserMessage(inMessage);

        String replyContent = String.format("收到您的位置信息：\n纬度：%s\n经度：%s\n\n如需基于位置的服务，请联系客服。",
                inMessage.getLocationX(), inMessage.getLocationY());

        WxMpXmlOutTextMessage outMessage = WxMpXmlOutMessage.TEXT()
                .content(replyContent)
                .fromUser(inMessage.getToUser())
                .toUser(openId)
                .build();

        saveReplyMessage(outMessage, openId);
        return outMessage;
    }

    @Override
    public WxMpXmlOutMessage handleLinkMessage(WxMpXmlMessage inMessage) {
        String openId = inMessage.getFromUser();
        logger.info("收到链接消息: openId={}, url={}", openId, inMessage.getUrl());

        saveUserMessage(inMessage);

        String replyContent = "感谢您分享的链接！如需帮助，请输入\"帮助\"查看可用功能。";

        WxMpXmlOutTextMessage outMessage = WxMpXmlOutMessage.TEXT()
                .content(replyContent)
                .fromUser(inMessage.getToUser())
                .toUser(openId)
                .build();

        saveReplyMessage(outMessage, openId);
        return outMessage;
    }

    @Override
    public WxMpXmlOutMessage handleEventMessage(WxMpXmlMessage inMessage) {
        String openId = inMessage.getFromUser();
        String event = inMessage.getEvent();

        logger.info("收到事件消息: openId={}, event={}", openId, event);

        String replyContent;

        switch (event) {
            case "subscribe":
                replyContent = handleSubscribeEvent(openId);
                break;
            case "unsubscribe":
                handleUnsubscribeEvent(openId);
                return null; // 取消关注不回复消息
            case "SCAN":
                replyContent = handleScanEvent(openId, inMessage.getEventKey());
                break;
            case "CLICK":
                replyContent = handleMenuClickEvent(inMessage.getEventKey());
                break;
            default:
                replyContent = getDefaultReplyContent();
                break;
        }

        if (replyContent != null) {
            WxMpXmlOutTextMessage outMessage = WxMpXmlOutMessage.TEXT()
                    .content(replyContent)
                    .fromUser(inMessage.getToUser())
                    .toUser(openId)
                    .build();

            saveReplyMessage(outMessage, openId);
            return outMessage;
        }

        return null;
    }

    @Override
    public String getAutoReplyContent(String keyword, String openId) {
        // 精确匹配
        if (AUTO_REPLY_MAP.containsKey(keyword)) {
            return AUTO_REPLY_MAP.get(keyword);
        }

        // 模糊匹配
        for (Map.Entry<String, String> entry : AUTO_REPLY_MAP.entrySet()) {
            if (keyword.contains(entry.getKey()) || entry.getKey().contains(keyword)) {
                return entry.getValue();
            }
        }

        // 默认回复
        return getDefaultReplyContent();
    }

    @Override
    public void saveUserMessage(WxMpXmlMessage inMessage) {
        // TODO: 保存用户消息到数据库
        logger.info("保存用户消息: openId={}, msgType={}, content={}",
                inMessage.getFromUser(), inMessage.getMsgType(), inMessage.getContent());
    }

    @Override
    public void saveReplyMessage(WxMpXmlOutMessage outMessage, String openId) {
        // TODO: 保存回复消息到数据库
        logger.info("保存回复消息: openId={}, content={}", openId, outMessage.getMsgSignature());
    }

    @Override
    public String getDefaultReplyContent() {
        return "您好！欢迎关注我们！\n\n输入\"帮助\"查看可用功能，或直接描述您的问题，我们会尽快为您解答。";
    }

    @Override
    public String handleSubscribeEvent(String openId) {
        logger.info("用户关注: openId={}", openId);

        String welcomeMessage = "🎉 欢迎关注我们！\n\n" +
                "感谢您的关注，我们将为您提供优质的服务。\n\n" +
                "💡 输入\"帮助\"查看可用功能\n" +
                "📞 输入\"联系客服\"获取人工服务\n" +
                "❓ 输入\"常见问题\"查看FAQ\n\n" +
                "有任何问题随时联系我们！";

        return welcomeMessage;
    }

    @Override
    public void handleUnsubscribeEvent(String openId) {
        logger.info("用户取消关注: openId={}", openId);
        // TODO: 更新用户关注状态
    }

    @Override
    public String handleScanEvent(String openId, String sceneStr) {
        logger.info("用户扫码: openId={}, sceneStr={}", openId, sceneStr);

        if (sceneStr.startsWith("invite_")) {
            String inviteUserId = sceneStr.substring(7);
            return String.format("感谢通过邀请码关注我们！\n邀请人ID：%s\n\n您已获得新用户专属福利，详情请联系客服。", inviteUserId);
        } else if (sceneStr.startsWith("activity_")) {
            String activityId = sceneStr.substring(9);
            return String.format("欢迎参与活动！\n活动ID：%s\n\n活动详情和参与方式请联系客服了解。", activityId);
        } else if (sceneStr.startsWith("channel_")) {
            String channelId = sceneStr.substring(8);
            return String.format("欢迎通过渠道关注我们！\n渠道ID：%s\n\n感谢您的关注，有任何问题请随时联系。", channelId);
        }

        return "感谢扫码关注我们！如需帮助，请输入\"帮助\"查看可用功能。";
    }

    /**
     * 处理菜单点击事件
     *
     * @param eventKey 事件key
     * @return 回复内容
     */
    private String handleMenuClickEvent(String eventKey) {
        switch (eventKey) {
            case "ABOUT_US":
                return "关于我们\n\n我们是一家专注于为用户提供优质服务的公司，致力于通过技术创新改善用户体验。";
            case "ONLINE_SERVICE":
                return "在线客服\n\n客服工作时间：周一至周五 9:00-18:00\n\n请直接描述您的问题，我们会尽快回复。";
            case "FAQ":
                return AUTO_REPLY_MAP.get("常见问题");
            case "CONTACT_US":
                return AUTO_REPLY_MAP.get("联系客服");
            default:
                return getDefaultReplyContent();
        }
    }
}