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

import com.alibaba.fastjson.JSON;
import com.tzld.piaoquan.api.common.enums.ExceptionEnum;
import com.tzld.piaoquan.api.common.enums.contentplatform.AccountStatusEnum;
import com.tzld.piaoquan.api.common.enums.contentplatform.PublishStageEnum;
import com.tzld.piaoquan.api.common.exception.CommonException;
import com.tzld.piaoquan.api.dao.mapper.contentplatform.ext.ContentPlatformPlanMapperExt;
import com.tzld.piaoquan.api.model.config.LoginUserContext;
import com.tzld.piaoquan.api.model.param.contentplatform.GzhPlanSaveParam;
import com.tzld.piaoquan.api.model.param.contentplatform.GzhPlanVideoContentItemParam;
import com.tzld.piaoquan.api.model.param.contentplatform.VideoContentListParam;
import com.tzld.piaoquan.api.model.param.contentplatform.api.GetContentPageParam;
import com.tzld.piaoquan.api.model.param.contentplatform.api.GetTokenParam;
import com.tzld.piaoquan.api.model.param.contentplatform.api.GetVideoPageUrlParam;
import com.tzld.piaoquan.api.model.po.contentplatform.ContentPlatformAccount;
import com.tzld.piaoquan.api.model.po.contentplatform.ContentPlatformGzhAccount;
import com.tzld.piaoquan.api.model.po.contentplatform.ContentPlatformVideo;
import com.tzld.piaoquan.api.model.vo.contentplatform.api.VideoIdTitleVO;
import com.tzld.piaoquan.api.model.vo.contentplatform.api.VideoPageUrlVO;
import com.tzld.piaoquan.api.service.CgiReplyService;
import com.tzld.piaoquan.api.service.contentplatform.ContentPlatformAccountService;
import com.tzld.piaoquan.api.service.contentplatform.ContentPlatformApiService;
import com.tzld.piaoquan.api.service.contentplatform.ContentPlatformCooperateAccountService;
import com.tzld.piaoquan.api.service.contentplatform.ContentPlatformPlanService;
import com.tzld.piaoquan.growth.common.model.po.CgiReplyBucketData;
import com.tzld.piaoquan.growth.common.utils.RedisUtils;
import com.tzld.piaoquan.growth.common.utils.page.Page;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class ContentPlatformApiServiceImpl implements ContentPlatformApiService {

    @Autowired
    private ContentPlatformAccountService accountService;
    @Autowired
    private ContentPlatformPlanService planService;
    @Autowired
    private ContentPlatformPlanMapperExt planMapperExt;
    @Autowired
    private ContentPlatformCooperateAccountService gzhAccountService;
    @Autowired
    private CgiReplyService cgiReplyService;

    @Autowired
    private RedisUtils redisUtils;

    @Value("${video.min.score:0.0}")
    private Double videoMinScore;

    @Override
    public String getToken(GetTokenParam param) {
        ContentPlatformAccount account = accountService.getAccountByTelNum(param.getTelNum());
        if (Objects.isNull(account)) {
            throw new CommonException(ExceptionEnum.ACCOUNT_NOT_EXISTS_WRONG);
        }
        if (account.getStatus() == AccountStatusEnum.FORBIDDEN.getVal()) {
            throw new CommonException(ExceptionEnum.ACCOUNT_BANNED);
        }
        if (!account.getPassword().equals(param.getPassword())) {
            throw new CommonException(ExceptionEnum.LOGIN_PASSWORD_WRONG);
        }
        String token = UUID.randomUUID().toString().replace("-", "");
        saveTokenToRedis(account, token, 4 * 60 * 60L);
        return token;
    }

    private void saveTokenToRedis(ContentPlatformAccount account, String token, Long expireTime) {
        String tokenPrefix = "api.{token}";
        String redisKey = tokenPrefix.replace("{token}", token);
        redisUtils.setValueWithExpire(redisKey, JSON.toJSONString(account), expireTime);
    }

    @Override
    public Page<VideoIdTitleVO> getContent(String token, GetContentPageParam param) {
        checkToken(token);
        if (Objects.isNull(param.getPageNum()) || Objects.isNull(param.getPageSize())
                || param.getPageNum() <= 0 || param.getPageSize() <= 0) {
            throw new CommonException(ExceptionEnum.API_PAGE_PARAM_ERROR);
        }
        if (param.getPageSize() > 500) {
            throw new CommonException(ExceptionEnum.API_PAGE_SIZE_TOO_LARGE);
        }
        Page<VideoIdTitleVO> result = new Page<>(param.getPageNum(), param.getPageSize());
        int offset = (param.getPageNum() - 1) * param.getPageSize();
        String dt = planMapperExt.getVideoMaxDt();
        String datastatDt = planMapperExt.getVideoDatastatMaxDt();
        VideoContentListParam listParam = new VideoContentListParam();
        int count = planMapperExt.getVideoCount(listParam, dt, videoMinScore);
        result.setTotalSize(count);
        if (count == 0) {
            return result;
        }
        List<ContentPlatformVideo> videoList = planMapperExt.getVideoList(listParam, dt, datastatDt,
                "", "sum", "normal", videoMinScore,
                offset, param.getPageSize(), "video.score desc");
        List<VideoIdTitleVO> list = videoList.stream().map(video -> {
            VideoIdTitleVO vo = new VideoIdTitleVO();
            vo.setVideoId(video.getVideoId());
            vo.setTitle(video.getTitle());
            return vo;
        }).collect(Collectors.toList());
        result.setObjs(list);
        return result;
    }

    private ContentPlatformAccount checkToken(String token) {
        String tokenPrefix = "api.{token}";
        String redisKey = tokenPrefix.replace("{token}", token);
        String value = redisUtils.getString(redisKey);
        if (StringUtils.isBlank(value)) {
            throw new CommonException(ExceptionEnum.API_TOKEN_ERROR);
        }
        return JSON.parseObject(value, ContentPlatformAccount.class);
    }

    @Override
    public List<VideoPageUrlVO> getVideoPageUrl(String token, GetVideoPageUrlParam param) {
        ContentPlatformAccount account = checkToken(token);
        if (CollectionUtils.isEmpty(param.getPlanList()) || param.getPlanList().size() > 3) {
            throw new CommonException(ExceptionEnum.API_PAGE_URL_SIZE_TOO_LARGE);
        }
        List<VideoPageUrlVO> result = new ArrayList<>();
        List<Long> videoIds = param.getPlanList().stream().flatMap(o -> o.getVideoIds().stream()).collect(Collectors.toList());
        List<ContentPlatformVideo> videoList = planMapperExt.getVideoListByIds(videoIds);
        Map<Long, ContentPlatformVideo> videoMap = videoList.stream().collect(Collectors.toMap(ContentPlatformVideo::getVideoId, video -> video));
        List<String> ghIds = param.getPlanList().stream().map(GetVideoPageUrlParam.PlanItem::getGhId).collect(Collectors.toList());
        List<ContentPlatformGzhAccount> gzhAccountList = gzhAccountService.getAccountListByGhIds(ghIds, account.getId());
        Map<String, ContentPlatformGzhAccount> gzhAccountMap = gzhAccountList.stream()
                .collect(Collectors.toMap(ContentPlatformGzhAccount::getGhId, gzhAccount -> gzhAccount));
        LoginUserContext.setLoginUser(account);
        for (GetVideoPageUrlParam.PlanItem item : param.getPlanList()) {
            int code = 0;
            String msg = "";
            List<VideoPageUrlVO.VideoPageUrlItem> data = new ArrayList<>();
            try {
                GzhPlanSaveParam saveParam = new GzhPlanSaveParam();
                saveParam.setPublishStage(PublishStageEnum.USER.getVal());
                ContentPlatformGzhAccount gzhAccount = gzhAccountMap.get(item.getGhId());
                if (Objects.isNull(gzhAccount)) {
                    throw new CommonException(ExceptionEnum.GZH_ACCOUNT_NOT_EXISTS);
                }
                saveParam.setAccountId(gzhAccount.getId());
                saveParam.setScene(0);
                saveParam.setType(item.getType());
                saveParam.setSelectVideoType(0);
                List<GzhPlanVideoContentItemParam> videoItemList = new ArrayList<>();
                for (Long videoId : item.getVideoIds()) {
                    ContentPlatformVideo video = videoMap.get(videoId);
                    GzhPlanVideoContentItemParam videoItem = new GzhPlanVideoContentItemParam();
                    videoItem.setVideoId(video.getVideoId());
                    videoItem.setTitle(video.getTitle());
                    videoItem.setCover(video.getCover());
                    videoItem.setVideo(video.getVideo());
                    videoItemList.add(videoItem);
                }
                saveParam.setVideoList(videoItemList);
                planService.gzhPlanSave(saveParam);
                List<CgiReplyBucketData> replyBucketDataList = cgiReplyService.getCgiReplyBucketDataListByGhIdVideoId(
                        gzhAccount.getGhId(), item.getVideoIds(), "manual");
                for (CgiReplyBucketData cgiReplyBucketData : replyBucketDataList) {
                    VideoPageUrlVO.VideoPageUrlItem vo = new VideoPageUrlVO.VideoPageUrlItem();
                    vo.setVideoId(cgiReplyBucketData.getMiniVideoId());
                    vo.setTitle(cgiReplyBucketData.getTitle());
                    vo.setCover(cgiReplyBucketData.getCoverUrl());
                    vo.setPageUrl(cgiReplyBucketData.getMiniPagePath());
                    data.add(vo);
                }
            } catch (Exception e) {
                code = -1;
                msg = e.getMessage();
            } finally {
                VideoPageUrlVO response = new VideoPageUrlVO();
                response.setId(item.getId());
                response.setCode(code);
                response.setMsg(msg);
                response.setData(data);
                result.add(response);
            }
        }
        LoginUserContext.remove();
        return result;
    }
}
