package com.czg.service.market.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.czg.account.entity.ShopUser;
import com.czg.account.service.ShopUserService;
import com.czg.constant.MarketConstants;
import com.czg.exception.CzgException;
import com.czg.market.dto.ChatCouponDTO;
import com.czg.market.dto.MkShopCouponGiftDTO;
import com.czg.market.dto.MkShopCouponRecordDTO;
import com.czg.market.entity.ChatCoupon;
import com.czg.market.entity.MkShopCouponRecord;
import com.czg.market.entity.ShopCoupon;
import com.czg.market.service.ChatCouponService;
import com.czg.market.service.MkShopCouponRecordService;
import com.czg.market.service.ShopCouponService;
import com.czg.market.vo.ChatCouponVO;
import com.czg.service.market.mapper.ChatCouponMapper;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 服务层实现。
 *
 * @author ww
 * @since 2025-12-02
 */
@Slf4j
@Service
public class ChatCouponServiceImpl extends ServiceImpl<ChatCouponMapper, ChatCoupon> implements ChatCouponService {
    @Resource
    private ShopCouponService couponService;
    @Resource
    private MkShopCouponRecordService recordService;
    @DubboReference
    private ShopUserService shopUserService;
//    @DubboReference
//    private UserInfoService userInfoService;


    @Override
    @Transactional
    public ChatCoupon createChatCoupon(Long shopId, ChatCouponDTO chatCoupon) {
        ShopCoupon coupon = couponService.getOne(QueryWrapper.create()
                .eq(ShopCoupon::getId, chatCoupon.getCouponId())
        );
        if (coupon == null) {
            throw new CzgException("优惠券不可使用，优惠券不存在");
        }
        if (!"all".equals(coupon.getGetUserType())) {
            throw new CzgException("优惠券不可使用，优惠券存在领取用户限制");
        }
        ChatCoupon saveChatCoupon = ChatCoupon.builder()
                .shopId(shopId)
                .title(chatCoupon.getTitle())
                .getLimit(chatCoupon.getGetLimit() == null ? 1 : chatCoupon.getGetLimit())
                .giveNum(chatCoupon.getGiveNum() == null ? MarketConstants.Num.NOT_LIMIT : chatCoupon.getGiveNum())
                .leftNum(chatCoupon.getGiveNum() == null ? MarketConstants.Num.NOT_LIMIT : chatCoupon.getGiveNum())
                .useNum(0)
                .couponId(chatCoupon.getCouponId())
                .build();
        save(saveChatCoupon);
        if (saveChatCoupon.getId() == null) {
            log.info("发放创建失败，群聊发放任务回填Id失败：{}", JSONObject.toJSONString(saveChatCoupon));
            throw new CzgException("发放创建失败，请联系管理员");
        }
        MkShopCouponRecord record = recordService.assembleRecord(saveChatCoupon.getId(), coupon);
        saveChatCoupon.setCouponJson(JSONObject.toJSONString(record));
        updateById(saveChatCoupon);
        return saveChatCoupon;
    }


    @Override
    public Page<ChatCouponVO> pageChatCoupon(Long shopId, Integer page, Integer size, Integer status) {
        return pageAs(Page.of(page, size),
                QueryWrapper.create()
                        .eq(ChatCoupon::getShopId, shopId)
                        .eq(ChatCoupon::getStatus, status)
                        .orderBy(ChatCoupon::getStatus).asc()
                        .orderBy(ChatCoupon::getId).desc(),
                ChatCouponVO.class);
    }

    /**
     * 失效
     */
    @Override
    public boolean expiredChatCoupon(Long shopId, Long id) {
        ChatCoupon coupon = new ChatCoupon();
        coupon.setStatus(3);
        return update(coupon, QueryWrapper.create()
                .eq(ChatCoupon::getId, id)
                .eq(ChatCoupon::getShopId, shopId)
        );
    }

    @Override
    @Transactional
    public void grantChatCoupon(Long id, Long shopId, Long userId) {
        ChatCoupon coupon = getById(id);
        if (coupon == null) {
            throw new CzgException("活动不存在");
        }
        if (coupon.getStatus() != 1) {
            throw new CzgException("活动已失效");
        }
        boolean exists = recordService.exists(QueryWrapper.create()
                .eq(MkShopCouponRecord::getSource, "群聊发放")
                .eq(MkShopCouponRecord::getSourceId, coupon.getId())
                .eq(MkShopCouponRecord::getShopId, shopId)
                .eq(MkShopCouponRecord::getUserId, userId)
        );
        if (exists) {
            throw new CzgException("不可重复领取");
        }
        if (coupon.getLeftNum() <= 0) {
            throw new CzgException("发放失败,剩余数量不足");
        }
        if (coupon.getLeftNum() < coupon.getGetLimit()) {
            throw new CzgException("发放失败,剩余数量不足");
        }
        coupon.setLeftNum(coupon.getLeftNum() - coupon.getGetLimit());
        if (coupon.getLeftNum() == 0) {
            coupon.setStatus(3);
        }
        updateById(coupon);
        ShopUser shopUser = shopUserService.getUserInfo(shopId, userId);

//        MkShopCouponRecord record = JSONObject.parseObject(coupon.getCouponJson(), MkShopCouponRecord.class);
//        record.setShopUserId(shopUserId);
//        record.setUserId(userId);
//        recordService.grantChatCoupon(record, coupon.getGetLimit());
        if (shopUser == null) {
            throw new CzgException("用户不存在");
        }
        MkShopCouponGiftDTO giftDTO = new MkShopCouponGiftDTO()
                .setCouponId(coupon.getCouponId())
                .setShopId(shopId)
                .setSourceId(coupon.getId())
                .setShopUserId(shopUser.getId())
                .setSource("群聊发放");
        recordService.receiveCoupon(giftDTO, coupon.getGetLimit(), false);
    }

    @Override
    public Page<MkShopCouponRecordDTO> grantChatCouponRecord(Long id, Integer status, Integer page, Integer size) {
        Page<MkShopCouponRecordDTO> recordPage = recordService.pageAs(Page.of(page, size),
                QueryWrapper.create()
                        .eq(MkShopCouponRecord::getSourceId, id)
                        .eq(MkShopCouponRecord::getStatus, status)
                        .orderBy(MkShopCouponRecord::getId).desc(),
                MkShopCouponRecordDTO.class);
        for (MkShopCouponRecordDTO record : recordPage.getRecords()) {
            ShopUser userInfo = shopUserService.getById(record.getShopUserId());
            record.setHeadImg(userInfo.getHeadImg());
            record.setNickName(userInfo.getNickName());
        }
        return recordPage;
    }
}
