package com.cftech.mp.reply.service;

import com.cftech.accounts.model.MpAccountsEntity;
import com.cftech.accounts.service.MpAccountsService;
import com.cftech.base.org.model.OrgUnit;
import com.cftech.base.org.model.Qyuser;
import com.cftech.base.org.service.OrgUnitService;
import com.cftech.base.org.service.QyuserService;
import com.cftech.behavior.qrcode.record.model.QrcodeRecord;
import com.cftech.behavior.qrcode.record.service.QrcodeRecordService;
import com.cftech.cms.cfarticle.model.Cfarticle;
import com.cftech.cms.cfarticle.service.CfarticleService;
import com.cftech.cms.exhibi.model.Exhibi;
import com.cftech.cms.exhibi.service.ExhibiService;
import com.cftech.core.sql.Conds;
import com.cftech.core.util.Constants;
import com.cftech.core.util.MpTokenUtil;
import com.cftech.core.util.StringUtils;
import com.cftech.core.util.SystemConfig;
import com.cftech.mp.article.model.MpArticle;
import com.cftech.mp.article.service.ArticleService;
import com.cftech.mp.fans.model.MpFanssEntity;
import com.cftech.mp.fans.service.MpFanssService;
import com.cftech.mp.reply.model.Reply;
import com.cftech.mp.wechat.model.Menu;
import com.cftech.mp.wechat.service.MenuService;
import com.cftech.shop.qrcode.model.WxQrcode;
import com.cftech.shop.qrcode.service.WxQrcodeService;
import com.cftech.workshop.meeting.model.Meeting;
import com.cftech.workshop.meeting.service.MeetingService;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.mp.api.core.common.util.MessageUtil;
import org.mp.api.core.exception.WexinReqException;
import org.mp.api.wxsendmsg.model.Article;
import org.mp.api.wxsendmsg.model.ResBaseMessage;
import org.mp.api.wxsendmsg.model.ResNewsMessage;
import org.mp.api.wxsendmsg.model.ResTextMessage;
import org.mp.api.wxuser.user.JwUserAPI;
import org.mp.api.wxuser.user.model.Wxuser;
import org.owasp.esapi.ESAPI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.TextQuery;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 核心服务类
 */

/**
 * @author lisw
 * @date 2016年9月22日 下午2:31:52
 */
@Component
public class CoreService {

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

    private static final String appid = SystemConfig.p.getProperty("WX_MP_SERVER_APPID");

    @Autowired
    private MpAccountsService mpAccountsService;

    @Autowired
    private MenuService menuServices;

    @Autowired
    private ArticleService articleService;


    private HttpServletRequest requests;

    @Autowired
    private ReplyService replyService;

    @Autowired
    private CfarticleService cfarticleService;

//    @Autowired
//    private CardRecordService cardRecordService;
//
//    @Autowired
//    private CardService cardService;
//
//
//    @Autowired
//    private StoreService storeService;

    @Autowired
    private QrcodeRecordService qrcodeRecordService;

    @Autowired
    private MpFanssService mpFanssService;

    @Autowired
    private MpTokenUtil mpTokenUtil;

    private String domain = SystemConfig.p.getProperty("QY_DOMAIN");

    private String qyDomain = SystemConfig.p.getProperty("QY_DOMAIN");

    private MpAccountsEntity mpAccountEntity = null;


    @Autowired
    private WxQrcodeService wxQrcodeService;
//
//    @Autowired
//    private CarStoreService carStoreService;

    @Autowired
    private QyuserService qyuserService;

    @Autowired
    private MeetingService meetingService;

    @Autowired
    private ExhibiService exhibiService;

