package com.czg.controller.admin;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.thread.ThreadUtil;
import com.czg.account.vo.UserCouponVo;
import com.czg.log.annotation.OperationLog;
import com.czg.market.dto.MkCouponGiftDTO;
import com.czg.market.dto.MkRewardCouponDTO;
import com.czg.market.dto.MkShopCouponRecordDTO;
import com.czg.market.dto.ShopCouponDTO;
import com.czg.market.entity.MkPointsGoods;
import com.czg.market.service.MkCouponGiftService;
import com.czg.market.service.MkPointsGoodsService;
import com.czg.market.service.MkShopCouponRecordService;
import com.czg.market.service.ShopCouponService;
import com.czg.product.service.ShopSyncService;
import com.czg.resp.CzgResult;
import com.czg.sa.StpKit;
import com.czg.utils.AssertUtil;
import com.czg.validator.group.DefaultGroup;
import com.czg.validator.group.InsertGroup;
import com.czg.validator.group.UpdateGroup;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 优惠券
 *
 * @author ww
 */
@Slf4j
@RestController
@RequestMapping("/admin/coupon")
public class ACouponController {
    @Resource
    private ShopCouponService shopCouponService;
    @Resource
    private MkCouponGiftService couponGiftService;
    @Resource
    private MkShopCouponRecordService couponRecordService;
    @DubboReference
    private ShopSyncService shopSyncService;
    @Resource
    private MkPointsGoodsService pointsGoodsSettingService;

    /**
     * 分页
     */
    @GetMapping("page")
//    @SaAdminCheckPermission("coupon:page")
    public CzgResult<Page<ShopCouponDTO>> getCouponPage(ShopCouponDTO param) {
        Long shopId = StpKit.USER.getShopId();
        param.setShopId(shopId);
        Page<ShopCouponDTO> data = shopCouponService.getCouponPage(param);
        return CzgResult.success(data);
    }

    /**
     * 详情
     *
     * @param id 主键id
     */
    @GetMapping("{id}")
//    @SaAdminCheckPermission("coupon:info")
    public CzgResult<ShopCouponDTO> getCouponById(@PathVariable("id") Long id) {
        AssertUtil.isNull(id, "{}不能为空", "id");
        ShopCouponDTO data = shopCouponService.getCouponById(id);
        return CzgResult.success(data);
    }

    /**
     * 新增
     */
    @PostMapping
    @OperationLog("优惠券-新增")
//    @SaAdminCheckPermission("coupon:add")
    public CzgResult<Void> addCoupon(@RequestBody @Validated({InsertGroup.class, DefaultGroup.class}) ShopCouponDTO dto) {
        Long shopId = StpKit.USER.getShopId();
        dto.setShopId(shopId);
        dto.setLeftNum(dto.getGiveNum());
        if ("custom".equals(dto.getValidType())) {
            if (dto.getValidEndTime().isBefore(LocalDateTime.now())) {
                dto.setStatus(0);
            }
        }
        shopCouponService.addCoupon(dto);
        asyncToBranchShop(dto.getId(), 1);
        return CzgResult.success();
    }

    /**
     * 修改
     */
    @PutMapping
    @OperationLog("优惠券-修改")
//    @SaAdminCheckPermission("coupon:update")
    public CzgResult<Void> updateCoupon(@RequestBody @Validated({UpdateGroup.class, DefaultGroup.class}) ShopCouponDTO dto) {
        Long shopId = StpKit.USER.getShopId();
        dto.setShopId(shopId);
        if ("custom".equals(dto.getValidType())) {
            if (dto.getValidEndTime().isBefore(LocalDateTime.now())) {
                dto.setStatus(0);
            }
        }
        if (dto.getStatus().equals(0)) {
            //优惠券禁用 同步下架积分优惠券商品
            pointsGoodsSettingService.updateGoodsCouponStatus(dto.getId());
        }
        shopCouponService.updateCouponById(dto);
        couponGiftService.upCouponName(dto.getId(), dto.getTitle());
        asyncToBranchShop(dto.getId(), 2);
        return CzgResult.success();
    }

    /**
     * 删除
     */
    @DeleteMapping
    @OperationLog("优惠券-删除")
//    @SaAdminCheckPermission("prodGroup:delete")
    public CzgResult<String> deleteCoupon(@RequestParam Long id, @RequestParam Integer type) {
        AssertUtil.isNull(id, "{}不能为空", "id");
        if (type != 1) {
            List<MkCouponGiftDTO> gifts = couponGiftService.getCouponGiftBySourceId(id, 3);
            if (CollUtil.isNotEmpty(gifts)) {
                String collect = gifts.stream()
                        .map(MkCouponGiftDTO::getSourceName)
                        .filter(name -> name != null && !name.isEmpty())
                        .collect(Collectors.joining(","));
                return CzgResult.success(collect);
            }
        }
        shopCouponService.deleteCoupon(id);
        couponGiftService.deleteCoupon(id);
        //优惠券删除 同步下架积分优惠券商品
        pointsGoodsSettingService.updateGoodsCouponStatus(id);
        asyncToBranchShop(id, 3);
        return CzgResult.success();
    }

