package org.dromara.mall.coupon.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.mall.coupon.domain.MallCoupon;
import org.dromara.mall.coupon.domain.MallCouponUser;
import org.dromara.mall.coupon.domain.bo.MallCouponUserBo;
import org.dromara.mall.coupon.domain.vo.MallCouponUserVo;
import org.dromara.mall.coupon.domain.vo.MallCouponVo;
import org.dromara.mall.coupon.mapper.MallCouponMapper;
import org.dromara.mall.coupon.mapper.MallCouponUserMapper;
import org.dromara.mall.coupon.service.MallCouponUserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户优惠券Service业务层处理
 *
 * @author pengles
 */
@RequiredArgsConstructor
@Service
public class MallCouponUserServiceImpl implements MallCouponUserService {

    private final MallCouponUserMapper baseMapper;
    private final MallCouponMapper couponMapper;

    /**
     * 查询用户优惠券
     */
    @Override
    public MallCouponUserVo queryById(Long id) {
        MallCouponUserVo vo = baseMapper.selectVoById(id);
        if (vo != null && vo.getCouponId() != null) {
            // 关联查询优惠券信息
            MallCouponVo couponVo = couponMapper.selectVoById(vo.getCouponId());
            vo.setCouponInfo(couponVo);
        }
        return vo;
    }

    /**
     * 查询用户优惠券列表
     */
    @Override
    public TableDataInfo<MallCouponUserVo> queryPageList(MallCouponUserBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<MallCouponUser> lqw = buildQueryWrapper(bo);
        Page<MallCouponUserVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);

        // 关联查询优惠券信息
        fillCouponInfo(result.getRecords());

