package cn.com.poc.equity.aggregate.impl;

import cn.com.poc.common.constant.CommonConstant;
import cn.com.poc.common.utils.DateUtils;
import cn.com.poc.common.utils.JsonUtils;
import cn.com.poc.common.utils.StringUtils;
import cn.com.poc.equity.aggregate.EquityService;
import cn.com.poc.equity.constants.EquityEnum;
import cn.com.poc.equity.domain.AgentEquity;
import cn.com.poc.equity.entity.BizMemberEquityPayOrderLogEntity;
import cn.com.poc.equity.entity.BizPaymentPackageConfigurationEntity;
import cn.com.poc.equity.entity.CurrentUserPayOrderEntity;
import cn.com.poc.equity.service.BizMemberEquityPayOrderLogService;
import cn.com.poc.equity.service.BizPaymentPackageConfigurationService;
import cn.com.poc.thirdparty.resource.demand.dgTools.constants.CurrencyEnum;
import cn.com.poc.thirdparty.resource.demand.pay.entity.DgtoolsPayOrderEntity;
import cn.com.poc.thirdparty.resource.demand.pay.service.DgtoolsPayOrderService;
import cn.com.yict.framemax.core.i18n.I18nMessageException;
import cn.com.yict.framemax.data.model.PagingInfo;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
public class EquityServiceImpl implements EquityService {

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

    @Resource
    private BizPaymentPackageConfigurationService bizPaymentPackageConfigurationService;

    @Resource
    private DgtoolsPayOrderService dgtoolsPayOrderService;

    @Resource
    private BizMemberEquityPayOrderLogService bizMemberEquityPayOrderLogService;

    @Override
    public List<AgentEquity> getEquityList(EquityEnum.TYPE type) {
        List<AgentEquity> result = new ArrayList<>();
        BizPaymentPackageConfigurationEntity bizPaymentPackageConfigurationEntity = new BizPaymentPackageConfigurationEntity();
        bizPaymentPackageConfigurationEntity.setType(type.name());
        bizPaymentPackageConfigurationEntity.setDomain(EquityEnum.DOMAIN.equity.name());
        bizPaymentPackageConfigurationEntity.setIsDeleted(CommonConstant.IsDeleted.N);
        List<BizPaymentPackageConfigurationEntity> entities = bizPaymentPackageConfigurationService.findByExample(bizPaymentPackageConfigurationEntity, null);
        if (CollectionUtils.isNotEmpty(entities)) {
            for (BizPaymentPackageConfigurationEntity entity : entities) {
                AgentEquity agentEquity = new AgentEquity();
                String extraData = entity.getExtraData();
                if (StringUtils.isNotBlank(extraData)) {
                    agentEquity = JsonUtils.deSerialize(extraData, AgentEquity.class);
                }
                agentEquity.setAmount(new BigDecimal(entity.getAmount()).divide(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP));
                agentEquity.setPoints(entity.getResourceCount().longValue());
                agentEquity.setValidityUnit(EquityEnum.VALIDITY_UNIT.valueOf(entity.getExpiredType()));
                result.add(agentEquity);
            }
        }
        return result;
    }

    @Override
    public List<BizPaymentPackageConfigurationEntity> getPointList() {
        BizPaymentPackageConfigurationEntity bizPaymentPackageConfigurationEntity = new BizPaymentPackageConfigurationEntity();
        bizPaymentPackageConfigurationEntity.setDomain(EquityEnum.DOMAIN.point.name());
        bizPaymentPackageConfigurationEntity.setIsDeleted(CommonConstant.IsDeleted.N);
        List<BizPaymentPackageConfigurationEntity> entities = bizPaymentPackageConfigurationService.findByExample(bizPaymentPackageConfigurationEntity, null);
        return entities;
    }

