package com.tmerclub.cloud.user.feign;

import cn.hutool.core.date.DateUtil;
import com.tmerclub.cloud.api.order.constant.FinanceType;
import com.tmerclub.cloud.api.payment.constant.PaySysType;
import com.tmerclub.cloud.api.payment.vo.ShopAccountDetailVO;
import com.tmerclub.cloud.api.platform.feign.ConfigFeignClient;
import com.tmerclub.cloud.api.user.bo.BalancePayBO;
import com.tmerclub.cloud.api.user.bo.BalanceRefundBO;
import com.tmerclub.cloud.api.user.dto.FinanceDetailDTO;
import com.tmerclub.cloud.api.user.feign.UserBalanceLogFeignClient;
import com.tmerclub.cloud.api.user.vo.FinanceDetailExcelVO;
import com.tmerclub.cloud.api.user.vo.FinanceDetailVO;
import com.tmerclub.cloud.api.user.vo.UserPayInfoVO;
import com.tmerclub.cloud.common.constant.Constant;
import com.tmerclub.cloud.common.database.dto.PageDTO;
import com.tmerclub.cloud.common.database.util.PageUtil;
import com.tmerclub.cloud.common.database.vo.PageVO;
import com.tmerclub.cloud.common.leaf.manager.SegmentManager;
import com.tmerclub.cloud.common.response.ServerResponseEntity;
import com.tmerclub.cloud.common.security.AuthUserContext;
import com.tmerclub.cloud.user.bo.mongo.MongoUserBalanceLogBO;
import com.tmerclub.cloud.user.constant.DistributedIdKey;
import com.tmerclub.cloud.user.constant.RechargeIoTypeEnum;
import com.tmerclub.cloud.user.constant.RechargeTypeEnum;
import com.tmerclub.cloud.user.service.UserBalanceLogService;
import com.tmerclub.cloud.user.service.UserExtensionService;
import com.tmerclub.cloud.user.service.UserLevelLogService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

/**
 * 充值信息
 *
 * @author tmerclub
 */
@DubboService
public class UserBalanceLogFeignController implements UserBalanceLogFeignClient {

    @Autowired
    private UserBalanceLogService userBalanceLogService;
    @Autowired
    private UserLevelLogService userLevelLogService;
    @Autowired
    private SegmentManager segmentManager;
    @DubboReference
    private ConfigFeignClient configFeignClient;
    @Autowired
    private UserExtensionService userExtensionService;

    @Override
    public ServerResponseEntity<Long> getPayAmount(Long rechargeLogId) {
        MongoUserBalanceLogBO userBalanceLog = userBalanceLogService.getByBalanceLogId(rechargeLogId);
        return ServerResponseEntity.success(userBalanceLog.getChangeBalance());
    }

    @Override
    public ServerResponseEntity<Integer> getIsPay(Long rechargeLogId) {
        MongoUserBalanceLogBO userBalanceLog = userBalanceLogService.getByBalanceLogId(rechargeLogId);
        return ServerResponseEntity.success(userBalanceLog.getIsPayed());
    }

    @Override
    public ServerResponseEntity<Void> insertBalancePayLog(BalancePayBO balancePayBO) {
        Long userId = AuthUserContext.get().getUserId();
        MongoUserBalanceLogBO userBalanceLog = new MongoUserBalanceLogBO();
        userBalanceLog.setBalanceLogId(segmentManager.getSegmentId(DistributedIdKey.tmerclub_USER_BALANCE_LOG));
        userBalanceLog.setUserId(userId);
        userBalanceLog.setChangeBalance(balancePayBO.getChangeBalance());
        userBalanceLog.setIoType(RechargeIoTypeEnum.EXPENDITURE.value());
        if (Objects.nonNull(balancePayBO.getIsVip()) && Objects.equals(balancePayBO.getIsVip(), true)) {
            userBalanceLog.setType(RechargeTypeEnum.VIP.value());
        } else {
            userBalanceLog.setType(RechargeTypeEnum.PAY.value());
        }
        userBalanceLog.setIsPayed(0);
        userBalanceLog.setPayId(balancePayBO.getPayId());
        userBalanceLog.setPaySysType(balancePayBO.getPaySysType());
        userBalanceLogService.saveToMongdb(userBalanceLog);
        return ServerResponseEntity.success();
    }

    @Override
    public ServerResponseEntity<Void> doRefund(BalanceRefundBO balanceRefundBO) {
        userBalanceLogService.doRefund(balanceRefundBO);
        return ServerResponseEntity.success();
    }

