package com.fdkankan.ucenter.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fdkankan.common.constant.ErrorCode;
import com.fdkankan.common.constant.SceneConstant;
import com.fdkankan.common.exception.BusinessException;
import com.fdkankan.ucenter.common.PageInfo;
import com.fdkankan.ucenter.common.SkuEnum;
import com.fdkankan.ucenter.common.constants.ResultCodeMsg;
import com.fdkankan.ucenter.constant.LoginConstant;
import com.fdkankan.ucenter.constant.OrderConstant;
import com.fdkankan.ucenter.entity.*;
import com.fdkankan.ucenter.httpClient.param.PayAutoPayVo;
import com.fdkankan.ucenter.httpClient.param.PayGoods;
import com.fdkankan.ucenter.httpClient.service.PayService;
import com.fdkankan.ucenter.httpClient.vo.PayOrderVo;
import com.fdkankan.ucenter.mapper.IIncrementOrderMapper;
import com.fdkankan.ucenter.pay.paypal.sdk.AutoPaypalVo;
import com.fdkankan.ucenter.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fdkankan.ucenter.util.DateUserUtil;
import com.fdkankan.ucenter.vo.request.DownNumParam;
import com.fdkankan.ucenter.vo.request.IncrementOrderParam;
import com.fdkankan.ucenter.vo.request.OrderParam;
import com.fdkankan.ucenter.vo.response.GoodsSkuVo;
import com.fdkankan.ucenter.vo.response.IncrementOrderVo;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
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.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 增值权益订单表 服务实现类
 * </p>
 *
 * @author 
 * @since 2022-07-13
 */
@Service
public class IncrementOrderServiceImpl extends ServiceImpl<IIncrementOrderMapper, IncrementOrder> implements IIncrementOrderService {

    @Autowired
    IUserService userService;
    @Autowired
    IInvoiceService invoiceService;
    @Autowired
    IUserIncrementService userIncrementService;
    @Autowired
    IGoodsSkuService goodsSkuService;
    @Autowired
    IIncrementTypeService incrementTypeService;
    @Autowired
    IIncrementAutoOrderService incrementAutoOrderService;

    @Override
    public PageInfo pageList(IncrementOrderParam param) {
        User user = userService.getByUserName(param.getUserName());
        LambdaQueryWrapper<IncrementOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(IncrementOrder::getUserId,user.getId());
        wrapper.eq(IncrementOrder::getPayStatus,1);
        wrapper.orderByDesc(IncrementOrder::getTradeTime);
        Page<IncrementOrder> page = this.page(new Page<>(param.getPageNum(), param.getPageSize()), wrapper);

        List<IncrementOrderVo> listVo  =new ArrayList<>();

        Set<String> orderSn = page.getRecords().stream().map(IncrementOrder::getOrderSn).collect(Collectors.toSet());
        Set<Long> ids = page.getRecords().stream().map(IncrementOrder::getId).collect(Collectors.toSet());
        HashMap<String,List<Long>> map = userIncrementService.getByOrderSnList(orderSn);
        HashMap<Long,Invoice> invoiceHashMap = invoiceService.getByIncrementOrderIds(ids);
        for (IncrementOrder record : page.getRecords()) {
            if(StringUtils.isNotBlank(record.getTradeTime())){
                record.setTradeTime(DateUserUtil.AddMinute(record.getTradeTime(),record.getTimeZoneOff()));
            }
            Invoice invoice = invoiceHashMap.get(record.getId());
            IncrementOrderVo vo = new IncrementOrderVo();
            BeanUtils.copyProperties(record,vo);
            vo.setIncrementIds(map.get(record.getOrderSn()));
            vo.setInvoice(invoice);
            listVo.add(vo);
        }
        Page<IncrementOrderVo> pageVo = new Page<>(param.getPageNum(),param.getPageSize());
        pageVo.setRecords(listVo);
        pageVo.setTotal(page.getTotal());
        return PageInfo.PageInfo(pageVo);
    }

    @Override
    public GoodsSkuVo getDownloadPrice(OrderParam param) {
        if(param.getDateType() == null){
            throw new BusinessException(LoginConstant.FAILURE_CODE_3001, LoginConstant.FAILURE_MSG_3001);
        }
        // 5 专业会员，6 下载 ， 7 高级会员
        if(param.getDateType() != 6 && param.getIncrementTypeId() == null && param.getUserIncrementId() == null){
            throw new BusinessException(SceneConstant.FAILURE_CODE_5012, SceneConstant.FAILURE_MSG_5012);
        }
        return getGoodsSkuVo(param.getDateType(), param.getUserIncrementId(),param.getMonthQy(),param.getIncrementTypeId());

    }

