package com.tzld.piaoquan.api.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.tzld.piaoquan.api.common.enums.ExceptionEnum;
import com.tzld.piaoquan.api.common.enums.ReplyStrategyServiceEnum;
import com.tzld.piaoquan.api.common.exception.CommonException;
import com.tzld.piaoquan.api.component.TouLiuHttpClient;
import com.tzld.piaoquan.api.dao.mapper.GhDetailExtMapper;
import com.tzld.piaoquan.api.model.bo.*;
import com.tzld.piaoquan.api.model.po.GhDetailExt;
import com.tzld.piaoquan.api.model.po.GhDetailExtExample;
import com.tzld.piaoquan.api.model.vo.VideoCharacteristicVO;
import com.tzld.piaoquan.api.service.CgiReplyService;
import com.tzld.piaoquan.api.service.GhDetailService;
import com.tzld.piaoquan.api.service.VideoMultiService;
import com.tzld.piaoquan.api.service.strategy.ReplyStrategyService;
import com.tzld.piaoquan.growth.common.common.enums.GhTypeEnum;
import com.tzld.piaoquan.growth.common.dao.mapper.CgiReplyBucketDataMapper;
import com.tzld.piaoquan.growth.common.dao.mapper.GhDetailMapper;
import com.tzld.piaoquan.growth.common.model.po.CgiReplyBucketData;
import com.tzld.piaoquan.growth.common.model.po.CgiReplyBucketDataExample;
import com.tzld.piaoquan.growth.common.model.po.GhDetail;
import com.tzld.piaoquan.growth.common.model.po.GhDetailExample;
import com.tzld.piaoquan.growth.common.utils.MessageUtil;
import com.tzld.piaoquan.growth.common.utils.RedisUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import java.util.*;

@Service
public class CgiReplyServiceImpl implements CgiReplyService {

    @Autowired
    private ApplicationContext applicationContext;

    private Map<String, ReplyStrategyService> strategyServiceMap;

    @Autowired
    private GhDetailMapper ghDetailMapper;

    @Autowired
    private GhDetailExtMapper ghDetailExtMapper;

    @Autowired
    private CgiReplyBucketDataMapper cgiReplyBucketDataMapper;

    @Autowired
    GhDetailService ghDetailService;

    @Autowired
    private TouLiuHttpClient touLiuHttpClient;

    @Autowired
    private VideoMultiService videoMultiService;

    @Autowired
    private RedisUtils redisUtils;

    @Value("${rootSourceConfig:{}}")
    private String rootSourceConfig;
    @Value("${small_page_url}")
    private String GET_SMALL_PAGE_URL;
    private static final String SMALL_APP_Id = "wxbdd2a2e93d9a6e25";

    @PostConstruct
    public void init() {
        strategyServiceMap = applicationContext.getBeansOfType(ReplyStrategyService.class);
    }


    @Override
    public ReplyBucketData getRgiReplyData(BucketDataParam bucketDataParam) {
        String ghId = bucketDataParam.getGhId();
        GhDetailExample example = new GhDetailExample();
        example.createCriteria().andGhIdEqualTo(ghId).andIsDeleteEqualTo(0);
        List<GhDetail> ghDetails = ghDetailMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(ghDetails)) {
            //LarkRobotUtil.sendMessage("公众号信息查询失败 ghId=" + ghId);
            return null;
        }
        GhDetail ghDetail = ghDetails.get(0);
        bucketDataParam.setStrategyStatus(ghDetail.getStrategyStatus());
        bucketDataParam.setRate(ghDetail.getRate());
        bucketDataParam.setContentDetail(ghDetail.getContentDetail());
        if (StringUtils.isNotEmpty(ghDetail.getVideoIds())) {
            bucketDataParam.setVideos(JSONArray.parseArray(ghDetail.getVideoIds(), Long.class));
        }
        GhDetailExtExample extExample = new GhDetailExtExample();
        extExample.createCriteria().andGhDetailIdEqualTo(ghDetail.getId()).andIsDeleteEqualTo(0);
        List<GhDetailExt> ghDetailExts = ghDetailExtMapper.selectByExample(extExample);
        if (!CollectionUtils.isEmpty(ghDetailExts)) {
            bucketDataParam.setMiniPageDatas(ghDetailExts.stream().sorted(Comparator.comparing(GhDetailExt::getSort)).map(ext -> {
                MiniPageData miniPageData = new MiniPageData();
                miniPageData.setPage(ext.getPage());
                miniPageData.setTitle(ext.getTitle());
                miniPageData.setCover(ext.getCover());
                return miniPageData;
            }).collect(java.util.stream.Collectors.toList()));
        }