    /**
     * 获取该券关联的功能列表
     *
     * @param couponId 如果syncId有值 则为syncId 否则为id
     */
    @GetMapping("/gifts")
    public CzgResult<Page<MkCouponGiftDTO>> getCouponGiftPage(@RequestParam Long couponId, @RequestParam(required = false) Integer type) {
        Page<MkCouponGiftDTO> data = couponGiftService.getCouponGiftPage(couponId, type);
        return CzgResult.success(data);
    }

    /**
     * 消费赠券已领取详情
     */
    @GetMapping("/consumerRecord")
    public CzgResult<Page<MkShopCouponRecordDTO>> getConsumerRecord(
            @RequestParam(required = false) String startTime,
            @RequestParam(required = false) String endTime,
            MkShopCouponRecordDTO param) {
        Page<MkShopCouponRecordDTO> data = couponRecordService.getConsumerRecord(param, startTime, endTime);
        return CzgResult.success(data);
    }

    /**
     * 优惠券列表/已领取详情
     */
    @GetMapping("/record")
    public CzgResult<Map<String, Object>> getRecordByCoupon(
            @RequestParam(required = false) String startTime,
            @RequestParam(required = false) String endTime,
            MkShopCouponRecordDTO param) {
        Map<String, Object> data = couponRecordService.getRecord(param, startTime, endTime);
        return CzgResult.success(data);
    }

    /**
     * 优惠券列表/已领取详情
     *
     * @param param 用户的优惠券列表 使用该对象的UserId
     */
    @GetMapping("/getRecordByUser")
    public CzgResult<Page<MkShopCouponRecordDTO>> getRecordByUser(
            @RequestParam(required = false) String startTime,
            @RequestParam(required = false) String endTime,
            MkShopCouponRecordDTO param) {
        Page<MkShopCouponRecordDTO> data = couponRecordService.getRecordByShopUser(param, startTime, endTime);
        return CzgResult.success(data);
    }

    /**
     * 删除用户优惠券 失效
     *
     * @param id 优惠券记录Id
     */
    @DeleteMapping("/deleteRecord")
    public CzgResult<Void> cancelRecord(Long id) {
        couponRecordService.deleteRecord(id);
        return CzgResult.success();
    }

    private void asyncToBranchShop(Long id, Integer type) {
        long shopId = StpKit.USER.getShopId(0L);
        log.info("优惠券同步,优惠券id:{},类型:{}", id, type);
        ThreadUtil.execAsync(() -> shopSyncService.syncCouponBySourceShop(shopId, id, type));
    }

    /**
     * 券发放
     *
     * @return 是否发放成功
     */
    @PostMapping("/grant")
    public CzgResult<Boolean> rewardCoupon(@Validated @RequestBody MkRewardCouponDTO rewardCouponDTO) {
        return CzgResult.success(couponRecordService.grant(rewardCouponDTO.getShopId() != null ? rewardCouponDTO.getShopId() : StpKit.USER.getShopId(), rewardCouponDTO, "管理员赠送"));
    }


    /**
     * 生成订单后使用
     * 通过用户Id 查找优惠券
     *
     * @param shopUserId 店铺用户Id
     */
    @GetMapping("/findCoupon")
    public CzgResult<List<UserCouponVo>> findCoupon(@RequestParam Long shopUserId, @RequestParam(required = false) Integer type, @RequestParam(required = false) Integer isFood) {
        return CzgResult.success(shopCouponService.findCoupon(StpKit.USER.getShopId(), shopUserId, type, isFood));
    }

    /**
     * 群聊可发放优惠券列表
     *
     * @param search 优惠券名称模糊搜索
     */
    @GetMapping("/chatCoupon")
    public CzgResult<Page<ShopCouponDTO>> chatCoupon(@RequestParam(required = false, defaultValue = "1") Integer page,
                                                     @RequestParam(required = false, defaultValue = "10") Integer size,
                                                     @RequestParam(required = false) String search) {
        Long shopId = StpKit.USER.getShopId();
        return CzgResult.success(shopCouponService.chatCoupon(shopId, search));
    }
}
