package com.fs.live.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.fs.common.constant.LiveKeysConstant;
import com.fs.common.core.domain.R;
import com.fs.common.core.redis.RedisUtil;
import com.fs.common.utils.DateUtils;
import com.fs.common.utils.StringUtils;
import com.fs.live.domain.*;
import com.fs.live.mapper.LiveCouponIssueMapper;
import com.fs.live.mapper.LiveGoodsMapper;
import com.fs.live.mapper.LiveMapper;
import com.fs.live.param.CouponPO;
import com.fs.live.service.*;
import com.fs.live.vo.LiveCouponListVo;
import com.fs.store.domain.FsStoreCoupon;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fs.live.mapper.LiveCouponMapper;
import org.springframework.transaction.annotation.Transactional;

/**
 * 优惠券Service业务层处理
 *
 * @author fs
 * @date 2025-09-30
 */
@Service
public class LiveCouponServiceImpl implements ILiveCouponService
{
    @Autowired
    private LiveCouponMapper liveCouponMapper;

    @Autowired
    private LiveMapper liveMapper;

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private ILiveCouponIssueUserService liveCouponIssueUserService;
    @Autowired
    private ILiveCouponUserService liveCouponUserService;
    @Autowired
    private ILiveCouponIssueService liveCouponIssueService;
    @Autowired
    private LiveGoodsMapper liveGoodsMapper;
    @Autowired
    private ILiveAutoTaskService liveAutoTaskService;
    @Autowired
    private LiveCouponIssueMapper liveCouponIssueMapper;

    /**
     * 查询优惠券
     *
     * @param couponId 优惠券ID
     * @return 优惠券
     */
    @Override
    public LiveCoupon selectLiveCouponById(Long couponId)
    {
        return liveCouponMapper.selectLiveCouponById(couponId);
    }

    /**
     * 查询优惠券列表
     *
     * @param liveCoupon 优惠券
     * @return 优惠券
     */
    @Override
    public List<LiveCoupon> selectLiveCouponList(LiveCoupon liveCoupon)
    {
        return liveCouponMapper.selectLiveCouponList(liveCoupon);
    }

    /**
     * 新增优惠券
     *
     * @param liveCoupon 优惠券
     * @return 结果
     */
    @Override
    public int insertLiveCoupon(LiveCoupon liveCoupon)
    {
        liveCoupon.setCreateTime(DateUtils.getNowDate());
        return liveCouponMapper.insertLiveCoupon(liveCoupon);
    }

    /**
     * 修改优惠券
     *
     * @param liveCoupon 优惠券
     * @return 结果
     */
    @Override
    public int updateLiveCoupon(LiveCoupon liveCoupon)
    {
        liveCoupon.setUpdateTime(DateUtils.getNowDate());
        return liveCouponMapper.updateLiveCoupon(liveCoupon);
    }

    /**
     * 批量删除优惠券
     *
     * @param couponIds 需要删除的优惠券ID
     * @return 结果
     */
    @Override
    public int deleteLiveCouponByIds(Long[] couponIds)
    {
        // 联动删除：删除所有直播间存在的优惠券、定时任务和缓存
        for (Long couponId : couponIds) {
            // 删除所有直播间相关的自动化任务（liveId为null表示所有直播间）
            liveAutoTaskService
                    .deleteAutoTasksByCouponId(couponId, null);

            // 查询所有使用该优惠券的优惠券发布记录
            LiveCouponIssue queryIssue = new LiveCouponIssue();
            queryIssue.setCouponId(couponId);
            List<LiveCouponIssue> couponIssues = liveCouponIssueMapper.selectLiveCouponIssueList(queryIssue);

            // 删除所有直播间的关联关系
            for (LiveCouponIssue issue : couponIssues) {
                if (issue.getId() != null) {
                    // 查询所有使用该优惠券发布的直播间关联关系
                    List<LiveCouponIssueRelation> relations = liveCouponMapper.selectCouponRelationByCouponIssueId(issue.getId());
                    for (LiveCouponIssueRelation relation : relations) {
                        LiveCouponListVo listVo = new LiveCouponListVo();
                        listVo.setCouponIds(java.util.Arrays.asList(issue.getId()));
                        listVo.setLiveId(relation.getLiveId().intValue());
                        liveCouponMapper.handleDeleteSelectedAdmin(listVo);
                    }
                }
            }
        }
        return liveCouponMapper.deleteLiveCouponByIds(couponIds);
    }

    /**
     * 删除优惠券信息
     *
     * @param couponId 优惠券ID
     * @return 结果
     */
    @Override
    public int deleteLiveCouponById(Long couponId)
    {
        return liveCouponMapper.deleteLiveCouponById(couponId);
    }

    @Override
    public List<LiveCoupon> selectLiveCouponByIds(String ids) {
        return liveCouponMapper.selectLiveCouponByIds(ids);
    }

