package shop.alien.store.service.impl;

import com.aliyun.tea.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import shop.alien.entity.result.R;
import shop.alien.entity.store.LifeCollect;
import shop.alien.entity.store.LifeDiscountCoupon;
import shop.alien.entity.store.LifeDiscountCouponUser;
import shop.alien.entity.store.LifeUser;
import shop.alien.entity.store.StoreInfo;
import shop.alien.entity.store.dto.LifeDiscountCouponUserDto;
import shop.alien.mapper.LifeCollectMapper;
import shop.alien.mapper.LifeDiscountCouponMapper;
import shop.alien.mapper.LifeDiscountCouponUserMapper;
import shop.alien.mapper.LifeUserMapper;
import shop.alien.mapper.StoreInfoMapper;
import shop.alien.store.config.BaseRedisService;
import shop.alien.store.service.LifeDiscountCouponUserService;
import shop.alien.util.common.constant.DiscountCouponEnum;
import shop.alien.util.coupon.DiscountCouponExpirationUtil;
import shop.alien.util.coupon.LifeDiscountCouponStock;
import shop.alien.util.type.LifeCollectIdentityQuery;
import shop.alien.util.type.TypeUtil;

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;

/**
 * <p>
 * 优惠券用户表 服务实现类
 * </p>
 *
 * @author ssk
 * @since 2025-02-08
 */
@Service
@RequiredArgsConstructor
public class LifeDiscountCouponUserServiceImpl extends ServiceImpl<LifeDiscountCouponUserMapper, LifeDiscountCouponUser> implements LifeDiscountCouponUserService {

    private final LifeCollectMapper lifeCollectMapper;

    private final LifeUserMapper lifeUserMapper;

    private final StoreInfoMapper storeInfoMapper;

    private final LifeDiscountCouponMapper lifeDiscountCouponMapper;

    private final LifeDiscountCouponUserMapper lifeDiscountCouponUserMapper;

    private final BaseRedisService baseRedisService;

