package com.crm.activity.service.impl;

import com.crm.activity.dao.mapper.ActivityRaceRankingMapper;
import com.crm.activity.dao.mapper.ActivityRaceRuleMapper;
import com.crm.activity.dao.repository.ActivityRaceRankingRepository;
import com.crm.activity.dao.repository.CustomInfoRepository;
import com.crm.activity.enums.ActivityRaceType;
import com.crm.activity.service.ActivityRaceRankingService;
import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.core.dto.base.BaseResultWithPagerDto;
import com.crm.rely.backend.core.dto.base.PageDto;
import com.crm.rely.backend.core.exception.ServiceException;
import com.crm.rely.backend.model.dto.activity.ActivityRaceRankingDto;
import com.crm.rely.backend.model.dto.activity.ActivityRaceRankingProfitCoverDto;
import com.crm.rely.backend.model.entity.activity.ActivityRaceRankingListEntity;
import com.crm.rely.backend.model.entity.activity.ActivityRaceRankingManualEntity;
import com.crm.rely.backend.model.entity.activity.ActivityRaceRankingMyEntity;
import com.crm.rely.backend.model.pojo.table.ActivityRaceRankingTable;
import com.crm.rely.backend.model.pojo.table.ActivityRaceRuleTable;
import com.crm.rely.backend.model.pojo.table.CustomInfoTable;
import com.crm.rely.backend.model.pojo.view.ActivityRaceRankingView;
import com.crm.rely.backend.util.FormatPage;
import com.crm.rely.backend.util.NameUtil;
import com.crm.rely.backend.util.RexUtil;
import com.crm.rely.backend.util.StringUtil;
import com.google.common.collect.Maps;
import org.apache.commons.compress.utils.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author y
 * @create 2022/7/21
 */
@Service
public class ActivityRaceRankingServiceImpl implements ActivityRaceRankingService {

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

    @Autowired
    private ActivityRaceRankingMapper activityRaceRankingMapper;
    @Autowired
    private ActivityRaceRuleMapper activityRaceRuleMapper;
    @Autowired
    private ActivityRaceRankingRepository activityRaceRankingRepository;
    @Autowired
    private CustomInfoRepository customInfoRepository;

    @Override
    public BaseResultWithPagerDto<List<ActivityRaceRankingDto>> searchList(ActivityRaceRankingListEntity entity) throws Exception {

        Integer count = activityRaceRankingMapper.countList(entity);
        if (count == null || count == 0) {
            return new BaseResultWithPagerDto<>(Constants.SUCCESS_CODE, Constants.SUCCESS);
        }

        PageDto pageDto = FormatPage.format(entity.getPage(), count);

        List<ActivityRaceRankingView> views = activityRaceRankingMapper.getList(entity);
        List<ActivityRaceRankingDto> dtos = Lists.newArrayList();
        for (ActivityRaceRankingView view : views) {
            dtos.add(convertViewToDtoBySecret(view, entity.isHide()));
        }

        return new BaseResultWithPagerDto<>(Constants.SUCCESS_CODE, Constants.SUCCESS, dtos, pageDto);
    }