    @Override
    public List<LiveCoupon> selectLiveCouponByLiveId(Long liveId) {
        return liveCouponMapper.selectLiveCouponByLiveId(liveId);
    }

    @Override
    public List<LiveCoupon> listCoupon(Long liveId, String couponName) {
        return liveCouponMapper.listCoupon(liveId, couponName);
    }

    @Override
    public int insertLiveCouponEntity(Map<String, Object> payload) {
        Long liveId = Long.valueOf((String) payload.get("liveId"));
        Live live = liveMapper.selectLiveByLiveId(liveId);
        if(live == null) return -1;
        String s = String.valueOf(payload.get("couponIds"));
        if(StringUtils.isEmpty(s)) return -1;
        Set<Long> collect = liveCouponMapper.selectLiveCouponIssueByLiveId(liveId).stream().collect(Collectors.toSet());

        String[] split = s.split(",");
        for (String couponId : split) {
            if(collect.contains(Long.valueOf(couponId))) continue;
            liveCouponMapper.insertLiveCouponEntity(liveId, Long.valueOf(couponId));
        }
        return 1;
    }

    @Override
    public R handleIsShowChange(Map<String, Object> payload) {
        Long liveId = Long.valueOf((String) payload.get("liveId"));
        Live live = liveMapper.selectLiveByLiveId(liveId);
        if(live == null) return R.error("直播间不存在");
        boolean isShow = Boolean.parseBoolean(payload.get("isShow").toString());
        if (isShow) {
            int i = liveCouponMapper.selectShowByLiveId(liveId);
            if (i > 0) return R.error("直播间已存在优惠券");
        }
        Long couponId = Long.valueOf(payload.get("couponId").toString());
        LiveCouponIssueRelation liveCouponIssueRelation = liveCouponMapper.selectRelation(liveId,couponId);
        if(ObjectUtil.isEmpty(liveCouponIssueRelation.getGoodsId())) return R.error("未绑定商品，无法发布！");
        liveCouponMapper.updateShow(liveId, couponId, isShow ? 1 : 0);
        return R.ok("操作成功");
    }

    @Override
    @Transactional
    public R handleDeleteSelectedAdmin(LiveCouponListVo listVo) {
        // 在删除前，查询关联关系，获取couponId和liveId，用于联动删除
        if (listVo.getCouponIds() != null && !listVo.getCouponIds().isEmpty() && listVo.getLiveId() != null) {
            Long liveId = Long.valueOf(listVo.getLiveId());
            for (Long couponIssueId : listVo.getCouponIds()) {
                // 查询优惠券发布信息
                LiveCouponIssue liveCouponIssue = liveCouponIssueMapper.selectLiveCouponIssueById(couponIssueId);
                if (liveCouponIssue != null && liveCouponIssue.getCouponId() != null) {
                    // 删除相关的自动化任务
                    liveAutoTaskService
                            .deleteAutoTasksByCouponId(liveCouponIssue.getCouponId(), liveId);
                }
            }
        }
        liveCouponMapper.handleDeleteSelectedAdmin(listVo);
        return R.ok();
    }

    @Override
    @Transactional
    public int delLiveCoupon(LiveCouponListVo vo) {
        // 在删除前，查询关联关系，获取couponId和liveId，用于联动删除
        if (vo.getCouponIds() != null && !vo.getCouponIds().isEmpty() && vo.getLiveId() != null) {
            Long liveId = Long.valueOf(vo.getLiveId());
            for (Long couponIssueId : vo.getCouponIds()) {
                // 查询优惠券发布信息
                LiveCouponIssue liveCouponIssue = liveCouponIssueMapper.selectLiveCouponIssueById(couponIssueId);
                if (liveCouponIssue != null && liveCouponIssue.getCouponId() != null) {
                    // 删除相关的自动化任务
                    liveAutoTaskService
                            .deleteAutoTasksByCouponId(liveCouponIssue.getCouponId(), liveId);
                }
            }
        }
        liveCouponMapper.handleDeleteSelectedAdmin(vo);
        return 1;
    }

    @Override
    public R updateLiveCouponBind(LiveCouponListVo listVo) {
        Live live = liveMapper.selectLiveByLiveId(Long.valueOf(listVo.getLiveId()));
        if(live == null) return R.error("直播间不存在");
        int i = liveCouponMapper.updateLiveCouponBind(listVo);
        if(i > 0) return R.ok("操作成功");
        return R.error("操作失败");
    }

