package com.crm.activity.service.impl;

import com.crm.activity.dao.mapper.AccountInfoMapper;
import com.crm.activity.dao.mapper.ActivityRaceRuleMapper;
import com.crm.activity.dao.mapper.ActivityRaceSignMapper;
import com.crm.activity.dao.mapper.TradePositionMapper;
import com.crm.activity.dao.repository.*;
import com.crm.activity.enums.ActivityRaceType;
import com.crm.activity.service.ActivityRaceSignService;
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.ActivityRaceSignInfoDto;
import com.crm.rely.backend.model.entity.activity.ActivityRaceSignAddEntity;
import com.crm.rely.backend.model.entity.activity.ActivityRaceSignInfoEntity;
import com.crm.rely.backend.model.entity.activity.ActivityRaceSignListEntity;
import com.crm.rely.backend.model.entity.activity.ActivityRaceSignLoginEntity;
import com.crm.rely.backend.model.pojo.table.*;
import com.crm.rely.backend.model.pojo.view.AccountInfoView;
import com.crm.rely.backend.model.pojo.view.ActivityRaceSignView;
import com.crm.rely.backend.util.FormatPage;
import com.crm.rely.backend.util.NameUtil;
import org.apache.commons.compress.utils.Lists;
import org.apache.poi.ss.formula.functions.Now;
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;

/**
 * 周比赛服务接口实现
 *
 * @author y
 * @create 2022/7/19
 */
@Service
public class ActivityRaceSignServiceImpl implements ActivityRaceSignService {

    @Autowired
    private ActivityRaceSignMapper activityRaceSignMapper;
    @Autowired
    private ActivityRaceSignRepository activityRaceSignRepository;
    @Autowired
    private ActivityRaceRuleMapper activityRaceRuleMapper;
    @Autowired
    private AccountInfoMapper accountInfoMapper;
    @Autowired
    private TradePositionMapper tradePositionMapper;
    @Autowired
    private CustomLoginRepository customLoginRepository;
    @Autowired
    private CustomLoginAssetManagementRepository customLoginAssetManagementRepository;
    @Autowired
    private CustomLoginFirmOfferRepository customLoginFirmOfferRepository;
    @Autowired
    private ActivityRaceRankingRepository activityRaceRankingRepository;