    @Override
    public ServerResponseEntity<PageVO<FinanceDetailVO>> pageFinanceDetail(FinanceDetailDTO financeDetailDTO) {
        PageDTO pageDTO = new PageDTO();
        pageDTO.setPageSize(financeDetailDTO.getPageSize());
        pageDTO.setPageNum(financeDetailDTO.getPageNum());
        financeDetailDTO.setPaySysType(configFeignClient.getPaySysType().getData());
        PageVO<FinanceDetailVO> result = userBalanceLogService.pageFinanceDetail(pageDTO, financeDetailDTO);
        return ServerResponseEntity.success(result);
    }

    @Override
    public ServerResponseEntity<List<FinanceDetailExcelVO>> listFinanceDetail(FinanceDetailDTO financeDetailDTO) {
        List<FinanceDetailExcelVO> listFinanceDetail = userBalanceLogService.listFinanceDetail(financeDetailDTO);
        return ServerResponseEntity.success(listFinanceDetail);
    }

    @Override
    public ServerResponseEntity<ShopAccountDetailVO> getPlatformAccountDetail(Date startTime, Date endTime) {
        ShopAccountDetailVO shopAccountDetailVO = userBalanceLogService.getPlatformAccountDetail(startTime, endTime);
        return ServerResponseEntity.success(shopAccountDetailVO);
    }

    @Override
    public ServerResponseEntity<PageVO<UserPayInfoVO>> pageUserPayInfo(Date startTime, Date endTime, Integer financeType, Integer pageSize, Integer pageNum) {
        PageDTO pageDTO = new PageDTO();
        pageDTO.setPageSize(pageSize);
        pageDTO.setPageNum(pageNum);
        PageVO<UserPayInfoVO> pageVO = new PageVO<>();
        if (Objects.equals(financeType, FinanceType.RECHARGE.value())) {
            pageVO = userBalanceLogService.pagePayInfoVO(startTime, endTime, pageDTO);
        } else if (Objects.equals(financeType, FinanceType.LEVEL.value())) {
            pageVO = PageUtil.doPage(pageDTO, () -> userLevelLogService.listPayInfoVO(startTime, endTime));
        }
        return ServerResponseEntity.success(pageVO);
    }

    @Override
    public ServerResponseEntity<List<UserPayInfoVO>> listUserPayInfo(Date startTime, Date endTime, Integer financeType) {
        List<UserPayInfoVO> result = new ArrayList<>(Constant.INITIAL_CAPACITY);
        if (Objects.equals(financeType, FinanceType.RECHARGE.value())) {
            result = userBalanceLogService.listPayInfoVO(startTime, endTime);
        } else if (Objects.equals(financeType, FinanceType.LEVEL.value())) {
            result = userLevelLogService.listPayInfoVO(startTime, endTime);
        }
        return ServerResponseEntity.success(result);
    }

    @Override
    public ServerResponseEntity<Void> updateToOrderPaySuccess(Long payId) {
        MongoUserBalanceLogBO userBalanceLog = userBalanceLogService.getByPayId(payId);
        userBalanceLogService.updateToOrderPaySuccess(payId, userBalanceLog);
        return ServerResponseEntity.success();
    }

    @Override
    public ServerResponseEntity<Void> sellCueUpdateBalance(Long userId, Long money) {
        // 修改余额
        userExtensionService.updateBatchUserBalanceByUserIds(Collections.singletonList(userId), money, DateUtil.date());
        // 创建日志
        List<MongoUserBalanceLogBO> userBalanceLogs = new ArrayList<>(Constant.INITIAL_CAPACITY);
        List<Long> userBalanceLogIds = segmentManager.listSegmentId(DistributedIdKey.tmerclub_USER_BALANCE_LOG, 1);
        MongoUserBalanceLogBO userBalanceLog = new MongoUserBalanceLogBO();
        userBalanceLog.setBalanceLogId(userBalanceLogIds.get(0));
        userBalanceLog.setUserId(userId);
        userBalanceLog.setChangeBalance(money);
        userBalanceLog.setPaySysType(PaySysType.DEFAULT.value());
        userBalanceLog.setIoType(RechargeIoTypeEnum.INCOME.value());
        userBalanceLog.setType(RechargeTypeEnum.SELL.value());
        userBalanceLogs.add(userBalanceLog);
        userBalanceLogService.saveBatchToMongodb(userBalanceLogs);
        return ServerResponseEntity.success();
    }

}
