package com.ruoyi.app.user;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageHelper;
import com.ruoyi.app.user.dto.ReceiveQuanyiInput;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SalesPromotion;
import com.ruoyi.system.domain.VipQuanyi;
import com.ruoyi.system.service.ISalesPromotionService;
import com.ruoyi.system.service.IVipQuanyiService;
import com.ruoyi.system.utils.Auth;
import com.ruoyi.system.utils.JwtUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.system.domain.VipUserQuanyi;
import com.ruoyi.system.service.IVipUserQuanyiService;
import com.ruoyi.common.core.page.TableDataInfo;
import redis.clients.jedis.Jedis;

/**
 * 用户优惠券
 * Controller
 *
 * @author ruoyi
 * @date 2025-05-09
 */
@Api("用户优惠券管理")
@RestController
@RequestMapping("/system/userQuanyi")
public class VipUserQuanyiController extends BaseController {
    @Autowired
    private IVipUserQuanyiService vipUserQuanyiService;
    @Autowired
    private IVipQuanyiService vipQuanyiService;
    @Autowired
    private ISalesPromotionService promotionService;

    @Anonymous
    @Auth
    @ApiOperation("可用活动分页列表")
    @GetMapping("/promotionList")
    public R<IPage<SalesPromotion>> promotionList(@RequestHeader String token,
                                                  @RequestParam Integer pageNum,
                                                  @RequestParam Integer pageSize,
//                                                  @RequestParam String language,
                                                  @RequestParam(defaultValue = "") String mdId,
                                                  @RequestParam(defaultValue = "") String price
    ) {
        System.out.println("promotionList");
        JwtUtil jwtUtil = new JwtUtil();
        String uid = jwtUtil.getusid(token);
        String language = getLanguage(uid);
        IPage<SalesPromotion> stlist = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<SalesPromotion> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SalesPromotion::getSalesState, "0");
        queryWrapper.ge(SalesPromotion::getEndTime,
                DateUtils.truncate(new Date(), java.util.Calendar.DAY_OF_MONTH));
        queryWrapper.eq(SalesPromotion::getDeleted, "0");
        queryWrapper.eq(SalesPromotion::getLanguage, language);
        if (!"".equals(price)) {
            queryWrapper.and(is -> is.le(SalesPromotion::getSalesCondition, price).or().isNull(SalesPromotion::getSalesCondition));
        }
        if (!"".equals(mdId)) {
            // 查询平台优惠券(mdId为空)或当前商家的优惠券
            queryWrapper.and(wrapper -> wrapper.isNull(SalesPromotion::getShId)
                    .or()
                    .eq(SalesPromotion::getShId, mdId));
        }
        IPage<SalesPromotion> list = promotionService.page(stlist, queryWrapper);

