package com.hzs.member.account.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzs.common.core.constant.MagicNumberConstants;
import com.hzs.common.core.constant.MemberFieldConstants;
import com.hzs.common.core.enums.EAccount;
import com.hzs.common.core.utils.reflect.ReflectUtils;
import com.hzs.common.domain.member.account.CuMemberAccountDetail;
import com.hzs.common.domain.member.account.CuMemberAccountDetailExt;
import com.hzs.common.domain.system.config.BdAccount;
import com.hzs.member.account.mapper.CuMemberAccountDetailMapper;
import com.hzs.member.account.service.ICuMemberAccountDetailService;
import com.hzs.member.account.service.ICuMemberBaseService;
import com.hzs.member.account.vo.CuMemberAccountDetailLookExtVO;
import com.hzs.member.account.vo.CuMemberAccountDetailLookVO;
import com.hzs.member.account.vo.CuMemberAccountDetailVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 会员账户详情 服务实现类
 */
@Service
@Slf4j
public class CuMemberAccountDetailServiceImpl extends ServiceImpl<CuMemberAccountDetailMapper, CuMemberAccountDetail> implements ICuMemberAccountDetailService {

    @Autowired
    private ICuMemberBaseService iCuMemberBaseService;

    @Override
    public Object[] findAccountDetailList(CuMemberAccountDetailVO memberAccountDetailVO) {
        CuMemberAccountDetailVO cuMemberAccountDetailVO;
        List<CuMemberAccountDetailVO> memberAccountDetailVOList = new ArrayList<>();
        Integer pkCountry = memberAccountDetailVO.getPkCountry();
        List<CuMemberAccountDetail> memberAccountDetailList = baseMapper.selectAccountDetailList(memberAccountDetailVO);
        if (CollUtil.isNotEmpty(memberAccountDetailList)) {
            //币种值
            List<BdAccount> allAccounts = iCuMemberBaseService.getAccountByCountryId(pkCountry);
            Map<Integer, BdAccount> map = allAccounts.stream().collect(Collectors.toMap(BdAccount::getFieldValue, o -> o));
            //汇率
            BigDecimal exchangeRate = iCuMemberBaseService.getCurrency(pkCountry).getInExchangeRate();
            for (CuMemberAccountDetail cuMemberAccountDetail : memberAccountDetailList) {
                cuMemberAccountDetailVO = new CuMemberAccountDetailVO();
                BeanUtils.copyProperties(cuMemberAccountDetail, cuMemberAccountDetailVO);
                for (BdAccount bdAccount : allAccounts) {
                    Integer value = bdAccount.getFieldValue();
                    BigDecimal account = ReflectUtils.invokeGetter(cuMemberAccountDetailVO, MemberFieldConstants.ACCOUNT + value);
                    if (null != account) {
                        BigDecimal settleAccount = account.divide(exchangeRate, 4, RoundingMode.HALF_UP);
                        ReflectUtils.invokeSetter(cuMemberAccountDetailVO, MemberFieldConstants.SETTLE_ACCOUNT + value, settleAccount);
                    }
                }
                noIncludeAccount(cuMemberAccountDetailVO, map);
                memberAccountDetailVOList.add(cuMemberAccountDetailVO);
            }
        }
        return new Object[]{memberAccountDetailList, memberAccountDetailVOList};

    }

    /**
     * 根据账户配置 （没有配置不显示）
     *
     * @param cuMemberAccountDetail 账户详情
     * @param map                   账户配置
     */
    private void noIncludeAccount(CuMemberAccountDetailVO cuMemberAccountDetail, Map<Integer, BdAccount> map) {
        for (int i = 1; i < MagicNumberConstants.ACC0UNT_NUM + 1; i++) {
            if (null == map.get(i)) {
                ReflectUtils.invokeSetter(cuMemberAccountDetail, MemberFieldConstants.ACCOUNT + i, null);
            }
        }
    }


    @Override
    public Object[] selectAccountDetailLookList(CuMemberAccountDetailLookVO memberAccountDetailLookVO) {
        CuMemberAccountDetailLookExtVO detailLookExtVO;
        List<CuMemberAccountDetailLookExtVO> detailLookExtVOList = new ArrayList<>();
        List<CuMemberAccountDetailExt> cuMemberAccountDetailExtList = baseMapper.selectAccountDetailLookList(memberAccountDetailLookVO);
        if (CollUtil.isNotEmpty(cuMemberAccountDetailExtList)) {
            List<Integer> pkAccounts = memberAccountDetailLookVO.getPkAccounts();
            Integer pkCountry = memberAccountDetailLookVO.getPkCountry();
            //币种
            List<Integer> allAccounts = iCuMemberBaseService.getAccountValuesByPkCountry(pkCountry);
            List<BdAccount> allBdAccount = iCuMemberBaseService.getAccountByCountryId(pkCountry);
            Map<Integer, BdAccount> map = allBdAccount.stream().collect(Collectors.toMap(BdAccount::getFieldValue, o -> o));
            pkAccounts = CollUtil.isEmpty(pkAccounts) ? allAccounts : pkAccounts;
            for (CuMemberAccountDetailExt cuMemberAccountDetailExt : cuMemberAccountDetailExtList) {
                detailLookExtVO = BeanUtil.copyProperties(cuMemberAccountDetailExt, CuMemberAccountDetailLookExtVO.class);
                getCuMemberAccountExtVO(detailLookExtVO, pkAccounts, allAccounts);
                //不在配置中的账户不显示
                for (int i = 1; i < MagicNumberConstants.ACC0UNT_NUM + 1; i++) {
                    if (null == map.get(i)) {
                        ReflectUtils.invokeSetter(detailLookExtVO, MemberFieldConstants.ACCOUNT + i, null);
                        //10以上的账户没有以下两个属性
                        if (i <= MagicNumberConstants.ACC0UNT_LOCK_NUM) {
                            ReflectUtils.invokeSetter(detailLookExtVO, MemberFieldConstants.LOCK_ACCOUNT + i, null);
                            ReflectUtils.invokeSetter(detailLookExtVO, MemberFieldConstants.LOCK_TRANSFER_ACCOUNT + i, null);
                        }
                    }
                }
                detailLookExtVOList.add(detailLookExtVO);
            }
        }
        return new Object[]{cuMemberAccountDetailExtList, detailLookExtVOList};
    }


