package com.copy.trade.service.impl;

import java.math.BigDecimal;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.ArrayList;
import java.util.List;

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 com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.copy.trade.constant.DogeApi;
import com.copy.trade.dao.FavoriteMapper;
import com.copy.trade.entity.po.Customer;
import com.copy.trade.entity.po.Favorite;
import com.copy.trade.entity.po.FollowConfig;
import com.copy.trade.entity.po.Tag;
import com.copy.trade.entity.vo.TraderVo;
import com.copy.trade.entity.vo.YieldVo;
import com.copy.trade.enums.FollowConfigEnum;
import com.copy.trade.enums.TraderEnum;
import com.copy.trade.service.ICustomerService;
import com.copy.trade.service.IFavoriteService;
import com.copy.trade.service.IFollowConfigService;
import com.copy.trade.service.IFollowService;
import com.copy.trade.service.ITraderDataService;
import com.copy.trade.service.ITraderTagService;
import com.copy.trade.util.DogeContractUtils;
import com.copy.trade.util.RedisUtils;
import com.copy.trade.util.TraderConfiguration;
import com.copy.trade.util.WebAssert;

/**
 * <p>
 * 关注表 服务实现类
 * </p>
 *
 * @author wz
 * @since 2022-11-08
 */
@Service
public class FavoriteServiceImpl extends ServiceImpl<FavoriteMapper, Favorite> implements IFavoriteService {
    @Value("${doge.host_inner}")
    private String dogeHost;

    @Value("${doge.host}")
    private String host;
	
	@Autowired
    private ICustomerService customerServiceImpl;

    @Autowired
    private IFollowService followServiceImpl;

    @Autowired
    private ITraderTagService traderTagServiceImpl;

    @Autowired
    private ITraderDataService traderDataServiceImpl;
    
    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private IFollowConfigService followConfigServiceImpl;

    @Override
    public Boolean favorite(Long customerId, Long traderId) {
        Customer trader = customerServiceImpl.getById(traderId);
        WebAssert.isNotNull(trader,"chk.trader.not.exist");
        Boolean isTrader = trader.getTrader().equals(TraderEnum.TRADER.getStatus());
        WebAssert.isTrue(isTrader, "chk.not.trader");
        Favorite favorite = new Favorite();
        favorite.setTraderId(traderId);
        favorite.setCustomerId(customerId);
        try{
            save(favorite);
        }catch (Exception e){
            Throwable cause = e.getCause();
            if(cause instanceof SQLIntegrityConstraintViolationException){
                String errMsg = ((java.sql.SQLIntegrityConstraintViolationException) cause).getMessage();
                if(StringUtils.isNotEmpty(errMsg) && errMsg.indexOf("favorite_unique") != -1){
                    //唯一索引异常
                }
            }
        }
        return true;
    }

    @Override
    public Boolean unfavorite(Long customerId, Long traderId) {
        QueryWrapper<Favorite> favoriteQueryWrapper = new QueryWrapper<>();
        favoriteQueryWrapper.eq("customer_id",customerId)
                .eq("trader_id",traderId);
        Favorite favorite = getOne(favoriteQueryWrapper);
        if(favorite != null){
           removeById(favorite);
        }
        return true;
    }



    @Override
    public Page<TraderVo> list(Long customerId, Page page) {
        List<TraderVo> list = ((FavoriteMapper)baseMapper).inFocus(page, customerId);
        list.forEach(traderVo -> {
            Integer followCount = followServiceImpl.countByTrader(traderVo.getId());
            Integer defaultFollowCustomer = traderVo.getDefaultFollowCustomer() == null ? 0 : traderVo.getDefaultFollowCustomer();
            traderVo.setFollowing(followCount + defaultFollowCustomer);
            traderVo.setFollowCustomer((traderVo.getFollowCustomer() == null ? 0L : traderVo.getFollowCustomer()) + defaultFollowCustomer);

            traderVo.setIsFavorite(1);
            traderVo.setIsFollow(0);
            if (followServiceImpl.isFollow(customerId, traderVo.getId())) {
                traderVo.setIsFollow(1);
            }

            FollowConfig followConfig = followConfigServiceImpl.getConfig(FollowConfigEnum.SPECIAL_TRADER_CODE.getNameEn());
            boolean isSpecialTrader = traderVo.getTraderLevelId() >= Integer.parseInt(followConfig.getConfigContent());
            traderVo.setSpecialTrader(isSpecialTrader);

            List<Tag> taglist = traderTagServiceImpl.list(traderVo.getId());
            List<String> tags = new ArrayList<>();
            taglist.forEach(tag -> tags.add(tag.getName()));
            traderVo.setTags(tags);

            List<YieldVo> yieldVoList = traderDataServiceImpl.yield14(traderVo.getId());
            traderVo.setYield14List(dayYield14Trans(yieldVoList, traderVo));

            BigDecimal balance = DogeContractUtils.asset(host + DogeApi.CONTRACT_ASSET_NEW, traderVo.getMemberId());
            traderVo.setMoneyStrength("≥5K");
            if (balance.compareTo(new BigDecimal("5000")) < 0) {
                traderVo.setMoneyStrength("<5K");
            }

            if (isSpecialTrader) {
                traderVo.setTags(TraderConfiguration.getSpecailTagList(traderVo.getMemberId(), traderVo.getTags()));
                traderVo.setNickname(TraderConfiguration.getSpecailName(traderVo.getMemberId(), traderVo.getNickname()));
                traderVo.setMinFollowAmount(traderVo.getMinFollowAmount() == null ? 2000L : traderVo.getMinFollowAmount());
            }
            traderVo.setTeamProfit14String(TraderConfiguration.getSpecialTraderAmoutString(traderVo.getTeamProfit14()));
            traderVo.setProfitAmountString(TraderConfiguration.getSpecialTraderAmoutString(traderVo.getProfitAmount()));
        });
        page.setRecords(list);
        return page;
    }

    private List<YieldVo> dayYield14Trans(List<YieldVo> list, TraderVo traderVo) {
        FollowConfig followConfig = followConfigServiceImpl.getConfig(FollowConfigEnum.DAY_YEILD_14_IS_MULTIPLY_14.getNameEn());
        boolean isMultiply14 = followConfig != null
                && StringUtils.isNotEmpty(followConfig.getConfigContent())
                && "1".equals(followConfig.getConfigContent());
        if (isMultiply14) {
            traderVo.setDayYield14(traderVo.getDayYield14() == null ? new BigDecimal(0) : traderVo.getDayYield14().multiply(new BigDecimal(14)));
            list.forEach(yieldVo -> yieldVo.setDayYield14(yieldVo.getDayYield14() == null ? new BigDecimal(0) : yieldVo.getDayYield14().multiply(new BigDecimal(14))));
        }
        return list;
    }

    @Override
    public Boolean isFavorite(Long customerId, Long traderId) {
        QueryWrapper<Favorite> favoriteQueryWrapper = new QueryWrapper<>();
        favoriteQueryWrapper.eq("customer_id",customerId)
                .eq("trader_id",traderId);
        Favorite favorite = getOne(favoriteQueryWrapper);
        if(favorite == null){
            return false;
        }
        return true;
    }
}