    private final TypeUtil typeUtil;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Boolean> receiveCoupon(LifeDiscountCouponUserDto lifeDiscountCouponUserDto) {
        // 锁value
        String identifier = null;
        try {
            identifier = baseRedisService.lock(lifeDiscountCouponUserDto.getCouponId().toString());
            if (StringUtils.isEmpty(identifier)) {
                throw new RuntimeException("抢购人数过多，请稍后重试");
            }

            Integer receiveQuantity = lifeDiscountCouponUserDto.getReceiveQuantity();
            int receiveQty = (receiveQuantity == null || receiveQuantity < 1) ? 1 : receiveQuantity;

            LifeDiscountCoupon lifeDiscountCoupon = lifeDiscountCouponMapper.selectById(lifeDiscountCouponUserDto.getCouponId());
            if (lifeDiscountCoupon == null) {
                return R.fail("优惠券不存在");
            }
            // 判断是否在领取时间内
            Date now = new Date();
            ZoneId zoneId = ZoneId.systemDefault();
            LocalDate localNow = now.toInstant().atZone(zoneId).toLocalDate();
            LocalDate beginGet = lifeDiscountCoupon.getBeginGetDate();
            if (beginGet != null && localNow.isBefore(beginGet)) {
                return R.fail("该优惠劵活动时间未开始");
            }
            LocalDate endGet = lifeDiscountCoupon.getEndGetDate();
            if (endGet != null && localNow.isAfter(endGet)) {
                return R.fail("该优惠劵领取时间已结束");
            }
            Integer getStatusFlag = lifeDiscountCoupon.getGetStatus();
            if (getStatusFlag == null || Integer.parseInt(DiscountCouponEnum.NO_GET.getValue()) == getStatusFlag) {
                return R.fail("该优惠劵已经关闭领取");
            }

            if (!LifeDiscountCouponStock.hasTemplateStockRemaining(
                    lifeDiscountCoupon.getUnlimitedQty(), lifeDiscountCoupon.getSingleQty())) {
                return R.fail("已发放完毕");
            }

            if (!LifeDiscountCouponStock.isUnlimitedQty(lifeDiscountCoupon.getUnlimitedQty())
                    && lifeDiscountCoupon.getSingleQty() != null
                    && lifeDiscountCoupon.getSingleQty() < receiveQty) {
                return R.fail("已发放完毕");
            }

            //判断领取数量
            for (int i = 0; i < receiveQty; i++) {
                LifeDiscountCouponUser lifeDiscountCouponUser = new LifeDiscountCouponUser();
                BeanUtils.copyProperties(lifeDiscountCouponUserDto, lifeDiscountCouponUser);
                lifeDiscountCouponUser.setReceiveTime(new Date());
                lifeDiscountCouponUser.setExpirationTime(DiscountCouponExpirationUtil.resolveLifeDiscountCouponExpiration(
                        lifeDiscountCouponUser.getReceiveTime(),
                        lifeDiscountCoupon.getLongTermValid(),
                        lifeDiscountCoupon.getSpecifiedDay(),
                        lifeDiscountCoupon.getExpirationDate(),
                        lifeDiscountCoupon.getValidDate(),
                        lifeDiscountCoupon.getEndDate(),
                        ZoneId.systemDefault()));

                //存入状态  待使用：0
                lifeDiscountCouponUser.setStatus(Integer.parseInt(DiscountCouponEnum.WAITING_USED.getValue()));
                lifeDiscountCouponUser.setIssueSource(1); // 1-手动领取
                lifeDiscountCouponUserMapper.insert(lifeDiscountCouponUser);
            }
            //削减该优惠券库存（发行量不限则不扣减）
            if (!LifeDiscountCouponStock.isUnlimitedQty(lifeDiscountCoupon.getUnlimitedQty())
                    && lifeDiscountCoupon.getSingleQty() != null) {
                lifeDiscountCoupon.setSingleQty(lifeDiscountCoupon.getSingleQty() - receiveQty);
                lifeDiscountCouponMapper.updateById(lifeDiscountCoupon);
            }

            //是否领取优惠券收藏店铺
            Integer attentionCanReceived = lifeDiscountCoupon.getAttentionCanReceived();
            if(attentionCanReceived != null && attentionCanReceived == 1){

                LifeUser lifeUser = lifeUserMapper.selectById(lifeDiscountCouponUserDto.getUserId());
                String collectUserId = lifeUser != null && !StringUtils.isEmpty(lifeUser.getUserPhone())
                        ? "user_" + lifeUser.getUserPhone()
                        : lifeDiscountCouponUserDto.getUserId().toString();

                LifeCollectIdentityQuery.Scope collectScope = LifeCollectIdentityQuery.resolve(collectUserId, typeUtil);

                LambdaQueryWrapper<LifeCollect> lifeCollectLambdaQueryWrapper = new LambdaQueryWrapper<>();
                lifeCollectLambdaQueryWrapper.eq(LifeCollect::getStoreId, lifeDiscountCoupon.getStoreId());
                LifeCollectIdentityQuery.applyUserSide(lifeCollectLambdaQueryWrapper, collectScope);
                lifeCollectLambdaQueryWrapper.eq(LifeCollect::getDeleteFlag, 0);
                int lifeCollectCount = lifeCollectMapper.selectCount(lifeCollectLambdaQueryWrapper);
                if(lifeCollectCount == 0){
                    LifeCollect lifeCollect = new LifeCollect();
                    lifeCollect.setStoreId(lifeDiscountCoupon.getStoreId());
                    lifeCollect.setUserId(collectUserId);
                    LifeCollectIdentityQuery.fillIdentityOnCollect(lifeCollect, typeUtil, lifeUserMapper);
                    lifeCollectMapper.insert(lifeCollect);
                    //同步店铺收藏数量
                    if (!StringUtils.isEmpty(lifeCollect.getStoreId())) {
                        LambdaQueryWrapper<LifeCollect> queryWrapper = new LambdaQueryWrapper<>();
                        queryWrapper.eq(LifeCollect::getStoreId, lifeCollect.getStoreId());
                        storeInfoMapper.update(null, new LambdaUpdateWrapper<StoreInfo>().eq(StoreInfo::getId, lifeCollect.getStoreId()).set(StoreInfo::getCollectNum, lifeCollectMapper.selectCount(queryWrapper)));
                    }
                }
            }
        } catch (Exception e) {
            log.error("LifeDiscountCouponController.receiveCoupon ERROR Msg=" + e.getMessage());
            baseRedisService.unlock(lifeDiscountCouponUserDto.getCouponId().toString(), identifier);
            return R.fail("领取失败");
        } finally {
            baseRedisService.unlock(lifeDiscountCouponUserDto.getCouponId().toString(), identifier);
        }
        return R.success("领取成功");
    }
}