        return TableDataInfo.build(result);
    }

    /**
     * 查询用户优惠券列表
     */
    @Override
    public List<MallCouponUserVo> queryList(MallCouponUserBo bo) {
        LambdaQueryWrapper<MallCouponUser> lqw = buildQueryWrapper(bo);
        List<MallCouponUserVo> list = baseMapper.selectVoList(lqw);

        // 关联查询优惠券信息
        fillCouponInfo(list);

        return list;
    }

    /**
     * 查询用户可用优惠券列表
     */
    @Override
    public List<MallCouponUserVo> queryAvailableList(Long userId) {
        LambdaQueryWrapper<MallCouponUser> lqw = new LambdaQueryWrapper<>();
        lqw.eq(MallCouponUser::getUserId, userId);
        lqw.eq(MallCouponUser::getStatus, 0); // 未使用
        lqw.orderByDesc(MallCouponUser::getCreateTime);

        List<MallCouponUserVo> list = baseMapper.selectVoList(lqw);

        // 过滤已过期的优惠券
        Date now = new Date();
        list = list.stream().filter(vo -> {
            if (vo.getCouponId() == null) {
                return false;
            }
            MallCouponVo couponVo = couponMapper.selectVoById(vo.getCouponId());
            if (couponVo == null || couponVo.getStatus() != 0) {
                return false;
            }
            return couponVo.getValidEndTime() != null && couponVo.getValidEndTime().after(now);
        }).collect(Collectors.toList());

        // 关联查询优惠券信息
        fillCouponInfo(list);

        return list;
    }

    /**
     * 填充优惠券信息
     */
    private void fillCouponInfo(List<MallCouponUserVo> list) {
        if (list == null || list.isEmpty()) {
            return;
        }
        for (MallCouponUserVo vo : list) {
            if (vo.getCouponId() != null) {
                MallCouponVo couponVo = couponMapper.selectVoById(vo.getCouponId());
                vo.setCouponInfo(couponVo);
            }
        }
    }

    private LambdaQueryWrapper<MallCouponUser> buildQueryWrapper(MallCouponUserBo bo) {
        LambdaQueryWrapper<MallCouponUser> lqw = new LambdaQueryWrapper<>();
        lqw.eq(bo.getUserId() != null, MallCouponUser::getUserId, bo.getUserId());
        lqw.eq(bo.getCouponId() != null, MallCouponUser::getCouponId, bo.getCouponId());
        lqw.eq(bo.getStatus() != null, MallCouponUser::getStatus, bo.getStatus());
        lqw.orderByDesc(MallCouponUser::getCreateTime);
        return lqw;
    }

    /**
     * 用户领取优惠券
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean receiveCoupon(Long couponId) {
        Long userId = LoginHelper.getUserId();

        // 查询优惠券信息
        MallCoupon coupon = couponMapper.selectById(couponId);
        if (coupon == null) {
            throw new ServiceException("优惠券不存在");
        }
        if (coupon.getStatus() != 0) {
            throw new ServiceException("优惠券已禁用");
        }

        // 校验有效期
        Date now = new Date();
        if (coupon.getValidStartTime().after(now) || coupon.getValidEndTime().before(now)) {
            throw new ServiceException("优惠券不在有效期内");
        }

        // 校验发放数量
        if (coupon.getTotalCount() != null) {
            if (coupon.getUsedCount() >= coupon.getTotalCount()) {
                throw new ServiceException("优惠券已发放完毕");
            }
        }

        // 校验每人限领数量
        LambdaQueryWrapper<MallCouponUser> countWrapper = new LambdaQueryWrapper<>();
        countWrapper.eq(MallCouponUser::getUserId, userId);
        countWrapper.eq(MallCouponUser::getCouponId, couponId);
        Long receivedCount = baseMapper.selectCount(countWrapper);
        if (receivedCount >= coupon.getPerLimit()) {
            throw new ServiceException("已达到每人限领数量");
        }

        // 创建用户优惠券记录
        MallCouponUser couponUser = new MallCouponUser();
        couponUser.setUserId(userId);
        couponUser.setCouponId(couponId);
        couponUser.setStatus(0); // 未使用
        couponUser.setCreateTime(now);

        boolean flag = baseMapper.insert(couponUser) > 0;

        if (flag) {
            // 更新优惠券已发放数量（注意：这里used_count实际存储的是已发放数量，不是已使用数量）
            // 如果业务需要区分，可以考虑增加字段
            LambdaUpdateWrapper<MallCoupon> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(MallCoupon::getId, couponId);
            updateWrapper.setSql("used_count = used_count + 1");
            couponMapper.update(null, updateWrapper);
        }

        return flag;
    }

    /**
     * 使用优惠券（订单结算时调用）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean useCoupon(Long couponUserId, Long orderId) {
        MallCouponUser couponUser = baseMapper.selectById(couponUserId);
        if (couponUser == null) {
            throw new ServiceException("用户优惠券不存在");
        }
        if (couponUser.getStatus() != 0) {
            throw new ServiceException("优惠券已使用或已过期");
        }

        // 校验优惠券是否过期
        MallCoupon coupon = couponMapper.selectById(couponUser.getCouponId());
        if (coupon == null) {
            throw new ServiceException("优惠券不存在");
        }
        Date now = new Date();
        if (coupon.getValidEndTime().before(now)) {
            throw new ServiceException("优惠券已过期");
        }

        // 更新用户优惠券状态
        couponUser.setStatus(1); // 已使用
        couponUser.setUsedTime(now);
        couponUser.setOrderId(orderId);

        return baseMapper.updateById(couponUser) > 0;
    }

    /**
     * 退还优惠券（订单取消时调用）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean returnCoupon(Long couponUserId) {
        MallCouponUser couponUser = baseMapper.selectById(couponUserId);
        if (couponUser == null) {
            throw new ServiceException("用户优惠券不存在");
        }
        if (couponUser.getStatus() != 1) {
            throw new ServiceException("优惠券状态不正确，无法退还");
        }

        // 校验优惠券是否过期
        MallCoupon coupon = couponMapper.selectById(couponUser.getCouponId());
        if (coupon == null) {
            throw new ServiceException("优惠券不存在");
        }
        Date now = new Date();
        if (coupon.getValidEndTime().before(now)) {
            // 已过期，状态改为已过期
            couponUser.setStatus(2);
        } else {
            // 未过期，状态改为未使用
            couponUser.setStatus(0);
        }
        couponUser.setUsedTime(null);
        couponUser.setOrderId(null);

        return baseMapper.updateById(couponUser) > 0;
    }

    /**
     * 批量删除用户优惠券
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            // 可以添加业务校验逻辑
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 处理过期优惠券（定时任务调用）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void processExpiredCoupons() {
        Date now = new Date();

        // 查询所有未使用的用户优惠券
        LambdaQueryWrapper<MallCouponUser> lqw = new LambdaQueryWrapper<>();
        lqw.eq(MallCouponUser::getStatus, 0); // 未使用
        List<MallCouponUser> list = baseMapper.selectList(lqw);

        for (MallCouponUser couponUser : list) {
            MallCoupon coupon = couponMapper.selectById(couponUser.getCouponId());
            if (coupon != null && coupon.getValidEndTime().before(now)) {
                // 优惠券已过期，更新状态
                couponUser.setStatus(2); // 已过期
                baseMapper.updateById(couponUser);
            }
        }
    }

}