    @Override
    public String createEquityOrder(EquityEnum.TYPE type, EquityEnum.DOMAIN domain, EquityEnum.VALIDITY_UNIT validityUnit, Long memberId) throws Exception {
        logger.info("创建权益订单,type:{},domain:{},validity_unit:{},member_id:{}", type, domain, validityUnit, memberId);
        BizPaymentPackageConfigurationEntity bizPaymentPackageConfigurationEntity = new BizPaymentPackageConfigurationEntity();
        bizPaymentPackageConfigurationEntity.setType(type.name());
        bizPaymentPackageConfigurationEntity.setDomain(domain.name());
        bizPaymentPackageConfigurationEntity.setExpiredType(validityUnit.name());
        bizPaymentPackageConfigurationEntity.setIsDeleted(CommonConstant.IsDeleted.N);
        List<BizPaymentPackageConfigurationEntity> paymentPackageConfigurationEntities = bizPaymentPackageConfigurationService.findByExample(bizPaymentPackageConfigurationEntity, null);
        if (CollectionUtils.isEmpty(paymentPackageConfigurationEntities)) {
            throw new I18nMessageException("exception/payment.package.configuration.not.exist");
        }
        BizPaymentPackageConfigurationEntity packageConfiguration = paymentPackageConfigurationEntities.get(0);
        DgtoolsPayOrderEntity dgtoolsPayOrderEntity = new DgtoolsPayOrderEntity();
        dgtoolsPayOrderEntity.setAmount(packageConfiguration.getAmount());
        dgtoolsPayOrderEntity.setPayOrderType(domain.name());
        dgtoolsPayOrderEntity.setMemberId(memberId.intValue());
        dgtoolsPayOrderEntity.setCurrency(CurrencyEnum.CHINA.getCurrencyCode());
        dgtoolsPayOrderEntity.setDescription(packageConfiguration.getName());
        dgtoolsPayOrderEntity.setRetainInformation(JsonUtils.serialize(packageConfiguration));

        // 创建支付订单-支付中台
        DgtoolsPayOrderEntity payOrder = dgtoolsPayOrderService.createPayOrder(dgtoolsPayOrderEntity, memberId);
        logger.info("创建支付订单,pay_order:{}", JsonUtils.serialize(payOrder));
        return payOrder.getPayOrderSn();
    }

    @Override
    public List<CurrentUserPayOrderEntity> getUserOrderList(Long memberId, EquityEnum.DOMAIN domain, PagingInfo pagingInfo) {
        List<CurrentUserPayOrderEntity> currentUserPayOrderEntities = new ArrayList<>();
        BizMemberEquityPayOrderLogEntity bizMemberEquityPayOrderLogEntity = new BizMemberEquityPayOrderLogEntity();
        bizMemberEquityPayOrderLogEntity.setMemberId(memberId);
        bizMemberEquityPayOrderLogEntity.setDomain(domain.name());
        bizMemberEquityPayOrderLogEntity.setIsDeleted(CommonConstant.IsDeleted.N);
        List<BizMemberEquityPayOrderLogEntity> payOrderLogEntities = bizMemberEquityPayOrderLogService.findByExample(bizMemberEquityPayOrderLogEntity, pagingInfo);
        Date currDateTime = DateUtils.getCurrDateTime();
        if (CollectionUtils.isNotEmpty(payOrderLogEntities)) {
            for (BizMemberEquityPayOrderLogEntity payOrderLogEntity : payOrderLogEntities) {
                CurrentUserPayOrderEntity currentUserPayOrderEntity = new CurrentUserPayOrderEntity();
                currentUserPayOrderEntity.setType(EquityEnum.TYPE.valueOf(payOrderLogEntity.getType()));
                currentUserPayOrderEntity.setDomain(domain);
                currentUserPayOrderEntity.setExpiredNum(payOrderLogEntity.getExpiredNum());
                currentUserPayOrderEntity.setExpiredType(EquityEnum.VALIDITY_UNIT.valueOf(payOrderLogEntity.getExpiredType()));
                currentUserPayOrderEntity.setPointNum(new BigDecimal(payOrderLogEntity.getTotalPoints()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP));
                currentUserPayOrderEntity.setRemainExpiredDay(calculateRemainExpiredDay(currDateTime, payOrderLogEntity.getPayTime(), payOrderLogEntity.getExpiredNum(), EquityEnum.VALIDITY_UNIT.valueOf(payOrderLogEntity.getExpiredType())));
                currentUserPayOrderEntity.setAmount(new BigDecimal(payOrderLogEntity.getPayAmount()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP));
                currentUserPayOrderEntity.setPayTime(DateUtils.formatDate(payOrderLogEntity.getPayTime(), DateUtils.yyyy_MM_dd_HH_mm_ss));
                currentUserPayOrderEntity.setPayChannel(payOrderLogEntity.getPayChannel());
                currentUserPayOrderEntity.setPayOrderSn(payOrderLogEntity.getPayOrderSn());
                currentUserPayOrderEntities.add(currentUserPayOrderEntity);
            }
        }
        return currentUserPayOrderEntities;
    }

    /**
     * 计算剩余有效天数
     *
     * @param now
     * @param payTime
     * @param expiredNum
     * @param validityUnit
     * @return -1 表示永久有效, 0 表示已过期 , >0 表示剩余有效天数
     */
    private Integer calculateRemainExpiredDay(Date now, Date payTime, Integer expiredNum, EquityEnum.VALIDITY_UNIT validityUnit) {
        int diff = 0;
        Date expiredDate = new Date();
        switch (validityUnit) {
            case month:
                expiredDate = DateUtils.addMonth(payTime, expiredNum);
                diff = DateUtils.diffTwoDateDay(expiredDate, now);
                break;
            case year:
                expiredDate = DateUtils.addYear(payTime, expiredNum);
                diff = DateUtils.diffTwoDateDay(expiredDate, now);
                break;
            case indefinite:
                return -2;
        }
        if (now.after(expiredDate)) {
            return -1;
        }
        return diff;
    }
}