    /**
     * 根据前端选择的币种返回显示内容
     *
     * @param accountDetailLookVO 账户信息
     * @param pkAccounts          前端选择的币种
     * @param allAccounts         配置中的币种
     * @return CuMemberAccountExtVO
     */
    private CuMemberAccountDetailLookExtVO getCuMemberAccountExtVO(CuMemberAccountDetailLookExtVO accountDetailLookVO, List<Integer> pkAccounts, List<Integer> allAccounts) {
        //汇率
        BigDecimal exchangeRate = iCuMemberBaseService.getCurrencyById(accountDetailLookVO.getPkRate()).getInExchangeRate();
        for (Integer pkAccount : pkAccounts) {
            //币种
            BigDecimal account = ReflectUtils.invokeGetter(accountDetailLookVO, MemberFieldConstants.ACCOUNT + pkAccount);
            BigDecimal settleAccount = account.divide(exchangeRate, 4, RoundingMode.HALF_UP);
            ReflectUtils.invokeSetter(accountDetailLookVO, MemberFieldConstants.SETTLE_ACCOUNT + pkAccount, settleAccount);

            BigDecimal availableAccount;
            if (pkAccount < EAccount.LIVE_CASH_COUPON.getValue()) {
                //锁定消费
                BigDecimal lockConsume = ReflectUtils.invokeGetter(accountDetailLookVO, MemberFieldConstants.LOCK_ACCOUNT + pkAccount);
                BigDecimal settleLockConsume = lockConsume.divide(exchangeRate, 4, RoundingMode.HALF_UP);
                ReflectUtils.invokeSetter(accountDetailLookVO, MemberFieldConstants.LOCK_SETTLE_ACCOUNT + pkAccount, settleLockConsume);

                //锁定转账
                BigDecimal lockTransfer = ReflectUtils.invokeGetter(accountDetailLookVO, MemberFieldConstants.LOCK_TRANSFER_ACCOUNT + pkAccount);
                BigDecimal settleLockTransfer = lockTransfer.divide(exchangeRate, 4, RoundingMode.HALF_UP);
                ReflectUtils.invokeSetter(accountDetailLookVO, MemberFieldConstants.LOCK_SETTLE_TRANSFER_ACCOUNT + pkAccount, settleLockTransfer);

                //可用金额
                availableAccount = account.subtract(lockConsume).subtract(lockTransfer);
            } else {
                availableAccount = account;
            }

            //锁定提现
            if (pkAccount.equals(EAccount.BONUS.getValue())) {
                BigDecimal lockWithdraw = ReflectUtils.invokeGetter(accountDetailLookVO, MemberFieldConstants.LOCK_WITHDRAW_ACCOUNT + pkAccount);
                availableAccount = availableAccount.subtract(lockWithdraw);

                BigDecimal settleLockWithdraw = lockWithdraw.divide(exchangeRate, 4, RoundingMode.HALF_UP);
                ReflectUtils.invokeSetter(accountDetailLookVO, MemberFieldConstants.LOCK_SETTLE_WITHDRAW_ACCOUNT + pkAccount, settleLockWithdraw);
            }
            //可用金额
            ReflectUtils.invokeSetter(accountDetailLookVO, MemberFieldConstants.AVAILABLE_ACCOUNT + pkAccount, availableAccount);

            BigDecimal settleAvailableAccount = availableAccount.divide(exchangeRate, 4, RoundingMode.HALF_UP);
            ReflectUtils.invokeSetter(accountDetailLookVO, MemberFieldConstants.SETTLE_AVAILABLE_ACCOUNT + pkAccount, settleAvailableAccount);
        }

        //末选中的币种 置为null 前台不显示
        allAccounts.removeAll(pkAccounts);
        for (Integer account : allAccounts) {
            ReflectUtils.invokeSetter(accountDetailLookVO, MemberFieldConstants.ACCOUNT + account, null);
            if (account <= MagicNumberConstants.ACC0UNT_LOCK_NUM) {
                ReflectUtils.invokeSetter(accountDetailLookVO, MemberFieldConstants.LOCK_ACCOUNT + account, null);
                ReflectUtils.invokeSetter(accountDetailLookVO, MemberFieldConstants.LOCK_TRANSFER_ACCOUNT + account, null);
            }
            if (account.equals(EAccount.BONUS.getValue())) {
                ReflectUtils.invokeSetter(accountDetailLookVO, MemberFieldConstants.LOCK_WITHDRAW_ACCOUNT + account, null);
            }
        }
        return accountDetailLookVO;
    }


    @Override
    public Integer insertAccountDetail() {
        return baseMapper.insertAccountDetail();
    }

    @Override
    public Integer deleteAccountDetailByMonth() {
        return baseMapper.deleteAccontDetailByMonth();
    }
}