    @Override
    @Transactional
    public R claimCoupon(CouponPO coupon) {
        Object o = redisUtil.hashGet(String.format(LiveKeysConstant.LIVE_HOME_PAGE_CONFIG_COUPON, coupon.getLiveId(), coupon.getCouponIssueId()), String.valueOf(coupon.getUserId()));
        if (ObjectUtil.isNotEmpty(o)) {
            return R.error("您已经领取过优惠券了！");
        }
        LiveCouponIssue issue = liveCouponMapper.selectLiveCouponIssueByLiveIdAndCouponId(coupon.getLiveId(), coupon.getCouponIssueId());
        if (coupon == null || issue == null || issue.getStatus() != 1) {
            return R.error("优惠券不存在或者已下架！");
        }

        LiveCoupon liveCoupon = liveCouponMapper.selectLiveCouponById(issue.getCouponId());
        if (liveCoupon == null) {
            return R.error("优惠券不存在！");
        }

        // 检查单场直播可使用优惠券数量限制
        String liveLimitKey = String.format("live:coupon:limit:%s:%s", coupon.getLiveId(), coupon.getCouponIssueId());
        Integer liveLimitNum = liveCoupon.getLiveLimitNum();
        int currentClaimedCount = 0;

        if (liveLimitNum != null && liveLimitNum > 0) {
            // 先查Redis缓存
            Object cachedCount = redisUtil.get(liveLimitKey);

            if (cachedCount != null) {
                currentClaimedCount = Integer.parseInt(cachedCount.toString());
            } else {
                // 缓存不存在，查询数据库
                currentClaimedCount = liveCouponIssueUserService.countClaimedByLiveIdAndIssueId(coupon.getLiveId(), coupon.getCouponIssueId());
                // 存入Redis，24小时过期
                redisUtil.set(liveLimitKey, currentClaimedCount, 24 * 60 * 60, java.util.concurrent.TimeUnit.SECONDS);
            }

            if (currentClaimedCount >= liveLimitNum) {
                return R.error("此优惠券单场直播领取数量已达上限！");
            }
        }

        Long decrement = redisUtil.decrement(String.format(LiveKeysConstant.LIVE_COUPON_NUM , coupon.getCouponIssueId()));

        if (decrement < 0L) {
            issue.setStatus(-1);
            issue.setRemainCount(0L);
            redisUtil.delete(String.valueOf(issue.getId()));
            liveCouponIssueService.updateLiveCouponIssue(issue);
            return R.error("此优惠券已领完");
        }
        Date now = DateUtils.getNowDate();
        LiveCouponIssueUser record = new LiveCouponIssueUser();
        record.setUserId(coupon.getUserId());
        record.setIssueId(issue.getId());
        record.setCreateTime(now);
        record.setUpdateTime(now);
        record.setIsDel(0);
        record.setGoodsId(coupon.getGoodsId());
        record.setLiveId(coupon.getLiveId());


        LiveCouponUser userRecord = new LiveCouponUser();
        userRecord.setCouponId(liveCoupon.getCouponId());
        userRecord.setUserId(Math.toIntExact(coupon.getUserId()));
        userRecord.setCouponTitle(liveCoupon.getTitle());
        userRecord.setCouponPrice(liveCoupon.getCouponPrice());
        userRecord.setUseMinPrice(liveCoupon.getUseMinPrice());
        userRecord.setCreateTime(now);
        userRecord.setUpdateTime(now);
        userRecord.setStatus(0);
        userRecord.setLimitTime(DateUtils.addDays(now, Math.toIntExact(liveCoupon.getCouponTime())));
        userRecord.setIsFail(1);
        userRecord.setIsDel(0);
        userRecord.setIsDel(0);
        userRecord.setGoodsId(coupon.getGoodsId());
        userRecord.setType("live-"+coupon.getLiveId());
        liveCouponUserService.insertLiveCouponUser(userRecord);
        liveCouponIssueUserService.insertLiveCouponIssueUser(record);
        redisUtil.hashPut(String.format(LiveKeysConstant.LIVE_HOME_PAGE_CONFIG_COUPON, coupon.getLiveId(), coupon.getCouponIssueId()), String.valueOf(coupon.getUserId()), JSONUtil.toJsonStr(record));

        // 更新单场直播领取数量缓存
        if (liveLimitNum != null && liveLimitNum > 0) {
            redisUtil.set(liveLimitKey, currentClaimedCount + 1, 24 * 60 * 60, java.util.concurrent.TimeUnit.SECONDS);
        }

        return R.ok("恭喜您抢到优惠券");
    }

    @Override
    public R userCouponList(CouponPO coupon) {
        List<LiveCouponUser> list = liveCouponUserService.selectLiveCouponUserByCouponPO(coupon);
        return R.ok().put("data", list);
    }

    @Override
    public R curCoupon(CouponPO coupon) {
        List<LiveCouponUser> list = liveCouponUserService.curCoupon(coupon);
        return R.ok().put("data", list);
    }

    @Override
    public List<LiveCoupon> listOn(Long liveId) {
        return liveCouponMapper.listOn(liveId);
    }


}
