/*
 * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
 *
 * https://www.gz-yami.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.yami.shop.distribution.comment.service.impl;

import cn.hutool.core.lang.Snowflake;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.bean.enums.EnterpriseApplyType;
import com.yami.shop.bean.enums.EnterprisePayStatus;
import com.yami.shop.bean.model.EnterprisePay;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.exception.GlobalException;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.util.Arith;
import com.yami.shop.dao.EnterprisePayMapper;
import com.yami.shop.distribution.comment.Enums.DistributionWithdrawCashStateEnum;
import com.yami.shop.distribution.comment.dao.*;
import com.yami.shop.distribution.comment.dto.DistributionWithdrawCashDto;
import com.yami.shop.distribution.comment.model.*;
import com.yami.shop.distribution.comment.param.RangeTimeParam;
import com.yami.shop.distribution.comment.service.DistributionWithdrawCashService;
import com.yami.shop.security.comment.model.AppConnect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.PipedReader;
import java.util.Calendar;
import java.util.Date;
import java.util.Objects;

/**
 * @author lgh on 2019/04/01.
 */
@Service
public class DistributionWithdrawCashServiceImpl extends ServiceImpl<DistributionWithdrawCashMapper, DistributionWithdrawCash> implements DistributionWithdrawCashService {

    @Autowired
    private DistributionWithdrawCashMapper distributionWithdrawCashMapper;

    @Autowired
    private DistributionWithdrawCashSetMapper distributionWithdrawCashSetMapper;

    @Autowired
    private DistributionUserWalletMapper distributionUserWalletMapper;

    @Autowired
    private DistributionUserMapper distributionUserMapper;

    @Autowired
    private DistributionUserWalletBillMapper distributionUserWalletBillMapper;

    @Autowired
    private Snowflake snowflake;

    @Autowired
    private EnterprisePayMapper enterprisePayMapper;

    @Override
    public IPage<DistributionWithdrawCash> distributionWithdrawCashsPage(Page page, Long shopId, RangeTimeParam rangeTimeParam, String userMobile, DistributionWithdrawCash distributionWithdrawCash) {
        return distributionWithdrawCashMapper.distributionWithdrawCashsPage(page, shopId, rangeTimeParam, userMobile, distributionWithdrawCash);
    }

    @Override
    public IPage<DistributionWithdrawCashDto> distributionWithdrawCashDtoPageByUserId(Page page, Long distributionUserId) {
        return distributionWithdrawCashMapper.distributionWithdrawCashDtoPageByUserId(page, distributionUserId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void apply(Double amount, DistributionUser distributionUser, AppConnect appConnect) {
        //获取用户的钱包数据
        DistributionUserWallet distributionUserWallet = distributionUserWalletMapper.selectOne(new LambdaQueryWrapper<DistributionUserWallet>()
                .eq(DistributionUserWallet::getDistributionUserId, distributionUser.getDistributionUserId()));
        //获取店铺提现设置
        DistributionWithdrawCashSet distributionWithdrawCashSet = distributionWithdrawCashSetMapper.selectOne(new LambdaQueryWrapper<DistributionWithdrawCashSet>()
                .eq(DistributionWithdrawCashSet::getShopId, Constant.PLATFORM_SHOP_ID));

        //结算提现金额是否超出限制
        if (amount > distributionWithdrawCashSet.getAmountMax()) {
            throw new GlobalException("提现金额大于最大提现金额");
        }
        if (amount < distributionWithdrawCashSet.getAmountMin()) {
            throw new GlobalException("提现金额小于最小提现金额");
        }
        //获取店铺设置的提现频率算出时间区间
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - distributionWithdrawCashSet.getFrequency());
        RangeTimeParam rangeTimeParam = new RangeTimeParam(calendar.getTime(), new Date());
        //获取用户最近的提现次数，判断是否能够提现
        if (distributionWithdrawCashMapper.getCountByRangeTimeAndDistributionUserId(rangeTimeParam, distributionUser.getDistributionUserId()) >= distributionWithdrawCashSet.getNumber()) {
            throw new GlobalException("提现次数为" + distributionWithdrawCashSet.getFrequency() + "天" + distributionWithdrawCashSet.getNumber() + "次");
        }

        //判断提现金额 是否大于钱包金额
        if (distributionUserWallet.getSettledAmount() < amount) {
            throw new GlobalException("提现失败,余额不足");
        }

        //扣除可提现余额
        distributionUserWallet.setSettledAmount(Arith.sub(distributionUserWallet.getSettledAmount(), amount));

        //插入一条提现记录
        Date now = new Date();
        DistributionWithdrawCash distributionWithdrawCash = new DistributionWithdrawCash();
        distributionWithdrawCash.setCreateTime(now);
        distributionWithdrawCash.setWalletId(distributionUserWallet.getWalletId());
        distributionWithdrawCash.setAmount(amount);
        distributionWithdrawCash.setMerchantOrderId(String.valueOf(snowflake.nextId()));
        distributionWithdrawCash.setState(DistributionWithdrawCashStateEnum.APPLY.getValue());
        distributionWithdrawCash.setMoneyFlow(1);
        distributionWithdrawCash.setVersion(0);
        distributionWithdrawCash.setUpdateTime(now);
        // 暂时没有手续费
        distributionWithdrawCash.setFee(0.0);
        //设置为自动提现
        distributionWithdrawCash.setType(1);

        // 存入提现记录
        distributionWithdrawCashMapper.insert(distributionWithdrawCash);

        // 增加钱包流水记录
        distributionUserWalletBillMapper.insert(new DistributionUserWalletBill(distributionUserWallet, "用户提现", 0.0, -amount, 0.0, 0.0, 0));

        // 修改钱包
        distributionUserWalletMapper.updateById(distributionUserWallet);

        // 添加企业支付记录
        EnterprisePay enterprisePay = new EnterprisePay();
        enterprisePay.setStatus(EnterprisePayStatus.APPLY.getValue());
        enterprisePay.setType(EnterpriseApplyType.DISTRIBUTION_WITHDRAW.value());
        enterprisePay.setBizId(distributionWithdrawCash.getWithdrawCashId());
        enterprisePay.setUserId(appConnect.getUserId());
        enterprisePay.setOpenId(appConnect.getBizUserId());
        enterprisePay.setVersion(0);
        enterprisePay.setEntPayOrderNo(snowflake.nextId());
        enterprisePay.setUpdateTime(now);
        enterprisePay.setCreateTime(now);
        enterprisePay.setAmount(distributionWithdrawCash.getAmount());
        enterprisePayMapper.insert(enterprisePay);

    }

    @Override
    public Integer getCountByRangeTimeAndDistributionUserId(RangeTimeParam rangeTimeParam, Long distributionUserId) {
        return distributionWithdrawCashMapper.getCountByRangeTimeAndDistributionUserId(rangeTimeParam, distributionUserId);
    }

    @Override
    public Double getUserTotalWithdrawCash(Long walletId) {
        return distributionWithdrawCashMapper.getUserTotalWithdrawCash(walletId);
    }


}
