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.beans.BeansException;
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.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.StoreInfoMapper;
import shop.alien.store.config.BaseRedisService;
import shop.alien.store.service.LifeDiscountCouponUserService;
import shop.alien.util.common.constant.DiscountCouponEnum;

import java.time.Instant;
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 StoreInfoMapper storeInfoMapper;

    private final LifeDiscountCouponMapper lifeDiscountCouponMapper;

    private final LifeDiscountCouponUserMapper lifeDiscountCouponUserMapper;

    private final BaseRedisService baseRedisService;


    @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();
            LifeDiscountCoupon lifeDiscountCoupon = lifeDiscountCouponMapper.selectById(lifeDiscountCouponUserDto.getCouponId());
            // 判断是否在领取时间内
            Date now = new Date();
            Instant instant = now.toInstant();
            ZoneId zoneId = ZoneId.systemDefault();
            LocalDate localNow = instant.atZone(zoneId).toLocalDate();
            int startResult = localNow.compareTo(lifeDiscountCoupon.getBeginGetDate());
            if (startResult < 0) {
                return R.fail("该优惠劵活动时间未开始");
            }
            int getStatus = lifeDiscountCoupon.getGetStatus();
            if (getStatus == 0) {
                return R.fail("该优惠劵已经关闭领取");
            }

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

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

            String specifiedDay = lifeDiscountCoupon.getSpecifiedDay();

            //判断领取数量
            for (int i = 0; i < receiveQuantity; i++) {
                LifeDiscountCouponUser lifeDiscountCouponUser = new LifeDiscountCouponUser();
                BeanUtils.copyProperties(lifeDiscountCouponUserDto, lifeDiscountCouponUser);
                lifeDiscountCouponUser.setReceiveTime(new Date());

                // 存入过期时间, 领取时间加上specifiedDay
                if(!StringUtils.isEmpty(specifiedDay)){
                    int sDay = Integer.parseInt(specifiedDay);
                    if(sDay > 0 && lifeDiscountCoupon.getBeginGetDate() != null) {
                        Date validDate = addDaysToDateJava8(new Date(), sDay);
                        LocalDate validDateLocalDate = validDate.toInstant()
                                .atZone(ZoneId.systemDefault())
                                .toLocalDate();
                        lifeDiscountCouponUser.setExpirationTime(validDateLocalDate);
                    }
                }

                //存入状态  待使用：0
                lifeDiscountCouponUser.setStatus(Integer.parseInt(DiscountCouponEnum.WAITING_USED.getValue()));
                lifeDiscountCouponUserMapper.insert(lifeDiscountCouponUser);
            }
            //削减该优惠券库存
            lifeDiscountCoupon.setSingleQty(lifeDiscountCoupon.getSingleQty() - receiveQuantity);
            lifeDiscountCouponMapper.updateById(lifeDiscountCoupon);

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

                LambdaQueryWrapper<LifeCollect> lifeCollectLambdaQueryWrapper = new LambdaQueryWrapper<>();
                lifeCollectLambdaQueryWrapper.eq(LifeCollect::getStoreId, lifeDiscountCoupon.getStoreId());
                lifeCollectLambdaQueryWrapper.eq(LifeCollect::getUserId, lifeDiscountCouponUserDto.getUserId());
                lifeCollectLambdaQueryWrapper.eq(LifeCollect::getDeleteFlag, 0);
                int lifeCollectCount = lifeCollectMapper.selectCount(lifeCollectLambdaQueryWrapper);
                if(lifeCollectCount == 0){
                    LifeCollect lifeCollect = new LifeCollect();
                    lifeCollect.setStoreId(lifeDiscountCoupon.getStoreId());
                    lifeCollect.setUserId(lifeDiscountCouponUserDto.getUserId().toString());
                    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("领取成功");
    }

    public static Date addDaysToDateJava8(Date date, int days) {
        // 将Date转换为Instant
        Instant instant = date.toInstant();

        // 转换为LocalDate并加天数
        LocalDate localDate = instant.atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDate newLocalDate = localDate.plusDays(days);

        // 转换回Date
        return Date.from(newLocalDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
    }
}