    private GoodsSkuVo getGoodsSkuVo (Integer dateType,Integer userIncrementId,Integer monthDy,Integer incrementTypeId){
        GoodsSkuVo goodsSkuVo = new GoodsSkuVo();
        if(userIncrementId != null){
            UserIncrement userIncrement = userIncrementService.getById(userIncrementId);
            incrementTypeId = userIncrement.getIncrementTypeId();
        }
        IncrementType incrementType = null;
        if(incrementTypeId != null){       //购买会员
            incrementType = incrementTypeService.getById(incrementTypeId);
            if(incrementType == null){
                throw new BusinessException(ErrorCode.MISSING_REQUIRED_PARAMETERS);
            }
            goodsSkuVo.setPrice(incrementType.getPrice());
            goodsSkuVo.setSkuSn(incrementType.getId().toString());
            goodsSkuVo.setDeadLine(getDateTime(incrementType,userIncrementId,monthDy).toDate().getTime());
            return goodsSkuVo;
        }
        if(dateType == 6){ //下载场景
            incrementType = incrementTypeService.list().get(0);
            goodsSkuVo.setPrice(incrementType.getDownloadPrice());
            goodsSkuVo.setSkuSn(incrementType.getId().toString());
            goodsSkuVo.setDeadLine(getDateTime(incrementType,userIncrementId,monthDy).toDate().getTime());
            return goodsSkuVo;
        }

        return goodsSkuVo;
    }

    @Override
    public DateTime getDateTime(IncrementType incrementType, Integer userIncrementId,Integer count) {
        Date userTime = new Date();
        if(userIncrementId != null){
            UserIncrement userIncrement = userIncrementService.getById(userIncrementId);
            userTime = DateUserUtil.getDate(userIncrement.getIncrementEndTime());
        }
        return  DateUserUtil.getDateTime(userTime, incrementType,count);
    }


    public GoodsSkuVo getIncrementOrDownloadPrice(Integer dateType)  {
        String skuStr = SkuEnum.skusMap.get(String.valueOf(dateType));
        if (StringUtils.isEmpty(skuStr)){
            skuStr = SkuEnum.skusMap.get("5");
        }

        GoodsSkuVo responseGoodsSku = new GoodsSkuVo();
        GoodsSku goodsSkuEntity = goodsSkuService.getBySku(skuStr);
        BeanUtils.copyProperties(goodsSkuEntity, responseGoodsSku);

        return responseGoodsSku;
    }
    @Autowired
    PayService payService;

    @Override
    public IncrementOrder insertIncrementOrder(User user, DownNumParam param,IncrementType incrementType) {

        BigDecimal total = incrementType.getPrice().multiply(new BigDecimal(param.getCount()));
        if(param.getMonthQy() != null){
            total = total.multiply(new BigDecimal(param.getMonthQy()));  //高级会员月份
        }
        if(param.getIncrementId() != null){
            IncrementAutoOrder autoOrder2 =  incrementAutoOrderService.getByIncrementId(param.getIncrementId());
            if(autoOrder2 != null){
                throw new BusinessException(ResultCodeMsg.FAILURE_CODE_400007, ResultCodeMsg.FAILURE_MSG_400007);
            }
        }

        IncrementOrder incrementOrderEntity = new IncrementOrder();
        PayAutoPayVo autoPayVo = null;
        String autoStartTime = null;
        String autoPayTime = null;
        UserIncrement userIncrement = null;
        if(param.getAutoPay() != null && param.getAutoPay() == 1){
            if(param.getIncrementId() != null){
                userIncrement = userIncrementService.getById(param.getIncrementId());
                if(userIncrement != null){
                    autoStartTime = userIncrement.getIncrementEndTime();
                }
            }
        }
        if(incrementType.getValidTimeType() == 0){
            incrementOrderEntity.setMemberLevels("PR");
            autoPayTime = "YEAR";
        }
        if(incrementType.getValidTimeType() == 1){
            incrementOrderEntity.setMemberLevels("SE");
            autoPayTime = "MONTH";
        }
        autoPayVo =new PayAutoPayVo(param.getAutoPay(),autoPayTime,autoStartTime);
        PayGoods payGoods = new PayGoods(incrementType.getName(),param.getCount(),incrementType.getValidTimeType(),param.getMonthQy());
        PayOrderVo payOrderVo = payService.downOrder(total, "incrementOrder",user.getUserName(),user.getNickName(), Arrays.asList(payGoods),autoPayVo);
        if(payOrderVo == null){
            throw new BusinessException(OrderConstant.FAILURE_CODE_8005,OrderConstant.FAILURE_MSG_8005);
        }

        incrementOrderEntity.setOrderSn(payOrderVo.getOrderSn());
        incrementOrderEntity.setAmount(total);
        incrementOrderEntity.setPayType(param.getPayType());
        incrementOrderEntity.setPayStatus(-1);
        incrementOrderEntity.setUserId(user.getId());
        incrementOrderEntity.setCount(param.getCount());
        incrementOrderEntity.setAbroad(param.getAbroad());
        incrementOrderEntity.setStatus(param.getIncrementId() == null ? 1 : 2);
        incrementOrderEntity.setIncrementId(param.getIncrementId());
        incrementOrderEntity.setRecStatus("A");
        incrementOrderEntity.setCreateTime(DateUserUtil.getDate(new Date()));
        incrementOrderEntity.setUpdateTime(DateUserUtil.getDate(new Date()));
        incrementOrderEntity.setIncrementType(incrementType.getId());
        incrementOrderEntity.setMonthQy(param.getMonthQy());
        incrementOrderEntity.setTimeZoneOff(param.getTimeZoneOff());
        incrementOrderEntity.setAutoPay(param.getAutoPay());
        incrementOrderEntity.setAgentKey(param.getAgentKey());
        if(param.getAutoPay() != null && param.getAutoPay()==1){
            incrementAutoOrderService.addOrder(user.getId(),incrementType.getId(),param.getIncrementId(),incrementOrderEntity.getOrderSn(),param.getAgentKey());
            return incrementOrderEntity;
        }
        this.save(incrementOrderEntity);
        return incrementOrderEntity;
    }