    /**
     * 拦截的请求处理返回消息信息
     *
     * @param request
     * @return update mubo 2017.04.09(修改消费者服务号部署回调客服)
     */
    public String processRequest(String appid, Map<String, String> requestMap,
                                 HttpServletRequest request) {
        requests = request;
        StringBuffer url = request.getRequestURL();
        domain = url.delete(url.length() - request.getRequestURI().length(), url.length()).append("/").toString();
        logger.info("请求的链接:" + url + "; Domain:" + domain);

        try {
            // 发送方帐号（open_id）
            String fromUserName = requestMap.get("FromUserName");
            // 公众帐号
            String toUserName = requestMap.get("ToUserName");
            // 消息类型
            String msgType = requestMap.get("MsgType");
            mpAccountEntity = mpAccountsService.getMpAccountsAppid(appid);
            if (mpAccountEntity == null) {
                return "";
            }
            // 文本消息 tx太繁忙规划法
            //@李士伟 客服消息转发前还是要有自动回复，而且希望根据时间回复不同内容。8:30-16:30回复“您好，
            // 很高兴为您服务！”，其他时间段回复“非常抱歉哦~我们客服服务时间段是08：30-16：30哦~有需要请08：30之后在线咨询哦~或者是拨打全国服务热线4008288988/95105910咨询哦
            if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) {//文字消息进行关键字回复
//                String content = requestMap.get("Content");
//                return replyMessage(fromUserName, toUserName, content, "keyword");
                return "";
            }
            // 图片消息
            else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)) {
                return "";
            }
            // 地理位置消息
            else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION)) {
                return "";
            }
            // 链接消息
            else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LINK)) {
                return "";
            }
            // 音频消息
            else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)) {
                return "";
            }
            // 事件推送
            else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)) {
                logger.info(requestMap.toString());
                // 事件类型
                String eventType = requestMap.get("Event");
                String eventKey = requestMap.get("EventKey");
                String ticket = requestMap.get("Ticket");
                // 关注
                if (eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) {// 普通关注
                    if (eventKey != null && eventKey.contains("qrscene")) {// 二维码关注
                        return createQrcodeRecord(fromUserName, toUserName, eventKey, fromUserName, ticket, eventType);
                    } else {
                        insertFanss(fromUserName, "0", null, null);
                        return replyMessage(fromUserName, toUserName, null, "subscribe");
                    }

                } else if (eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)) {// 取消关注
                    mpFanssService.deleteByOpenId(fromUserName);
                    return "";
                } else if (eventType.equals(MessageUtil.EVENT_TYPE_CLICK)) {// 自定义菜单点击事件
//                    Menu menu = menuServices.fetchById(eventKey);
//                    if (StringUtils.equals(menu.getMsgType(), "1")) {
//                        String content = MessageUtil.textMessageToXml(text(fromUserName, toUserName, menu.getSourceContent()));
//                        return content;
//                    } else if (StringUtils.equals(menu.getMsgType(), "2")) {
//                        return MessageUtil.newsMessageToXml(news(fromUserName, toUserName, menu.getSourceContent()));
//                    } else if (StringUtils.equals(menu.getMsgType(), "3")) {
//                        return MessageUtil.newsMessageToXml(localNews(fromUserName, toUserName, menu.getSourceContent()));
//                    }
                } else if (eventType.equals(MessageUtil.EVENT_TYPE_USER_GET_CARD)) {//用户领取卡券
                } else if (eventType.equals(MessageUtil.EVENT_TYPE_USER_GIFTING_CARD)) {//用户转赠卡券
                } else if (eventType.equals(MessageUtil.EVENT_TYPE_USER_CONSUME_CARD)) {//核销卡券
                } else if (eventType.equals(MessageUtil.EVENT_TYPE_ADD_STORE_AUDIT_INFO)) {//添加门店审核
                } else if (eventType.equals(MessageUtil.EVENT_TYPE_MODIFY_STORE_AUDIT_INFO)) {//修改门店审核
                } else if (eventType.equals(MessageUtil.EVENT_TYPE_SCAN)) {//扫码
                    return createQrcodeRecord(fromUserName, toUserName, eventKey, fromUserName, ticket, eventType);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }


    /**
     * /**
     * 回复消息
     * reply  subscribe关注  keyword关键字
     */
    public String replyMessage(String fromUserName, String toUserName,
                               String content, String replyType) {
        if (replyType.equals("subscribe")) {//关注回复
            //查询关注回复的内容
//            insertFanss(fromUserName, "0",null, null);
            Conds conds = new Conds();
            conds.equal("delflag", 0);
            conds.equal("accountsid", mpAccountEntity.getId());
            conds.equal("send_type", "subscribe");
            Reply reply = replyService.fetchSearchByConds(conds);
            if (reply != null) {
                if (reply.getReplyType().equals("text")) {//回复文本
                    return MessageUtil.textMessageToXml(text(fromUserName, toUserName, reply.getContentSource()));
                } else if (reply.getReplyType().equals("news")) {//回复微信图文
                    return MessageUtil.newsMessageToXml(news(fromUserName, toUserName, reply.getContentSource()));
                } else if (reply.getReplyType().equals("article")) {//回复文章
                    return MessageUtil.newsMessageToXml(localNews(fromUserName, toUserName, reply.getContentSource()));
                }
            }
        } else if (replyType.equals("keyword")) {
//            List<Reply> replyList = replyService.fetchkeywordByPage(content, mpAccountEntity.getId(), "keyword");
//            if (replyList != null && replyList.size() > 0) {
//                Reply reply = replyList.get(0);
//                if (reply.getReplyType().equals("text")) {//回复文本
//                    return MessageUtil.textMessageToXml(text(fromUserName, toUserName, reply.getContentSource()));
//                } else if (reply.getReplyType().equals("news")) {//回复微信图文
//                    return MessageUtil.newsMessageToXml(news(fromUserName, toUserName, reply.getContentSource()));
//                } else if (reply.getReplyType().equals("article")) {//回复文章
//                    return MessageUtil.newsMessageToXml(localNews(fromUserName, toUserName, reply.getContentSource()));
//                }
//            } else {//没有匹配到关键字，接入到客服
//                return MessageUtil.customerServiceMessageToXml(resBaseMessage(fromUserName, toUserName));
//            }
        } else {

        }
        return "";
    }

    /**
     * 消息转发到多客服
     */
    public ResBaseMessage resBaseMessage(String fromUserName, String toUserName) {
        ResTextMessage textMessage = new ResTextMessage();
        textMessage.setToUserName(fromUserName);
        textMessage.setFromUserName(toUserName);
        textMessage.setCreateTime(System.currentTimeMillis());
        textMessage.setMsgType(MessageUtil.TRANSFER_CUSTOMER_SERVICE);
        textMessage.setFuncFlag(0);
        return textMessage;
    }


    /**
     * 返回单条固定图文信息
     */
    public ResNewsMessage newsinfo(String fromUserName, String toUserName,
                                   Article article) {
        ResNewsMessage newsMessage = new ResNewsMessage();
        newsMessage.setToUserName(fromUserName);
        newsMessage.setFromUserName(toUserName);
        newsMessage.setCreateTime(System.currentTimeMillis());
        newsMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_NEWS);
        newsMessage.setArticleCount(1);
        List<Article> articles = new ArrayList<Article>();
        articles.add(article);
        newsMessage.setArticles(articles);
        return newsMessage;
    }

    /**
     * 返回文章图文方法
     */
    public ResNewsMessage localNews(String fromUserName, String toUserName,
                                    String content) {
        List<Article> articleList = new ArrayList<Article>();
        Conds conds = new Conds();
        conds.equal("t.del_flag", Constants.DEL_FLAG_0);
        conds.equal("t.accounts_id", mpAccountEntity.getId());
        if (StringUtils.equals(content.substring(content.length() - 1), ",")) {
            content = content.substring(0, content.length() - 1);
        }
        conds.in("t.id", content.split(","));
        List<Cfarticle> list = cfarticleService.fetchSearchByPageInOrder(conds, content);
        if (list != null) {
            ResNewsMessage newsMessage = new ResNewsMessage();
            newsMessage.setToUserName(fromUserName);
            newsMessage.setFromUserName(toUserName);
            newsMessage.setCreateTime(System.currentTimeMillis());
            newsMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_NEWS);
            newsMessage.setArticleCount(list.size());
            int i = 0;
            for (Cfarticle cfarticle : list) {
                Article art = new Article();
                art.setDescription(cfarticle.getDesc());
                if (!cfarticle.getBigimg().startsWith("http")) {
                    cfarticle.setBigimg(domain + cfarticle.getBigimg());
                }
                if (!cfarticle.getSmallimg().startsWith("http")) {
                    cfarticle.setSmallimg(domain + cfarticle.getSmallimg());
                }
                if (i == 0) {
                    art.setPicUrl(cfarticle.getBigimg());
                } else {
                    art.setPicUrl(cfarticle.getSmallimg());
                }
                art.setTitle(cfarticle.getTitle());
                if (cfarticle.getIsUrl() == '0') {
                    art.setUrl(cfarticle.getContentSourceUrl());
                } else {
                    String articleDetailUrl = "";
                    if (cfarticle.getType().equals("0")) {//普通文章详情
                        articleDetailUrl = SystemConfig.p.get("ARTICLEDETAILURL").toString();
                    } else {//图集文章详情
                        articleDetailUrl = SystemConfig.p.get("ARTICLEDETAILPICURL").toString();
                    }
                    String url = articleDetailUrl.replace("{APPID}", mpAccountEntity.getAppid()).replace("{ID}", cfarticle.getId().toString());
                    art.setUrl(url);
                }
                articleList.add(art);
                i++;
            }
            newsMessage.setArticles(articleList);
            return newsMessage;
        } else {
            return null;
        }
    }

    /**
     * 返回微信图文素材方法
     */
    public ResNewsMessage news(String fromUserName, String toUserName,
                               String content) {
        List<Article> articleList = new ArrayList<Article>();
        //通过menuId找到需要返回的素材相关信息
        Conds mpArticleConds = new Conds();
        mpArticleConds.equal("del_flag", 0);
        mpArticleConds.equal("accounts_id", mpAccountEntity.getId());
        mpArticleConds.equal("media_id", content);
        MpArticle article = articleService.fetchSearchByConds(mpArticleConds);
        if (article != null) {
            JSONArray array = JSONArray.fromObject(article.getNews_item());
            ResNewsMessage newsMessage = new ResNewsMessage();
            newsMessage.setToUserName(fromUserName);
            newsMessage.setFromUserName(toUserName);
            newsMessage.setCreateTime(System.currentTimeMillis());
            newsMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_NEWS);
            newsMessage.setArticleCount(array.size());
            for (int i = 0; i < array.size(); i++) {
                JSONObject object = array.getJSONObject(i);
                Article art = new Article();
                art.setDescription(object.getString("digest"));
                art.setPicUrl(object.getString("thumb_url"));
                art.setTitle(object.getString("title"));
                art.setUrl(object.getString("url"));
                articleList.add(art);
            }
            newsMessage.setArticles(articleList);
            return newsMessage;
        } else {
            return null;
        }

    }

    /**
     * 返回文本消息
     */
    public ResTextMessage text(String fromUserName, String toUserName,
                               String content) {
        ResTextMessage textMessage = new ResTextMessage();
        textMessage.setToUserName(fromUserName);
        textMessage.setFromUserName(toUserName);
        content = ESAPI.encoder().decodeForHTML(content);
        textMessage.setContent(content.replace("<br/>", "\n"));
        textMessage.setCreateTime(System.currentTimeMillis());
        textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);
        textMessage.setFuncFlag(0);
        return textMessage;
    }

    /**
     * 更新粉丝来源,无则插入
     */
    public void updateFanssSource(String openid,String bindId,String ticket,String wxQrcodeType){
        MpFanssEntity fans = mpFanssService.getWxUser(openid);
        if(StringUtils.equals(wxQrcodeType,"1")){//药师二维码
            wxQrcodeType = "1";
        } else if(StringUtils.equals(wxQrcodeType,"2")){//客服二维码
            wxQrcodeType = "2";
        } else if(StringUtils.equals(wxQrcodeType,"3")){//医生二维码
            wxQrcodeType = "3";
        } else if(StringUtils.equals(wxQrcodeType,"4")){//组织二维码
            wxQrcodeType = "4";
        }
        if (fans != null) {
            MpFanssEntity realFans = new MpFanssEntity();
            realFans.setId(fans.getId());
            realFans.setOpenid(openid);
            realFans.setRecommender(bindId);
            realFans.setStatus(ticket);
            realFans.setSource(wxQrcodeType);
            mpFanssService.updateByOpenId(realFans);
        } else {
            insertFanss(openid, wxQrcodeType, String.valueOf(bindId), ticket);
        }
    }


    /**
     * 生成门店扫码记录
     */
    public String createQrcodeRecord(String fromUserName, String toUserName, String evenkey, String openid,
                                     String ticket, String event) {

        String returnMsg = "";
        QrcodeRecord qrcodeRecord = new QrcodeRecord();
        Long accountsid = mpAccountEntity.getId();
        qrcodeRecord.setAccountsId(accountsid);
        qrcodeRecord.setOpenid(openid);
        qrcodeRecord.setTicket(ticket);
        Conds wxQrcodeConds = new Conds();
        wxQrcodeConds.equal("t.del_flag", "0");
        wxQrcodeConds.equal("t.ticket", ticket);
        WxQrcode wxQrcode = wxQrcodeService.fetchSearchByConds(wxQrcodeConds);
        if (wxQrcode != null) {
            Long bindId = wxQrcode.getBindId();
            String wxQrcodeType = wxQrcode.getType();
            qrcodeRecord.setType(wxQrcodeType);
            if (bindId!=null){
                qrcodeRecord.setKeywords(String.valueOf(bindId));
            }
            qrcodeRecordService.save(qrcodeRecord);
            if (event.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) {
                updateFanssSource(fromUserName, String.valueOf(bindId), ticket, wxQrcodeType);
                return rtnMessage(wxQrcodeType, fromUserName, toUserName, bindId);
            } else {
                return rtnMessage(wxQrcodeType, fromUserName, toUserName, bindId);
            }
        } else {
            logger.info("未知的二维码来源,ticket,openid:" + ticket + "," + openid);
            if (event.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) {
                insertFanss(fromUserName, "0", null, null);
                returnMsg = replyMessage(fromUserName, toUserName, null, "subscribe");
            }
        }
        return returnMsg;
    }

    /**
     * 固定场景二维码图文拼装
     */
    private String rtnMessage(String source, String fromUserName, String toUserName, Long bindId) {
        //研讨会
        if (StringUtils.equals(source, "meeting")) {
            Meeting meeting = meetingService.fetchById(bindId);
            if (!meeting.getWxCover().startsWith("http") && !meeting.getWxCover().startsWith("https")) {
                meeting.setWxCover(qyDomain + meeting.getWxCover());
            }
            Article article = new Article();
            article.setTitle("活动报名 | " + meeting.getTitle());
            article.setPicUrl(meeting.getWxCover());
            article.setUrl(qyDomain + "/aidea/static/mp/aidea/meeting-intro.html?appid=" + appid + "&id=" + meeting.getId());
            return MessageUtil.newsMessageToXml(newsinfo(fromUserName, toUserName, article));
            //展会
        } else if (StringUtils.equals(source, "exhibi")) {
            Exhibi exhibi = exhibiService.fetchById(bindId);
            if (!exhibi.getExhibi_cover().startsWith("http") && !exhibi.getExhibi_cover().startsWith("https")) {
                exhibi.setExhibi_cover(qyDomain + exhibi.getExhibi_cover());
            }
            Article article = new Article();
            article.setTitle("展会 | " + exhibi.getExhibi_title());
            article.setPicUrl(exhibi.getExhibi_cover());
            article.setUrl(qyDomain + "/aidea/static/mp/aidea/exhibition.html?appid=" + appid + "&id=" + exhibi.getId());
            return MessageUtil.newsMessageToXml(newsinfo(fromUserName, toUserName, article));
            //展厅申请
        } else if (StringUtils.equals(source, "exhibiApp")) {
            String cover = qyDomain+"/aidea/static/mp/aidea/image/process/showroomcover.jpg";

            Article article = new Article();
            article.setTitle("欢迎预约舍弗勒安亭展厅Showroom Booking Platform");
            article.setPicUrl(cover);
            article.setUrl(qyDomain + "/aidea/static/mp/aidea/process/video.html?appid=" + appid);
            return MessageUtil.newsMessageToXml(newsinfo(fromUserName, toUserName, article));
        } else if(StringUtils.equals(source,"typeform")){
            String cover = qyDomain+"/aidea/static/mp/aidea/image/process/itemscover.jpg";
            Article article = new Article();
            article.setTitle("欢迎申请舍弗勒促销品！");
            article.setPicUrl(cover);
            article.setUrl(qyDomain + "/aidea/static/mp/aidea/process/commonagreement.html?appid=" + appid+"&typeformId="+bindId);
            return MessageUtil.newsMessageToXml(newsinfo(fromUserName, toUserName, article));
        } else if(StringUtils.equals(source,"supplierlist")){
            String cover = qyDomain+"/aidea/static/mp/aidea/image/supplier.jpg";
            Article article = new Article();
            article.setTitle("产品购买｜点击查询舍弗勒大中华区工业事业部授权经销商");
            article.setPicUrl(cover);
            article.setUrl(qyDomain + "/aidea/static/mp/aidea/dealerList.html?appid=" + appid);
            return MessageUtil.newsMessageToXml(newsinfo(fromUserName, toUserName, article));
        }else if(StringUtils.equals(source,"brandApply")){
            String cover = qyDomain+"/aidea/static/mp/aidea/image/process/itemscover.jpg";
            Article article = new Article();
            article.setTitle("欢迎申请品牌服务！");
            article.setPicUrl(cover);
            article.setUrl(qyDomain + "/aidea/static/mp/aidea/wx-brand-agreement.html?appid=" + appid);
            return MessageUtil.newsMessageToXml(newsinfo(fromUserName, toUserName, article));
        } else {
            return replyMessage(fromUserName, toUserName, null, "subscribe");
        }
    }


    /**
     * @param openId :粉丝OPENID
     * @param type   :粉丝来源
     *               :推荐人可为空
     * @param store  :门店 可为空
     * @param ticket :二维码ticket可为空
     */
    public void insertFanss(String openId, String type,
                            String store, String ticket) {
        MpFanssEntity fannsEntity = new MpFanssEntity();
        try {
            Wxuser user = JwUserAPI.getWxuser(mpTokenUtil.getToken(mpAccountEntity.getId()),
                    openId);
            fannsEntity.setHeadimgurl(user.getHeadimgurl());
            fannsEntity.setCity(user.getCity());
            fannsEntity.setProvince(user.getProvince());
            fannsEntity.setNickname(user.getNickname());
            fannsEntity.setMpaccountid(mpAccountEntity.getId());
            fannsEntity.setOpenid(user.getOpenid());
            fannsEntity.setSex(user.getSex());
            fannsEntity.setSource(type);
            fannsEntity.setRecommender(store);
            fannsEntity.setStatus(ticket);
            fannsEntity.setSubscribetime(new Date(Long.parseLong(user.getSubscribe_time()) * 1000));
            fannsEntity.setUnionid(user.getUnionid());
            String tags = "";
            if (user.getTagid_list() != null && user.getTagid_list().size() > 0) {
                tags = StringUtils.join(user.getTagid_list(), ",") + ",";
            }
            fannsEntity.setTaglist(tags);
            mpFanssService.insert(fannsEntity);
        } catch (WexinReqException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}
