package com.ytpm.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.ytpm.agent.enums.AdRecordEnum;
import com.ytpm.agent.model.YtApp;
import com.ytpm.agent.model.YtPlatformUserApp;
import com.ytpm.agent.param.AdRecordListParam;
import com.ytpm.agent.param.AuditCheckParam;
import com.ytpm.agent.param.AuditUserParam;
import com.ytpm.agent.view.AgentUserInfo;
import com.ytpm.app.model.YtDyzAdRecord;
import com.ytpm.app.model.YtDyzLoginRecord;
import com.ytpm.app.param.YtAppUserListParam;
import com.ytpm.app.view.AppUserStaticsView;
import com.ytpm.app.view.YtAppUserListView;
import com.ytpm.app.view.YtUserEcpmListView;
import com.ytpm.app.view.YtUserEcpmStatisticView;
import com.ytpm.dao.*;
import com.ytpm.general.*;
import com.ytpm.middle.model.YtPlatformMessage;
import com.ytpm.middle.view.MessageRecordVO;
import com.ytpm.middle.view.MessageVO;
import com.ytpm.risk.view.RiskTemplateView;
import com.ytpm.service.YtAppUserService;
import com.ytpm.utils.FeignClientInvoker;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * App用户业务逻辑
 */
@Slf4j
@Service
public class YtAppUserServiceImpl implements YtAppUserService {

    @Autowired
    private FeignClientInvoker feignInvoker;
    @Resource
    private AppMapper appMapper;
    @Resource
    private RiskMapper riskMapper;
    @Resource
    private AgentStaticsMapper staticsMapper;
    @Resource
    private MessageMapper messageMapper;
    @Resource
    private AgentAppMapper agentAppMapper;


    /**
     * 查询App用户列表
     * @param param 列表入参
     * @return 分页列表
     */
    @Override
    public ResultTable<YtAppUserListView> selectAppUserList(YtAppUserListParam param, AgentUserInfo userInfo) {
        //数据量大已改为appId必传
        YtApp ytApp = appMapper.selectPrimary(param.getAppIds());
        YtPlatformUserApp app = agentAppMapper.selectByPrimaryKey(ytApp.getSuperiorId());
        Object o = feignInvoker.invoke(app.getServiceName(), "queryAll", param);
        String string = JSON.toJSONString(o);
        JSONObject object = JSON.parseObject(string);
        List<YtAppUserListView> views = JSONArray.parseArray(object.getString("data"), YtAppUserListView.class);
        PageMeta pageMeta = JSON.parseObject(object.getString("pageMeta"), PageMeta.class);
        if(CollUtil.isNotEmpty(views)){
            setUserExtInfo(views,ytApp);
        }
        return new ResultTable(StatusCode.OK,RepMessage.QUERY_SUCCESS,views,pageMeta);
    }

    /**
     * 设置用户扩展信息
     */
    private void setUserExtInfo(List<YtAppUserListView> data, YtApp ytApp) {
        for (YtAppUserListView datum : data) {
            List<YtDyzLoginRecord> recordList = datum.getLoginRecordList();
            datum.setAppId(ytApp.getAppId());
            datum.setAppName(ytApp.getAppName());
            datum.setAppType(ytApp.getAppType());
            datum.setChannelId(ytApp.getChannelId());
            datum.setVersionCode(ytApp.getVersionCode());
            datum.setDitchId(ytApp.getDitchId());
            datum.setDitchName(ytApp.getDitchName());
            if(CollUtil.isNotEmpty(recordList)){
                datum.setDeviceRepeatCount((int) recordList.stream().map(YtDyzLoginRecord::getDeviceModel).distinct().count());
                datum.setIpRepeatCount((int)recordList.stream().map(YtDyzLoginRecord::getIpAddr).distinct().count());
                datum.setCommunicationOperator(recordList.get(0).getOperator());
            }

        }
    }

    /**
     * 查询用户广告数据统计列表
     */
    @Override
    public ResultTable<AppUserStaticsView> staticList() {
        List<AppUserStaticsView> list = new ArrayList<>();
        AppUserStaticsView view;
        List<String> formatList = Arrays.asList("%Y-%m", "%Y-%m-%d");
        for (String format : formatList) {
            view = new AppUserStaticsView();
            view.setStaticsType("%Y-%m".equals(format)?1:2);
            //用户数
            view.setUserNum(staticsMapper.getUserNum(format));
            //封禁用户数
            view.setBannedNum(staticsMapper.getBannedNum(format));
            //提现用户数
            view.setWithdrawNum(staticsMapper.getWithdrawNum(format));
            //提现笔数
            view.setWithdrawCount(staticsMapper.getWithdrawCount(format));
            //已发提现金额
            view.setWithdrawAmount(staticsMapper.getWithdrawSum(format));
            //总广告数
            view.setVideoWatchCount(staticsMapper.getVideoWatchCount(format));
            list.add(view);
        }
        return ResultTable.resultTableOk(new PageInfo<>(list));
    }

    /**
     * 查询用户的ecpm
     */
    @Override
    public ResultTable<YtUserEcpmListView> ecpmList(AdRecordListParam param) {
        ResultTable<YtUserEcpmListView> resultTable = new  ResultTable<>();
        try {
            resultTable = ecpmListV2(param);
        } catch (Exception e) {
            // 兼容旧服务包
            resultTable = ecpmListV1(param);
        }
        return resultTable;
    }