        if (Objects.equals(ghDetail.getType(), GhTypeEnum.THIRD_PARTY_GH.type)) {
            bucketDataParam.setChannel(ghDetail.getChannel());
            return getPushMessageData(bucketDataParam);
        }
        return getRgiBucketData(bucketDataParam);
    }

    private ReplyBucketData getRgiBucketData(BucketDataParam bucketDataParam) {
        for (Map.Entry<String, ReplyStrategyService> stringReplyStrategyServiceEntry : strategyServiceMap.entrySet()) {
            ReplyStrategyService replyStrategyService = stringReplyStrategyServiceEntry.getValue();
            // 使用策略层
            if (replyStrategyService.support(ReplyStrategyServiceEnum.BUCKET_STRATEGY_V1)) {
                return replyStrategyService.getResult(bucketDataParam);
            }
        }
        // 无执行策略 不会走到这里
        return null;
    }

    private ReplyBucketData getPushMessageData(BucketDataParam bucketDataParam) {
        for (Map.Entry<String, ReplyStrategyService> stringReplyStrategyServiceEntry : strategyServiceMap.entrySet()) {
            ReplyStrategyService replyStrategyService = stringReplyStrategyServiceEntry.getValue();
            // 使用策略层
            if (replyStrategyService.support(ReplyStrategyServiceEnum.THIRD_PARTY_PUSH_MESSAGE_STRATEGY_V1)) {
                return replyStrategyService.getResult(bucketDataParam);
            }
        }
        // 无执行策略 不会走到这里
        return null;
    }

    @Override
    public List<CgiReplyBucketData> getCgiReplyBucketDataListByGhId(String ghId, String strategy) {
        CgiReplyBucketDataExample example = new CgiReplyBucketDataExample();
        example.createCriteria().andGhIdEqualTo(ghId).andStrategyEqualTo(strategy).andIsDeleteEqualTo(0);
        return cgiReplyBucketDataMapper.selectByExample(example);
    }

    @Override
    public List<CgiReplyBucketData> getCgiReplyBucketDataListByGhIds(List<String> ghIds, String strategy) {
        CgiReplyBucketDataExample example = new CgiReplyBucketDataExample();
        example.createCriteria().andGhIdIn(ghIds).andStrategyEqualTo(strategy).andIsDeleteEqualTo(0);
        return cgiReplyBucketDataMapper.selectByExample(example);
    }

    @Override
    public List<CgiReplyBucketData> getCgiReplyBucketDataListByVideoId(Long videoId) {
        CgiReplyBucketDataExample example = new CgiReplyBucketDataExample();
        example.createCriteria().andMiniVideoIdEqualTo(videoId).andIsDeleteEqualTo(0);
        return cgiReplyBucketDataMapper.selectByExample(example);
    }

    @Override
    public List<CgiReplyBucketData> getCgiReplyBucketDataListByGhIdVideoId(String ghId, List<Long> videoIds, String strategy) {
        CgiReplyBucketDataExample example = new CgiReplyBucketDataExample();
        example.createCriteria().andGhIdEqualTo(ghId).andMiniVideoIdIn(videoIds)
                .andStrategyEqualTo(strategy).andIsDeleteEqualTo(0);
        return cgiReplyBucketDataMapper.selectByExample(example);
    }

    @Override
    public List<CgiReplyBucketData> getCgiReplyBucketDataListByRootSourceId(String rootSourceId) {
        CgiReplyBucketDataExample example = new CgiReplyBucketDataExample();
        example.createCriteria().andRootSourceIdEqualTo(rootSourceId);
        return cgiReplyBucketDataMapper.selectByExample(example);
    }

    @Override
    public VideoCharacteristicVO getVideoCharacteristicByRootSourceId(String rootSourceId) {
        if (!rootSourceId.startsWith("dyyjs")) {
            throw new CommonException(ExceptionEnum.CGI_REPLY_BUCKET_DATA_NOT_AUTO_REPLY);
        }
        String redisKey = "auto_reply_video_detail_" + rootSourceId;
        String value = redisUtils.get(redisKey);
        if (StringUtils.isNotEmpty(value)) {
            return JSONObject.parseObject(value, VideoCharacteristicVO.class);
        }
        String blackListKey = "auto_reply_video_detail_black_list_" + rootSourceId;
        String blackListValue = redisUtils.get(blackListKey);
        if (StringUtils.isNotEmpty(blackListValue)) {
            throw new CommonException(ExceptionEnum.CGI_REPLY_BUCKET_DATA_NOT_FOUND);
        }
        List<CgiReplyBucketData> list = getCgiReplyBucketDataListByRootSourceId(rootSourceId);
        if (CollectionUtils.isEmpty(list)) {
            redisUtils.set(blackListKey, "1", 60 * 60);
            throw new CommonException(ExceptionEnum.CGI_REPLY_BUCKET_DATA_NOT_FOUND);
        }
        list.sort(Comparator.comparing(CgiReplyBucketData::getCreateTime).reversed());
        CgiReplyBucketData cgiReplyBucketData = list.get(0);
        GhDetail ghDetail = ghDetailService.getGhDetailByGhId(cgiReplyBucketData.getGhId());
        VideoCharacteristicVO vo = new VideoCharacteristicVO();
        vo.setGhId(cgiReplyBucketData.getGhId());
        vo.setName(ghDetail.getGhName());
        vo.setVideoId(cgiReplyBucketData.getMiniVideoId());
        vo.setTitle(cgiReplyBucketData.getTitle());
        vo.setCover(cgiReplyBucketData.getCoverUrl());
        redisUtils.set(redisKey, JSONObject.toJSONString(vo), 3L * 24 * 60 * 60);
        return vo;
    }

    @Override
    public MsgData bucketDataGenerate(bucketDataGenerateParam param) {
        String putScene = param.getPutScene();
        String channel = param.getChannel();
        String ghId = param.getGhId();
        JSONObject rootSourceConfigs = JSON.parseObject(rootSourceConfig);
        JSONObject jsonObject = rootSourceConfigs.getJSONObject(ghId);
        if (jsonObject != null) {
            if (StringUtils.isNotEmpty(jsonObject.getString("putScene"))) {
                putScene = jsonObject.getString("putScene");
            }
            if (StringUtils.isNotEmpty(jsonObject.getString("channel"))) {
                channel = jsonObject.getString("channel");
            }
        }
        // 创建投流路径
        String response = touLiuHttpClient.sendAdFlowAddRequest(GET_SMALL_PAGE_URL, String.valueOf(param.getVideoId()),
                putScene, channel, "自动", "公众号", "自动回复小程序", "位置1", ghId, null);
        // 获取视频详情
        Map<Long, VideoDetail> videoDetailMap = touLiuHttpClient.getVideoDetailRequest(Collections.singletonList(param.getVideoId()));
        JSONObject responseJSON = JSON.parseObject(response);
        if (responseJSON.getInteger("code").equals(0)) {
            SmallPageUrlDetail smallPageUrlDetail = responseJSON.getObject("data", SmallPageUrlDetail.class);
            // cgi_reply_bucket_data
            CgiReplyBucketData item = new CgiReplyBucketData();
            item.setStrategy("manual");
            item.setSort(1);
            item.setBatchSort(1);
            item.setGhId(ghId);
            item.setMsgType(1);
            item.setTitle(param.getTitle());
            // 处理coverUrl
            String coverUrl = spliceCoverUrl(param.getVideoId(), param.getCoverUrl(), videoDetailMap);
            item.setCoverUrl(coverUrl);
            item.setMiniAppId(SMALL_APP_Id);
            String miniPagePath = smallPageUrlDetail.getUrl();
            miniPagePath = videoMultiService.setVideoMultiTitleCoverPagePath(param.getVideoId(), miniPagePath, param.getTitle(), item.getCoverUrl());
            item.setMiniPagePath(miniPagePath);
            item.setMiniVideoId(param.getVideoId());
            item.setRootSourceId(MessageUtil.getRootSourceId(item.getMiniPagePath()));
            item.setPagePathUrlId(smallPageUrlDetail.getId());
            item.setIsDelete(1);
            item.setCreateTime(new Date());
            item.setUpdateTime(new Date());
            cgiReplyBucketDataMapper.insertSelective(item);
            // result
            MsgData result = new MsgData();
            result.setMsgType(item.getMsgType());
            result.setTitle(item.getTitle());
            result.setCoverUrl(item.getCoverUrl());
            result.setMiniAppId(item.getMiniAppId());
            result.setMiniPagePath(item.getMiniPagePath());
            result.setMiniVideoId(item.getMiniVideoId());
            return result;
        }
        return null;
    }

    private String spliceCoverUrl(Long videoId, String coverUrl, Map<Long, VideoDetail> videoDetailMap) {
        coverUrl = coverUrl.contains("?") ? coverUrl.substring(0, coverUrl.indexOf("?")) : coverUrl;
        VideoDetail videoDetail = videoDetailMap.get(videoId);
        String coverSuffix = videoDetail.getCover().substring(videoDetail.getCover().indexOf("?"));
        if (coverUrl.contains("?") && coverUrl.contains("image/resize")) {
            coverSuffix = videoDetail.getCover().substring(videoDetail.getCover().indexOf("/watermark"));
        }
        if (!coverUrl.contains("yishihui")) {
            coverSuffix = "?x-oss-process=image/resize,m_fill,w_600,h_480,limit_0/format,jpg";
        }
        return coverUrl + coverSuffix;
    }

    @Override
    public Boolean checkExistRootSourceId(String rootSourceId) {
        String redisKey = "check_reply_exist_root_source_id_" + rootSourceId;
        String value = redisUtils.get(redisKey);
        if (StringUtils.isNotEmpty(value)) {
            return Boolean.parseBoolean(value);
        }
        List<CgiReplyBucketData> list = getCgiReplyBucketDataListByRootSourceId(rootSourceId);
        boolean exists = !CollectionUtils.isEmpty(list);
        // 缓存1小时
        redisUtils.set(redisKey, String.valueOf(exists), 60 * 60);
        return exists;
    }

}
