package cn.reghao.tnb.user.app.service;

import cn.reghao.jutil.jdk.converter.DateTimeConverter;
import cn.reghao.jutil.jdk.web.result.Result;
import cn.reghao.tnb.common.auth.UserContext;
import cn.reghao.tnb.user.app.db.mapper.UserVipMapper;
import cn.reghao.tnb.user.app.model.constant.VipMember;
import cn.reghao.tnb.user.app.model.dto.BuyVip;
import cn.reghao.tnb.user.app.model.po.UserVip;
import cn.reghao.tnb.user.app.model.vo.VipPlan;
import cn.reghao.tnb.user.app.model.vo.MyVip;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author reghao
 * @date 2023-06-22 14:14:31
 */
@Service
public class UserVipService {
    private final UserVipMapper userVipMapper;
    private final WalletService walletService;

    public UserVipService(UserVipMapper userVipMapper, WalletService walletService) {
        this.userVipMapper = userVipMapper;
        this.walletService = walletService;
    }

    public MyVip getMyVip(long userId) {
        UserVip userVip = userVipMapper.findByUserId(userId);
        if (userVip == null) {
            return new MyVip();
        }

        int rcmdMode = userVip.getRcmdMode();
        long expireAt = userVip.getExpireAt();
        if (expireAt < System.currentTimeMillis()) {
            return new MyVip(false, true, 0, rcmdMode);
        }

        LocalDateTime futureDay = DateTimeConverter.localDateTime(expireAt);
        long days = Duration.between(LocalDateTime.now(), futureDay).toDays();
        return new MyVip(true, false, (int) days, rcmdMode);
    }

    public boolean isVip(long userId) {
        UserVip userVip = userVipMapper.findByUserId(userId);
        return userVip != null && userVip.getExpireAt() > System.currentTimeMillis();
    }

    public List<VipPlan> getVipPlans() {
        return Arrays.stream(VipMember.values())
                .map(VipPlan::new)
                .collect(Collectors.toList());
    }

    public Result buyVip(BuyVip buyVip) throws Exception {
        int planId = buyVip.getPlanId();
        VipMember vipMember = VipMember.getByPlanId(planId);
        if (vipMember == null) {
            return Result.fail("vip 计划不存在");
        }

        VipPlan vipPlan = new VipPlan(vipMember);
        long userId = UserContext.getUserId();
        try {
            double price = vipPlan.getPrice();
            walletService.pay(price, userId);
            int duration = vipPlan.getDuration();
            long expireAt = System.currentTimeMillis() + 1000L *3600*24*duration;
            UserVip userVip = userVipMapper.findByUserId(userId);
            if (userVip == null) {
                userVip = new UserVip(userId, expireAt, 0);
                userVipMapper.save(userVip);
            } else {
                long expireAt1 = userVip.getExpireAt();
                if (expireAt1 < System.currentTimeMillis()) {
                    userVipMapper.updateUserVip(userId, expireAt);
                } else {
                    // 在当前时间上加上新的续费时间
                    userVipMapper.updateUserVip(userId, expireAt1 + 1000L *3600*24*duration);
                }
            }

            return Result.success();
        } catch (Exception e) {
            throw e;
        }
    }

    public void updateRcmdMode(long userId, int rcmdMode) {
        userVipMapper.updateRcmdMode(userId, rcmdMode);
    }
}