    @Override
    public IncrementOrder getByOrderSn(String orderSn) {
        QueryWrapper<IncrementOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(IncrementOrder::getOrderSn,orderSn);
        List<IncrementOrder> list = this.list(queryWrapper);
        if(list == null || list.size()<=0){
            return null;
        }
        return list.get(0);
    }

    @Override
    public IncrementOrder getByOrderSnNoPay(String orderSn) {
        QueryWrapper<IncrementOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(IncrementOrder::getOrderSn,orderSn);
        queryWrapper.lambda().ne(IncrementOrder::getPayStatus,1);
        List<IncrementOrder> list = this.list(queryWrapper);
        if(list == null || list.size()<=0){
            return null;
        }
        return list.get(0);    }

    @Override
    public boolean paySuccessIncrementOrder(String orderSn, String tradeNo, int paymentTypeName) {
        LambdaUpdateWrapper<IncrementOrder> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(IncrementOrder::getPayType,paymentTypeName)
                .set(IncrementOrder::getNumber,tradeNo)
                .set(IncrementOrder::getPayStatus, 1)
                .set(IncrementOrder::getTradeTime, new Date())
                .eq(IncrementOrder::getOrderSn,orderSn);
        return this.update(updateWrapper);
    }

    @Override
    public void addNewOrderByOrder(IncrementAutoOrder incrementAutoOrder, AutoPaypalVo order) {

        IncrementOrder incrementOrder = new IncrementOrder();
        incrementOrder.setOrderSn(order.getOrderSn());
        incrementOrder.setAmount(new BigDecimal(order.getAmount()));
        incrementOrder.setPayType(order.getPayType());
        incrementOrder.setPayStatus(-1);
        incrementOrder.setUserId(incrementAutoOrder.getUserId());
        incrementOrder.setCount(1);
        incrementOrder.setNumber(order.getTradeNo());
        incrementOrder.setAbroad(1);
        incrementOrder.setStatus(incrementAutoOrder.getUserIncrementId() == null ? 1 : 2);
        incrementOrder.setIncrementId(incrementAutoOrder.getUserIncrementId());
        incrementOrder.setRecStatus("A");
        incrementOrder.setCreateTime(DateUserUtil.getDate(new Date()));
        incrementOrder.setUpdateTime(DateUserUtil.getDate(new Date()));
        incrementOrder.setIncrementType(incrementAutoOrder.getIncrementTypeId());
        incrementOrder.setMonthQy(1);
        incrementOrder.setAutoPay(1);
        incrementOrder.setAutoOrderId(incrementAutoOrder.getId());
        incrementOrder.setTimeZoneOff(-480);
        incrementOrder.setAgentKey(incrementAutoOrder.getAgentKey());
        IncrementType incrementType = incrementTypeService.getById(incrementAutoOrder.getIncrementTypeId());
        if(incrementType != null && incrementType.getValidTimeType() == 0){
            incrementOrder.setMemberLevels("PR");
        }
        if(incrementType != null && incrementType.getValidTimeType() == 1){
            incrementOrder.setMemberLevels("SE");
        }
        if(incrementType != null && incrementType.getPrice() != null && StringUtils.isNotBlank(order.getAmount())){
            BigDecimal payAmount = new BigDecimal(order.getAmount());
            BigDecimal price = incrementType.getPrice();
            Integer monthQy = payAmount.divide(price,2, RoundingMode.HALF_UP).intValue();
            incrementOrder.setMonthQy(monthQy <=0 ? 1 : monthQy);
        }

        this.save(incrementOrder);
    }
}
