package com.zanxiang.game.data.serve.service.impl;

import com.github.sd4324530.jtuple.Tuple2;
import com.google.common.base.CaseFormat;
import com.zanxiang.game.data.serve.component.DataPowerComponent;
import com.zanxiang.game.data.serve.pojo.dto.AdsAccountRechargeRankingListDTO;
import com.zanxiang.game.data.serve.pojo.vo.AdsAccountRechargeRankingVO;
import com.zanxiang.game.data.serve.service.IAdsAccountRechargeRankingService;
import com.zanxiang.game.data.serve.utils.Page;
import com.zanxiang.module.util.NumberUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.entity.Entity;
import org.nutz.dao.pager.Pager;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.Daos;
import org.nutz.dao.util.cri.SimpleCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collections;
import java.util.List;

@Slf4j
@Service
public class AdsAccountRechargeRankingServiceImpl implements IAdsAccountRechargeRankingService {

    @Autowired
    private Dao dao;
    @Autowired
    private DataPowerComponent dataPowerComponent;

    @Override
    public Page<AdsAccountRechargeRankingVO> listOfPage(AdsAccountRechargeRankingListDTO dto) {
        Tuple2<List<Long>, List<Long>> poerInfo = dataPowerComponent.getPowerInfo();
        List<Long> userIds = dto.getPitcherId() == null ? poerInfo.first : Collections.singletonList(dto.getPitcherId());
        List<Long> gameIds = dto.getGameId() == null ? poerInfo.second : Collections.singletonList(dto.getGameId());
        if (StringUtils.isBlank(dto.getSortFiled())) {
            dto.setSortFiled("cost");
        }
        if (StringUtils.isBlank(dto.getSortType())) {
            dto.setSortType("desc");
        }
        Pager pager = dto.toPage();
        String sqlStr = """
                select account_id, pitcher_id, max(pitcher) as pitcher, `type`, game_id, max(game_name) as game_name, max(game_classify) as game_classify , max(game_cp) as game_cp,
                sum(cost) as cost,
                sum(ad_count) as ad_count,
                sum(view_count) as view_count,
                sum(click_count) as click_count,
                sum(click_count) / sum(view_count) as click_rate,
                if(sum(view_count) > 0, sum(cost)/sum(view_count) * 1000, '0') as thousand_display_price,
                sum(reg_user_cnt) as reg_user_cnt,
                sum(cost) / sum(reg_user_cnt) as reg_cost,
                sum(first_role) as first_role,
                sum(total_role) as total_role,
                sum(first_amount) as first_amount,
                sum(first_amount_user) as first_amount_user,
                sum(first_amount_count) as first_amount_count,
                sum(total_amount) as total_amount,
                sum(total_amount_user) as total_amount_user,
                sum(total_amount_count) as total_amount_count,
                sum(first_amount) / sum(cost) as first_roi,
                sum(total_amount) / sum(total_amount_count) as avg_amount,
                sum(total_amount) / sum(cost) as roi
                from ads_account_recharge_ranking
                """;
        SimpleCriteria cri = Cnd.cri();
        if (null != dto.getBeginDay() && null != dto.getEndDay()) {
            cri.where().and("dt", ">=", dto.getBeginDay()).and("dt", "<=", dto.getEndDay());
        }
        if (userIds != null) {
            cri.where().andInList("pitcher_id", userIds);
        }
        if (StringUtils.isNotBlank(dto.getAccountId())) {
            cri.where().and("account_id", "=", dto.getAccountId());
        }
        if (gameIds != null) {
            cri.where().andInList("game_id", gameIds);
        }
        if (StringUtils.isNotBlank(dto.getType())) {
            cri.where().and("type", "=", dto.getType());
        }
        if (StringUtils.isNotBlank(dto.getSourceSystem())) {
            cri.where().and("source_system", "=", dto.getSourceSystem());
        }
        cri.groupBy("account_id", "pitcher_id", "type", "game_id");
        cri.orderBy(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, dto.getSortFiled()), dto.getSortType());
        Sql sql = Sqls.queryEntity(sqlStr + "$condition");

        Entity<AdsAccountRechargeRankingVO> entity = dao.getEntity(AdsAccountRechargeRankingVO.class);
        sql.setEntity(entity).setCondition(cri);
        // 查询总数居条数
        pager.setRecordCount(((Long) Daos.queryCount(dao, sql)).intValue());
        // 分页查询数据
        sql.setPager(pager);
        dao.execute(sql);

        List<AdsAccountRechargeRankingVO> result = sql.getList(AdsAccountRechargeRankingVO.class);
        if (CollectionUtils.isNotEmpty(result)) {
            result.forEach(vo -> {
                if (vo.getClickRate() != null) {
                    vo.setClickRate(NumberUtil.multiply100(vo.getClickRate()).setScale(2, RoundingMode.HALF_UP));
                } else {
                    vo.setClickRate(BigDecimal.ZERO);
                }
                if (vo.getAvgAmount() != null) {
                    vo.setAvgAmount(vo.getAvgAmount().setScale(2, RoundingMode.HALF_UP));
                } else {
                    vo.setAvgAmount(BigDecimal.ZERO);
                }
                if (vo.getFirstRoi() != null) {
                    vo.setFirstRoi(NumberUtil.multiply100(vo.getFirstRoi()).setScale(2, RoundingMode.HALF_UP));
                } else {
                    vo.setFirstRoi(BigDecimal.ZERO);
                }
                if (vo.getRoi() != null) {
                    vo.setRoi(NumberUtil.multiply100(vo.getRoi()).setScale(2, RoundingMode.HALF_UP));
                } else {
                    vo.setRoi(BigDecimal.ZERO);
                }
            });
            int beginIndex = (dto.getPageNum() - 1) * dto.getPageSize();
            int size = result.size();
            while (--size >= 0) {
                result.get(size).setIndex(beginIndex + size);
            }
        }
        return new Page<>(result, pager);
    }
}