        return R.ok(list);
    }

    private String getLanguage(String uid) {

        Jedis jedis = new Jedis("localhost", 6379);
        String lang = jedis.get(uid);
        System.out.println("从redis获取的语言是：" + lang);
        String result = "0";
        if ("zh-CN".equals(lang)) {
            result = "2";
        }
        if ("zh-TW".equals(lang)) {
            result = "3";
        }
        if ("en-US".equals(lang)) {
            result = "1";
        }
        System.out.println("获取的语言是：" + result);
        return result;
    }

    /**
     * @param token
     * @param mdId
     * @param price
     * @param yfPrice
     * @return
     */
    @ApiOperation("用户生成订单时可用优惠券列表")
    @GetMapping("/orderyhList")
    @Anonymous
    @Auth
    public R<List<VipUserQuanyi>> orderyhList(@RequestHeader String token,
                                              @RequestParam(defaultValue = "") String mdId,
                                              @RequestParam(defaultValue = "") String price,
                                              @RequestParam(defaultValue = "") String yfPrice) {
        JwtUtil jwtUtil = new JwtUtil();
        String uid = jwtUtil.getusid(token);
        String language = getLanguage(uid);

        LambdaQueryWrapper<VipUserQuanyi> queryWrapper = new LambdaQueryWrapper<>();

        // 基础必选条件
        queryWrapper.eq(VipUserQuanyi::getUserId, uid)
                .eq(VipUserQuanyi::getDeleted, "0")
                .eq(VipUserQuanyi::getLanguage, language)
                .gt(VipUserQuanyi::getValidity, DateUtils.truncate(new Date(), Calendar.DAY_OF_MONTH))
                .eq(VipUserQuanyi::getState, "0");
        //传0 表示自提，去掉运费优惠券
        if (yfPrice.equals("0")) {
            queryWrapper.ne(VipUserQuanyi::getYhfangs, "1");
        }
        // 门店ID条件
        if (StringUtils.isNotBlank(mdId)) {
            queryWrapper.and(wrapper ->
                    wrapper.eq(VipUserQuanyi::getShId, mdId)
                            .or()
                            .isNull(VipUserQuanyi::getShId)
            );
        }

        queryWrapper.and(sub -> {
                    sub.nested(nonShip ->
                            nonShip.nested(cond -> cond.le(VipUserQuanyi::getTiaojian, price)
                                    .or()
                                    .nested(cn -> cn.isNull(VipUserQuanyi::getTiaojian))
                            )
                    );
                }
        );

//        // 动态构建价格条件
//        boolean hasPrice = StringUtils.isNotBlank(price);
//        boolean hasYfPrice = StringUtils.isNotBlank(yfPrice);

//        if (hasPrice || hasYfPrice) {
//            queryWrapper.and(wrap -> {
//                // 非运费条件块（sales_type <> 1）
//                if (hasPrice) {
//                    wrap.and(sub ->
//                            sub.nested(nonShip ->
//                                    nonShip.nested(cond -> cond.le(VipUserQuanyi::getTiaojian, price).ne(VipUserQuanyi::getYhfangs, "1"))
//                                            .or()
//                                            .nested(cond -> cond.isNull(VipUserQuanyi::getTiaojian).ne(VipUserQuanyi::getYhfangs, "1"))
//                            )
//                    );
//                }
//
//                // 运费条件块（sales_type = 1）
//                if (hasYfPrice) {
//                    wrap.or(sub ->
//                            sub.nested(ship ->
//                                    ship.nested(cond -> cond.le(VipUserQuanyi::getTiaojian, yfPrice).eq(VipUserQuanyi::getYhfangs, "1"))
//                                            .or()
//                                            .nested(cond -> cond.isNull(VipUserQuanyi::getTiaojian).eq(VipUserQuanyi::getYhfangs, "1"))
//                            )
//                    );
//                }
//            });
//        }


        // 排序
        queryWrapper.orderByDesc(VipUserQuanyi::getValidity);

        List<VipUserQuanyi> list = vipUserQuanyiService.list(queryWrapper);
        List<VipUserQuanyi> result = list.stream()
                .filter(item -> item.getQuanyiId() != null) // 可选：过滤掉quanyiId为null的
                .collect(Collectors.groupingBy(
                        VipUserQuanyi::getQuanyiId,
                        Collectors.minBy(Comparator.comparing(VipUserQuanyi::getValidity))
                ))
                .values().stream()
                .filter(Optional::isPresent)
                .map(Optional::get)
                .collect(Collectors.toList());
        return R.ok(result);
    }

    @ApiOperation("用户总的可用、过期优惠券分页列表")
    @GetMapping("/list")
    @Anonymous
    @Auth
    public R<IPage<VipUserQuanyi>> expiredList(@RequestHeader String token,
                                               @RequestParam Integer pageNum,
                                               @RequestParam Integer pageSize,
                                               @RequestParam int listType
    ) {
        JwtUtil jwtUtil = new JwtUtil();
        String uid = jwtUtil.getusid(token);
        String language = getLanguage(uid);
        IPage<VipUserQuanyi> stlist = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<VipUserQuanyi> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(VipUserQuanyi::getUserId, uid);
        queryWrapper.eq(VipUserQuanyi::getLanguage, language);
        if (listType == 2) {
            queryWrapper.lt(VipUserQuanyi::getValidity, DateUtils.truncate(new Date(), java.util.Calendar.DAY_OF_MONTH));
            queryWrapper.eq(VipUserQuanyi::getState, "0");
        }
        if (listType == 1) {
            queryWrapper.ge(VipUserQuanyi::getValidity, DateUtils.truncate(new Date(), java.util.Calendar.DAY_OF_MONTH));
            queryWrapper.eq(VipUserQuanyi::getState, "0");
        }
        queryWrapper.orderBy(true, false, VipUserQuanyi::getValidity);
        IPage<VipUserQuanyi> list = vipUserQuanyiService.page(stlist, queryWrapper);
        return R.ok(list);
    }


    @Anonymous
    @Auth
    @ApiOperation("待领取优惠券列表")
    @GetMapping("/userUnclaimedList")
    public TableDataInfo userUnclaimedList(@RequestHeader String token,
                                           @RequestParam Integer pageNum,
                                           @RequestParam Integer pageSize,
                                           @RequestParam(required = false) Long mdId
    ) {
        JwtUtil jwtUtil = new JwtUtil();
        String uid = jwtUtil.getusid(token);
        String language = getLanguage(uid);
        PageHelper.startPage(pageNum, pageSize);
        List<VipQuanyi> list = vipQuanyiService.userUnclaimedList(Long.valueOf(uid), language, mdId);
        return getDataTable(list);
    }


    @Anonymous
    @Auth
    @ApiOperation("用户领取优惠券")
    @PostMapping("/receive")
    @RepeatSubmit(interval = 1000, message = "请求过于频繁")
    @Transactional(rollbackFor = Exception.class)
    public R<String> receive(@RequestHeader String token, @RequestBody ReceiveQuanyiInput input) {
        JwtUtil jwtUtil = new JwtUtil();
        String userId = jwtUtil.getusid(token);
        LambdaQueryWrapper<VipQuanyi> query = new LambdaQueryWrapper<>();
        query.eq(VipQuanyi::getId, input.getQuanyiId());
        query.eq(VipQuanyi::getDeleted, "0");
        VipQuanyi quanyi = vipQuanyiService.getOne(query);
        if (quanyi == null) {
            throw new ServiceException(MessageUtils.message("no.youhuiquan.lqnodata"));
        }
        if ("1".equals(quanyi.getState())) {
            throw new ServiceException(MessageUtils.message("no.youhuiquan.lqyhqgb"));
        }
        if (quanyi.getTotal() != null && quanyi.getTotal().equals(quanyi.getClaimedCount())) {
            throw new ServiceException(MessageUtils.message("no.youhuiquan.lqyhqolqw"));
        }

        // 3. 检查用户输入数量是否合法
        if (input.num <= 0) {
            throw new ServiceException(MessageUtils.message("no.youhuiquan.lqyhqdy"));
        }

        // 4. 检查用户还能领取多少
        // 4.1 检查每人领取限制
        LambdaQueryWrapper<VipUserQuanyi> userCouponQuery = new LambdaQueryWrapper<>();
        userCouponQuery.eq(VipUserQuanyi::getUserId, userId)
                .eq(VipUserQuanyi::getQuanyiId, input.quanyiId);
        long userAlreadyClaimed = vipUserQuanyiService.count(userCouponQuery);
        int remainingPerUser = quanyi.getLqxz() - (int) userAlreadyClaimed;
        if (remainingPerUser <= 0) {
            throw new ServiceException(MessageUtils.message("no.youhuiquan.lqyhqysx"));
        }
        // 4.2 检查剩余库存
        long remainingStock = quanyi.getTotal() - quanyi.getClaimedCount();
        if (remainingStock <= 0) {
            throw new ServiceException(MessageUtils.message("no.youhuiquan.lqyhqolqw"));
        }
        // 4.3 确定实际可领取数量
        int actualReceiveNum = Math.min(input.num, remainingPerUser);
        actualReceiveNum = (int) Math.min(actualReceiveNum, remainingStock);
        Long version = quanyi.getVersion() != null ? quanyi.getVersion() + 1 : 0L;
        // 5. 使用乐观锁更新优惠券库存（防止并发超领）
        boolean updateSuccess = vipQuanyiService.update(
                new LambdaUpdateWrapper<VipQuanyi>()
                        .eq(VipQuanyi::getId, input.quanyiId)
                        .eq(VipQuanyi::getVersion, quanyi.getVersion()) // 乐观锁条件
                        .set(VipQuanyi::getClaimedCount, quanyi.getClaimedCount() + actualReceiveNum)
                        .set(VipQuanyi::getVersion, version)
        );
        if (!updateSuccess) {
            throw new ServiceException(MessageUtils.message("no.youhuiquan.lqyhqybxg"));
        }
        // 6. 为用户添加优惠券记录
        List<VipUserQuanyi> couponsToAdd = new ArrayList<>();
        Date now = new Date();
        Date expireTime = calculateExpireTime(now, quanyi.getValidity());
        for (int i = 0; i < actualReceiveNum; i++) {
            VipUserQuanyi coupon = new VipUserQuanyi();
            coupon.setUserId(Long.valueOf(userId));
            coupon.setQuanyiId(input.quanyiId);
            coupon.setCode(generateCouponCode());
            coupon.setState("0"); // 0-未使用
            coupon.setCreateTime(now);
            coupon.setValidity(expireTime);
            coupon.setYhfangs(quanyi.getYhfangs());
            coupon.setYhnum(quanyi.getYhnum());
            coupon.setName(quanyi.getName());
            coupon.setShuoming(quanyi.getShuoming());
            coupon.setTiaojian(quanyi.getTiaojian());
            coupon.setDeleted("0");
            coupon.setShId(quanyi.getShId());
            coupon.setSpId(quanyi.getSpId());
            coupon.setLanguage(quanyi.getLanguage());
            coupon.setPoster(quanyi.getPoster());
            coupon.setType(quanyi.getType());
            coupon.setMerchantId(quanyi.getMerchantId());
            couponsToAdd.add(coupon);
        }
        vipUserQuanyiService.saveBatch(couponsToAdd);
        return R.ok();
    }

    // 生成优惠券码
    private String generateCouponCode() {
        return UUID.randomUUID().toString().replace("-", "").substring(0, 12).toUpperCase();
    }

    // 计算过期时间
    private Date calculateExpireTime(Date now, Integer validityDays) {
        if (validityDays == null || validityDays <= 0) {
            return null; // 表示永久有效
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(now);
        calendar.add(Calendar.DAY_OF_MONTH, validityDays);
        return calendar.getTime();
    }


    /**
     * 获取用户优惠券
     * 详细信息
     */
    @Anonymous
    @Auth
    @ApiOperation("用户领取优惠券详情")

    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(vipUserQuanyiService.selectVipUserQuanyiById(id));
    }


}