    /**
     * 报名
     *
     * @param entity
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(ActivityRaceSignAddEntity entity) throws Exception {

        /*
            根据报名时间获取对应的报名规则信息
         */
        ActivityRaceRuleTable ruleTable = activityRaceRuleMapper.findFirstBySignDateBtAndType(entity.getSignDate(), entity.getRaceType());
        if (ruleTable == null) {
            throw new ServiceException("当前时间无" + ActivityRaceType.matchDesc(entity.getRaceType()));
        }
        //判断是否过了报名截至时间
        if (entity.getSignDate().getTime() > ruleTable.getUpTo().getTime()) {
            throw new ServiceException("报名已截至，敬请关注下期比赛");
        }
        //判断是否重复报名
        Integer exists = activityRaceSignRepository.countByRuleIdAndCustomIdAndRaceType(ruleTable.getId(), entity.getCustomId(), entity.getRaceType());
        if (exists != null && exists >= 1) {
            throw new ServiceException("不能重复报名");
        }
        //判断交易账户是否已经报名
        List<ActivityRaceSignTable> signTables = activityRaceSignMapper.findValidSignByCustomIdAndDate(entity.getCustomId(), entity.getSignDate());
        for (ActivityRaceSignTable signTable : signTables) {
            if (signTable.getLogin().equals(entity.getLogin())) {
                throw new ServiceException("不能重复报名");
            }
        }
        //验证交易账户是否能参与当前活动
        validateLogin(entity);
        //交易平台
        String platform = Constants.MT4;
        //判断是否有持仓
        exists = tradePositionMapper.countByLogin(entity.getLogin(), platform);
        if (exists != null && exists >= 1) {
            throw new ServiceException("报名前需清仓");
        }
        //获取账户信息
        AccountInfoView accountInfoView = accountInfoMapper.findByLogin(entity.getLogin(), platform);
        //净值要求
        validateEquity(accountInfoView, entity.getRaceType());
        //添加报名
        ActivityRaceSignTable signTable = new ActivityRaceSignTable();
        BeanUtils.copyProperties(entity, signTable);
        signTable.setAddTime(new Date());
        signTable.setEquity(accountInfoView.getEquity());
        signTable.setRaceStartDate(ruleTable.getStartDate());
        signTable.setRaceEndDate(ruleTable.getEndDate());
        signTable.setSerial(ruleTable.getSerial());
        signTable.setRuleId(ruleTable.getId());
        activityRaceSignRepository.save(signTable);
        //添加排名信息
        ActivityRaceRankingTable rankingTable = ActivityRaceRankingTable.getInstance();
        rankingTable.setCustomId(entity.getCustomId());
        rankingTable.setCId(entity.getCId());
        rankingTable.setLogin(entity.getLogin());
        rankingTable.setRuleId(ruleTable.getId());
        rankingTable.setStartEquity(accountInfoView.getEquity());
        rankingTable.setAddTime(new Date());
        rankingTable.setRuleId(ruleTable.getId());
        activityRaceRankingRepository.save(rankingTable);
    }

    @Override
    public ActivityRaceSignInfoDto info(ActivityRaceSignInfoEntity entity) throws Exception {

        //获取最近一次报名
        ActivityRaceSignView view = activityRaceSignMapper.findFirstByCustomIdAndRaceType(entity.getCustomId(), entity.getRaceType());
        if (view == null) {
            return null;
        }
        Date now = new Date();
        if (view.getRaceEndDate().getTime() < now.getTime()) {
            return null;
        }
        return convertViewToDto(view);
    }

    @Override
    public ActivityRaceSignInfoDto searchById(Long id) throws Exception {

        ActivityRaceSignView view = activityRaceSignMapper.findViewById(id);
        if (view == null) return null;
        return convertViewToDto(view);
    }

    @Override
    public BaseResultWithPagerDto<List<ActivityRaceSignInfoDto>> searchList(ActivityRaceSignListEntity entity) throws Exception {

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

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


        List<ActivityRaceSignInfoDto> dtos = Lists.newArrayList();
        List<ActivityRaceSignView> views = activityRaceSignMapper.getList(entity);
        for (ActivityRaceSignView view : views) {
            dtos.add(convertViewToDto(view));
        }

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

    @Override
    public List<Long> getLogins(ActivityRaceSignLoginEntity entity) throws Exception {

        Date now = new Date();
        /*
            根据报名时间获取对应的报名规则信息
         */
        ActivityRaceRuleTable ruleTable = activityRaceRuleMapper.findFirstBySignDateBtAndType(now, entity.getRaceType());
        if (ruleTable == null) {
            throw new ServiceException("当前时间无" + ActivityRaceType.matchDesc(entity.getRaceType()));
        }
        //可用的交易账户
        List<Long> logins = Lists.newArrayList();
        //获取当前时间已报名的信息
        List<ActivityRaceSignTable> signTables = activityRaceSignMapper.findValidSignByCustomIdAndDate(entity.getCustomId(), now);
        List<Long> signLogins = Lists.newArrayList();
        boolean applied = false;
        for (ActivityRaceSignTable signTable : signTables) {
            signLogins.add(signTable.getLogin());
            if (signTable.getRaceType().equals(entity.getRaceType())) {
                applied = true;
            }
        }

        if (applied) {
            throw new ServiceException("您已经参与本次" + ActivityRaceType.matchDesc(entity.getRaceType()));
        }

        List<Long> allLogins = Lists.newArrayList();

        //实盘账户
        List<CustomLoginTable> loginTables = customLoginRepository.findAllByCustomId(entity.getCustomId());
        for (CustomLoginTable loginTable : loginTables) {
            allLogins.add(loginTable.getLogin());
        }
        //月赛账户
        if (ActivityRaceType.MONTHLY.getCode().equals(entity.getRaceType())) {

            List<CustomLoginAssetManagementTable> managementTables = customLoginAssetManagementRepository.findAllByCustomId(entity.getCustomId());
            for (CustomLoginAssetManagementTable managementTable : managementTables) {
                allLogins.add(managementTable.getLogin());
            }

            List<CustomLoginFirmOfferTable> offerTables = customLoginFirmOfferRepository.findAllByCustomId(entity.getCustomId());
            for (CustomLoginFirmOfferTable offerTable : offerTables) {
                allLogins.add(offerTable.getLogin());
            }

        }

        //剔除已报名的账户
        for (Long allLogin : allLogins) {
            if (!signLogins.contains(allLogin)) {
                logins.add(allLogin);
            }
        }
        if (CollectionUtils.isEmpty(logins)){
            return logins;
        }
        //剔除净值不满足条件账户
        List<AccountInfoView> accountInfoViews = accountInfoMapper.findAllByLoginIn(logins, Constants.MT4);
        logins = Lists.newArrayList();
        for (AccountInfoView accountInfoView : accountInfoViews) {
            try {
                validateEquity(accountInfoView, entity.getRaceType());
                logins.add(accountInfoView.getLogin());
            }catch (Exception e){

            }

        }

        if (CollectionUtils.isEmpty(logins)) {
            throw new ServiceException("无可用的交易账户");
        }

        return logins;
    }

    private ActivityRaceSignInfoDto convertViewToDto(ActivityRaceSignView view) {
        ActivityRaceSignInfoDto dto = new ActivityRaceSignInfoDto();
        BeanUtils.copyProperties(view, dto);
        dto.setName(NameUtil.getName(view.getCountry(), view.getFirstName(), view.getMiddle(), view.getLastName()));
        return dto;
    }

    /**
     * 验证交易账户是否能参与当前活动
     *
     * @param entity
     * @throws Exception
     */
    private void validateLogin(ActivityRaceSignAddEntity entity) throws Exception {
        /*
            如果是周赛
         */
        if (ActivityRaceType.WEEKLY.getCode().equals(entity.getRaceType())) {
            CustomLoginTable customLoginTable = customLoginRepository.findFirstByLogin(entity.getLogin());
            if (customLoginTable == null) {
                throw new ServiceException("当前账户无法参与");
            }
        }
        /*
            如果是月赛
         */
        else if (ActivityRaceType.MONTHLY.getCode().equals(entity.getRaceType())) {
            CustomLoginTable customLoginTable = customLoginRepository.findFirstByLogin(entity.getLogin());
            if (customLoginTable == null) {
                CustomLoginFirmOfferTable firmOfferTable = customLoginFirmOfferRepository.findFirstByLogin(entity.getLogin());
                if (firmOfferTable == null) {
                    CustomLoginAssetManagementTable assetManagementTable = customLoginAssetManagementRepository.findFirstByLogin(entity.getLogin());
                    if (assetManagementTable == null) {
                        throw new ServiceException("当前账户无法参与");
                    }
                }
            }
        }

    }

    private void validateEquity(AccountInfoView accountInfoView, Integer raceType) {

        if (ActivityRaceType.WEEKLY.getCode().equals(raceType)) {
            if (accountInfoView.getEquity() < 500F) {
                throw new ServiceException("个人实盘账户净值需500美元以上");
            }
        } else if (ActivityRaceType.MONTHLY.getCode().equals(raceType)) {
            if (accountInfoView.getEquity() < 5000F) {
                throw new ServiceException("个人实盘账户净值需5000美元以上");
            }
        }
    }
}