    @Override
    public ActivityRaceRankingDto getById(Long id) throws Exception {
        ActivityRaceRankingView view = activityRaceRankingMapper.getViewById(id);
        if (view == null) {
            return null;
        }
        return convertViewToDto(view);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void reOrderRanking(Long ruleId) throws Exception {
        List<ActivityRaceRankingTable> all = activityRaceRankingMapper.getAllByRuleId(ruleId);
        all = reOrderRanking(all);
        //保存排名
        activityRaceRankingMapper.batchUpdateRank(all);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateManual(ActivityRaceRankingManualEntity entity) throws Exception {
        ActivityRaceRankingTable table = activityRaceRankingMapper.getById(entity.getId());
        if (table == null) {
            return;
        }
        //保存手动处理金额，重新计算profit
        table.setManual(table.getManual() + entity.getAmount());
        table.setProfit(table.getEndEquity() - table.getStartEquity() - table.getDw() + table.getManual());
        activityRaceRankingMapper.updateById(table);
        //重新排序
        ActivityRaceRuleTable raceRuleTable = activityRaceRuleMapper.getById(table.getRuleId());
        if (raceRuleTable == null) {
            throw new ServiceException("系统错误");
        }
        reOrderRanking(raceRuleTable.getId());

    }

    @Override
    public ActivityRaceRankingDto searchCustomRankingInfo(ActivityRaceRankingMyEntity entity) throws Exception {
        //获取活动规则信息
        ActivityRaceRuleTable ruleTable =
                activityRaceRuleMapper.findByCustomIdAndRaceTypeAndSerial(entity.getRaceType(), entity.getSerial());
        if (ruleTable == null) {
            throw new ServiceException(String.format("当前%s不存在", ActivityRaceType.matchDesc(entity.getRaceType())));
        }
        //根据规则获取当前用户的比赛信息
        ActivityRaceRankingView rankingView =
                activityRaceRankingMapper.getViewByCustomIdAndRuleId(entity.getCustomId(), ruleTable.getId());
        if (rankingView == null) {
            CustomInfoTable custom = customInfoRepository.getOne(entity.getCustomId());
            rankingView = new ActivityRaceRankingView();
            rankingView.setFirstName(custom.getFirstName());
            rankingView.setMiddle(custom.getMiddle());
            rankingView.setLastName(custom.getLastName());
            rankingView.setCountry(custom.getCountry());
            rankingView.setActive(-99);
        }
        return convertViewToDto(rankingView);
    }

    @Override
    public Map<Long, ActivityRaceRankingTable> mapAllByRuleId(Long ruleId) throws Exception {

        List<ActivityRaceRankingTable> tables = activityRaceRankingRepository.findAllByRuleId(ruleId);
        Map<Long, ActivityRaceRankingTable> map = Maps.newHashMap();
        for (ActivityRaceRankingTable table : tables) {
            map.put(table.getCustomId(), table);
        }

        return map;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCalcResult(List<ActivityRaceRankingTable> tables) throws Exception {
        activityRaceRankingMapper.batchUpdateProfit(tables);
    }

    @Override
    public List<ActivityRaceRankingTable> reOrderRanking(List<ActivityRaceRankingTable> tables) {

        if (CollectionUtils.isEmpty(tables)) {
            return null;
        }

        /*
            拆分为活跃和不活跃
         */
        List<ActivityRaceRankingTable> actives = Lists.newArrayList();
        List<ActivityRaceRankingTable> inactives = Lists.newArrayList();
        for (ActivityRaceRankingTable table : tables) {
            if (table.getActive() != null && table.getActive() >= 1) {
                actives.add(table);
            } else {
                table.setRank(0);
                inactives.add(table);
            }
        }

        /*
            对活跃报名排序
         */
        Date now = new Date();
        if (actives.size() == 1) {
            actives.get(0).setRank(1);
            actives.get(0).setModifyTime(now);
        } else {
            //按盈利排序
            actives.sort((i1, i2) -> (i1.getProfit() - i2.getProfit() >= 0) ? -1 : 1);
            //设置排名
            for (int i = 0; i < actives.size(); i++) {
                actives.get(i).setRank(i + 1);
                actives.get(i).setModifyTime(now);
            }
        }

        //返回结果
        List<ActivityRaceRankingTable> results = Lists.newArrayList();
        results.addAll(actives);
        results.addAll(inactives);
        return results;
    }

    @Override
    public BaseResultWithPagerDto<List<ActivityRaceRankingProfitCoverDto>> searchProfitCoverList(ActivityRaceRankingListEntity entity) throws Exception {
        Integer count = activityRaceRankingMapper.countList(entity);
        if (count == null || count == 0) {
            return new BaseResultWithPagerDto<>(Constants.SUCCESS_CODE, Constants.SUCCESS);
        }

        PageDto pageDto = FormatPage.format(entity.getPage(), count);

        List<ActivityRaceRankingView> views = activityRaceRankingMapper.getList(entity);
        List<ActivityRaceRankingProfitCoverDto> dtos = Lists.newArrayList();
        for (ActivityRaceRankingView view : views) {
            dtos.add(convertViewToDtoWithNameAndProfitSecret(view, entity.isHide()));
        }

        return new BaseResultWithPagerDto<>(Constants.SUCCESS_CODE, Constants.SUCCESS, dtos, pageDto);
    }

    private ActivityRaceRankingDto convertViewToDtoBySecret(ActivityRaceRankingView view, boolean isHide) {
        ActivityRaceRankingDto dto = new ActivityRaceRankingDto();
        BeanUtils.copyProperties(view, dto);
//        String name =  NameUtil.getName(view.getCountry(), view.getFirstName(), view.getMiddle(), view.getLastName());
        String name = RexUtil.rexName(view.getFirstName());
        dto.setName(name);
        if (isHide) {
//            dto.setName(StringUtil.secretLastName(view.getFirstName()));
            dto.setLogin(StringUtil.secretString(String.valueOf(view.getLogin())));
        } else {
            dto.setName(name);
            dto.setLogin(String.valueOf(view.getLogin()));
        }

        if (view.getActive() <= 0) {
            dto.setRank("暂无排名");
        } else {
            dto.setRank(String.format("#%d", view.getRank()));
        }

        return dto;
    }

    private ActivityRaceRankingDto convertViewToDto(ActivityRaceRankingView view) {
        ActivityRaceRankingDto dto = new ActivityRaceRankingDto();
        BeanUtils.copyProperties(view, dto);
        dto.setName(NameUtil.getName(view.getCountry(), view.getFirstName(), view.getMiddle(), view.getLastName()));
        if (view.getActive() == -99) {
            dto.setLogin("-");
        } else {
            dto.setLogin(String.valueOf(view.getLogin()));
        }
        if (view.getActive() <= 0) {
            if (view.getActive() == -99) {
                dto.setRank("未参赛");
            } else {
                dto.setRank("暂无排名");
            }

        } else {
            dto.setRank(String.format("#%d", view.getRank()));
        }
        return dto;
    }

    private ActivityRaceRankingProfitCoverDto convertViewToDtoWithNameAndProfitSecret(ActivityRaceRankingView view,
                                                                                      boolean isHide) {
        ActivityRaceRankingProfitCoverDto coverDto = new ActivityRaceRankingProfitCoverDto();
        ActivityRaceRankingDto raceRankingDto = convertViewToDtoBySecret(view, isHide);
        BeanUtils.copyProperties(raceRankingDto, coverDto);
        if (view.getRank() != 1) {
            coverDto.setProfit("***");
        } else {
            coverDto.setProfit(String.format("%.2f", raceRankingDto.getProfit()));
        }
        return coverDto;
    }

}