    private ResultTable<YtUserEcpmListView> ecpmListV1(AdRecordListParam param) {
        YtApp ytApp = appMapper.selectPrimary(param.getAppId());
        YtPlatformUserApp app = agentAppMapper.selectByPrimaryKey(ytApp.getSuperiorId());
        Object o = feignInvoker.invoke(app.getServiceName(), "adRecords", param.getUserId(), Integer.parseInt(param.getAdsourceType()));
        JSONObject object = JSONObject.parseObject(JSON.toJSONString(o));
        List<YtDyzAdRecord> records = JSONArray.parseArray(object.getString("data"), YtDyzAdRecord.class);
        PageMeta pageMeta = JSON.parseObject(object.getString("pageMeta"), PageMeta.class);
        return new ResultTable(StatusCode.OK,RepMessage.QUERY_SUCCESS,records,pageMeta);
    }

    private ResultTable<YtUserEcpmListView> ecpmListV2(AdRecordListParam param) {
        YtApp ytApp = appMapper.selectPrimary(param.getAppId());
        YtPlatformUserApp app = agentAppMapper.selectByPrimaryKey(ytApp.getSuperiorId());
        if (Objects.isNull(param.getLoginStatus())) {
            param.setLoginStatus(AdRecordEnum.LOGIN_AFTER.getCode());
        }
        Object o = feignInvoker.invoke(app.getServiceName(), "adRecordsPage", param);
        JSONObject object = JSONObject.parseObject(JSON.toJSONString(o));
        List<YtDyzAdRecord> records = JSONArray.parseArray(object.getString("data"), YtDyzAdRecord.class);
        PageMeta pageMeta = JSON.parseObject(object.getString("pageMeta"), PageMeta.class);
        return new ResultTable(StatusCode.OK, RepMessage.QUERY_SUCCESS, records, pageMeta);
    }


    /**
     * 根据时间统计收益
     */
    @Override
    public Result<BigDecimal> getRevenueByTime(YtAppUserListParam param, String userId) {
        //数据量大改为必定选择一个app
        YtApp ytApp = appMapper.selectPrimary(param.getAppIds());
        YtPlatformUserApp app = agentAppMapper.selectByPrimaryKey(ytApp.getSuperiorId());
        Object o = feignInvoker.invoke(app.getServiceName(), "getRevenueByTime",param);
        return Result.resultObjOk(new BigDecimal(JSON.toJSONString(o)));
    }

    /**
     * 查询我的未读消息
     */
    @Override
    public ResultTable<MessageVO> unreadMessage(String userId) {
        return ResultTable.resultTableOk(new PageInfo<MessageVO>(messageMapper.getUnreadMessage(userId)));
    }

    /**
     * 标记消息已读
     */
    @Override
    public Result<String> markRead(String messageId, String userId) {
        messageMapper.markRead(messageId,userId);
        //查询当前消息是否群发  如群发需判断是否是最后一个读取消息
        YtPlatformMessage message = messageMapper.queryMessage(messageId);
        if(Objects.isNull(message)) {
           return Result.resultErr(RepMessage.OBJECT_NOT_EXIST);
        }
        if(message.getSendType() == 1){ //单发直接修改并返回
            modifyMessageStatus(messageId,userId);
            return Result.resultOk(RepMessage.MODIFY_SUCCESS);
        }
        //群发需查询除我以外的该消息未读记录，如不存在则我为最后一个需要修改主类已读状态
        List<MessageRecordVO> vos =  messageMapper.queryUnreadRecord(messageId,userId);
        if(CollUtil.isNotEmpty(vos)) {
           return Result.resultOk(RepMessage.MODIFY_SUCCESS);
        }
        modifyMessageStatus(messageId,userId);
        return Result.resultOk(RepMessage.MODIFY_SUCCESS);
    }

    /**
     * 批量审核
     *  数据量大必须选择一个app
     */
    @Override
    public Result<String> batchAudit(AuditUserParam auditParam) {
        //根据appId 查询出配置的风控规则
        RiskTemplateView ecpmLimit= riskMapper.getByCode(auditParam.getAppId()+"-742");
        RiskTemplateView revenueLimit= riskMapper.getByCode(auditParam.getAppId()+"-746");
        auditParam.setAdSourceType(1);
        if(Objects.isNull(ecpmLimit) || Objects.isNull(revenueLimit)){
            return Result.resultErr(RepMessage.OBJECT_NOT_EXIST);
        }
        YtApp ytApp = appMapper.selectPrimary(auditParam.getAppId());
        YtPlatformUserApp app = agentAppMapper.selectByPrimaryKey(ytApp.getSuperiorId());
        feignInvoker.invoke(app.getServiceName(), "batchAudit", new AuditCheckParam(ecpmLimit,revenueLimit,auditParam));
        return Result.resultOk(RepMessage.CONFIRM_SUCCESS);
    }

    @Override
    public Result<YtUserEcpmStatisticView> ecpmStatistic(AdRecordListParam param) {
        YtUserEcpmStatisticView statisticView = null;
        YtApp ytApp = appMapper.selectPrimary(param.getAppId());
        YtPlatformUserApp app = agentAppMapper.selectByPrimaryKey(ytApp.getSuperiorId());
        try {
            Object object = feignInvoker.invoke(app.getServiceName(), "adRecordsStatistic", param);
            if (object != null) {
                JSONObject json = JSONObject.parseObject(JSON.toJSONString(object));
                statisticView = JSONObject.parseObject(json.getString("data"), YtUserEcpmStatisticView.class);
            }
        } catch (Exception e) {
            log.error(StrUtil.format("远程调用接口[adRecordsStatistic]失败: {}", e.getMessage()), e);
            return Result.resultErr(e.getMessage());
        }
        return Result.resultObjOk(statisticView);
    }

    /**
     * 修改消息已读状态
     */
    private void modifyMessageStatus(String messageId, String userId) {
        YtPlatformMessage msg = new YtPlatformMessage();
        msg.setMessageId(messageId);
        msg.setMessageStatus(1);
        msg.setUpdateParam(userId);
        messageMapper.updateById(msg);
    }
}
