package com.ym.mec.biz.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ym.mec.auth.api.client.SysUserFeignService;
import com.ym.mec.auth.api.entity.SysUser;
import com.ym.mec.biz.dal.dao.SysCouponIssueRecordDao;
import com.ym.mec.biz.dal.entity.SysCoupon;
import com.ym.mec.biz.dal.entity.SysCouponIssueRecord;
import com.ym.mec.biz.dal.vo.CouponIssueRecordVo;
import com.ym.mec.biz.service.SysCouponCodeService;
import com.ym.mec.biz.service.SysCouponIssueRecordService;
import com.ym.mec.biz.service.SysCouponService;
import com.ym.mec.common.exception.BizException;
import com.ym.mec.common.page.PageInfo;
import com.ym.mec.common.page.PageUtil;
import com.ym.mec.common.page.WrapperUtil;
import com.ym.mec.common.tenant.TenantContextHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 优惠券发放记录(SysCouponIssueRecord)表服务实现类
 *
 * @author hgw
 * @since 2021-12-29 20:26:12
 */
@Service("sysCouponIssueRecordService")
public class SysCouponIssueRecordServiceImpl extends ServiceImpl<SysCouponIssueRecordDao, SysCouponIssueRecord> implements SysCouponIssueRecordService {

    private final static Logger log = LoggerFactory.getLogger(SysCouponIssueRecordServiceImpl.class);

    @Autowired
    private SysCouponCodeService sysCouponCodeService;
    @Autowired
    private SysCouponService sysCouponService;
    @Autowired
    private SysUserFeignService sysUserFeignService;

    /**
     * 手动发优惠券
     *
     * @param param studentIds 学生id
     * @param param couponId   优惠券id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void issueCoupon(Map<String, Object> param) {
        String ids = WrapperUtil.toStr(param, "studentIds", "请选择学生！");
        List<String> studentIds = WrapperUtil.toList(ids);
        //校验优惠券信息 是否存在 是否是启用状态
        SysCoupon sysCoupon = Optional.ofNullable(param.get("couponId"))
                .map(String::valueOf)
                .map(Integer::parseInt)
                .map(sysCouponService::get)
                .filter(c -> c.getStatus() == 1 && c.getIssuanceType() == 1)
                .orElseThrow(() -> new BizException("查询不到优惠券!"));

        Integer tenantId = TenantContextHolder.getTenantId();

        SysCouponIssueRecord record = new SysCouponIssueRecord();
        record.setCouponId(sysCoupon.getId());
        record.setCouponName(sysCoupon.getName());
        record.setNum(studentIds.size());
        record.setOps(0);
        record.setTenantId(tenantId);
        record.setCreatedBy(getUserId());
        record.setCreatedTime(new Date());
        this.save(record);

        studentIds.forEach(id -> sysCouponCodeService.exchangeCoupon(Integer.parseInt(id), sysCoupon.getId(),
                null, 1, 1, record.getId())
        );

    }

    /**
     * 学生端
     * 手动领取优惠券
     *
     * @param userId   用户id
     * @param couponId 优惠券id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void manualIssueCoupon(Integer userId, Integer couponId) {
        sysCouponCodeService.exchangeCoupon(userId, couponId,
                null, 1, 0, null);
    }

    /**
     * 撤回优惠券
     *
     * @param issueId 发放记录
     */
    @Override
    public void revokeCoupon(Integer issueId) {
        SysCouponIssueRecord issueRecord = Optional.ofNullable(issueId)
                .map(this::getById)
                .orElseThrow(() -> new BizException("未查询到该发放记录!"));

        //修改优惠券与用户关系表中未使用的优惠券为撤回状态
        baseMapper.revoke(issueId);
        //查询券的信息
        SysCoupon sysCoupon = Optional.ofNullable(issueRecord.getCouponId())
                .map(sysCouponService::get)
                .orElseThrow(() -> new BizException("未查询到该优惠券!"));

        //查询未使用的优惠券有多少
        int useCount = baseMapper.queryCouponCode(issueId, 0);
        if (useCount > 0) {
            //返还库存
            baseMapper.opsConsume(sysCoupon.getId(), useCount);
        }
        //发放记录修改为撤回状态
        issueRecord.setOps(1);
        issueRecord.setUpdatedBy(getUserId());
        issueRecord.setUpdatedTime(new Date());
        this.updateById(issueRecord);
    }

    /**
     * 检查已使用的优惠券数量
     */
    @Override
    public int checkRevoke(Integer issueId) {
        return baseMapper.queryCouponCode(issueId, 1);//0 未使用 1已使用
    }

    /**
     * 查询发放记录
     */
    @Override
    public PageInfo<CouponIssueRecordVo> queryIssueRecord(Map<String, Object> param) {
        Page<CouponIssueRecordVo> pageInfo = PageUtil.getPageInfo(param);
        pageInfo.setAsc("a.created_time_");
        param.put("tenantId",TenantContextHolder.getTenantId());
        return PageUtil.pageInfo(baseMapper.queryIssueRecord(pageInfo, param));
    }

    /**
     * 学生端
     * 查询可以领取的优惠券
     *
     * @param userId 用户id
     */
    @Override
    public List<SysCoupon> queryCanBeGetCoupon(Integer userId) {
        return baseMapper.queryUserCanGetCoupon(userId,TenantContextHolder.getTenantId());
    }

    /**
     * 查询发放名单
     */
    @Override
    public PageInfo<?> queryIssueDetail(Map<String, Object> param) {
        Page<?> pageInfo = PageUtil.getPageInfo(param);
        pageInfo.setAsc("scc.create_time_");
        param.put("tenantId",TenantContextHolder.getTenantId());
        return PageUtil.pageInfo(baseMapper.queryIssueDetail(pageInfo, param));
    }

    private Integer getUserId() {
        //修改机构基础信息
        return Optional.ofNullable(sysUserFeignService.queryUserInfo())
                .map(SysUser::getId)
                .orElseThrow(() -> new BizException("用户信息获取失败,请刷新页面或者重新登录!"));
    }

}

