package com.yiqi.api.controller;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yiqi.activity.domain.vo.weapp.WeAppActivityCouponQueryVO;
import com.yiqi.app.domain.*;
import com.yiqi.app.domain.dto.AppCouponItemQueryByAppUserIdDTO;
import com.yiqi.app.domain.dto.weapp.WeAppCouponItemQueryDTO;
import com.yiqi.app.domain.vo.AppCouponItemVO;
import com.yiqi.app.domain.vo.AppCouponTypeApplyClothVO;
import com.yiqi.app.domain.vo.AppCouponTypeVO;
import com.yiqi.app.domain.vo.weapp.AppCouponItemListVO;
import com.yiqi.app.service.IAppCouponItemService;
import com.yiqi.app.service.IAppCouponTypeApplyClothService;
import com.yiqi.app.service.IAppCouponTypeService;
import com.yiqi.common.constant.UrlConstants;
import com.yiqi.common.core.controller.BaseController;
import com.yiqi.common.core.domain.AuthHolder;
import com.yiqi.common.core.domain.R;
import com.yiqi.common.enums.DeleteStatus;
import com.yiqi.common.enums.SourceType;
import com.yiqi.common.enums.StatusType;
import com.yiqi.common.enums.SysBoolType;
import com.yiqi.common.exception.ServiceException;
import com.yiqi.common.utils.DateUtils;
import com.yiqi.common.utils.StringUtils;
import com.yiqi.common.utils.bean.BeanUtils;
import com.yiqi.core.domain.ClothItem;
import com.yiqi.core.service.IClothItemService;
import com.yiqi.system.domain.SysOrg;
import com.yiqi.system.service.ISysOrgService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static com.yiqi.common.utils.DateUtils.YYYY_MM_DD;

@Api(tags = "优惠券")
@RestController
@RequestMapping(value = UrlConstants.wxappApi + "/coupon")
public class WeAppCouponItemController extends BaseController {

    @Autowired
    private IAppCouponItemService appCouponItemService;
    @Autowired
    private IAppCouponTypeApplyClothService appCouponTypeApplyClothService;
    @Autowired
    private IClothItemService clothItemService;
    @Autowired
    private ISysOrgService sysOrgService;
    @Autowired
    private IAppCouponTypeService appCouponTypeService;

    @ApiOperation("获取我的优惠券列表")
    @PostMapping(value = "findPage")
    public R<List<AppCouponItemListVO>> findPage(@RequestBody @Valid WeAppCouponItemQueryDTO weAppCouponItemQueryDTO) throws Exception {
        LambdaQueryWrapper<AppCouponItem> queryWrapper = new QueryWrapper<AppCouponItem>().lambda().eq(AppCouponItem::getAppUserId, AuthHolder.userId());
        if (!StringUtils.isEmpty(weAppCouponItemQueryDTO.getCouponStatus())) {
            switch (weAppCouponItemQueryDTO.getCouponStatus()) {
                case "0"://未使用
                {
                    queryWrapper.eq(AppCouponItem::getIsUsed, SysBoolType.NO.getCode()).ge(AppCouponItem::getEndDate, DateUtils.dateTimeNow("yyyy-MM-dd"));
                    break;
                }
                case "1"://已使用
                {
                    queryWrapper.eq(AppCouponItem::getIsUsed, SysBoolType.YES.getCode());
                    break;
                }
                case "2"://已过期
                {
                    queryWrapper.eq(AppCouponItem::getIsUsed, SysBoolType.NO.getCode()).lt(AppCouponItem::getEndDate, DateUtils.dateTimeNow("yyyy-MM-dd"));
                    break;
                }
            }
        }
        queryWrapper.orderByAsc(AppCouponItem::getEndDate);
        List<AppCouponItem> list = appCouponItemService.page(new Page<>(weAppCouponItemQueryDTO.getPageNum(),
                        weAppCouponItemQueryDTO.getPageSize()),
                queryWrapper).getRecords();
        if (CollUtil.isEmpty(list)) {
            return R.ok(new ArrayList<AppCouponItemListVO>());
        }
        List<AppCouponItemListVO> voList = new ArrayList<>();
        list.forEach(l -> {
            AppCouponItemListVO vo = new AppCouponItemListVO();
            BeanUtils.copyProperties(l, vo);
            vo.setIsValid(this.getIsValidBy(l));
            voList.add(vo);
        });
        return R.ok(voList);
    }

    @PostMapping(value = "getlistByAppUserId")
    @ApiOperation("下单选择客户可使用的优惠券")
    public R<List<AppCouponItemVO>> getlistByAppUserId(@RequestBody @Valid AppCouponItemQueryByAppUserIdDTO appCouponItemQueryByAppUserIdDTO) throws Exception {
        if (appCouponItemQueryByAppUserIdDTO.getClothIds() == null || appCouponItemQueryByAppUserIdDTO.getClothIds().size() == 0) {
            throw new ServiceException("未选择衣服");
        }
        Map<Long, ClothItem> clothItemMap = clothItemService.list(new QueryWrapper<ClothItem>().lambda()
                        .in(ClothItem::getId, appCouponItemQueryByAppUserIdDTO.getClothIds())).stream()
                .collect(Collectors.toMap(ClothItem::getId, ClothItem -> ClothItem));
        appCouponItemQueryByAppUserIdDTO.setDiscountWay(null);
        List<AppCouponItemVO> appCouponItemVOS = appCouponItemService.getlistByAppUserId(appCouponItemQueryByAppUserIdDTO);
        if (appCouponItemVOS == null || appCouponItemVOS.size() == 0) {
            return R.ok(appCouponItemVOS);
        }
        List<AppCouponTypeApplyCloth> appCouponTypeApplyCloths = appCouponTypeApplyClothService.list(
                new QueryWrapper<AppCouponTypeApplyCloth>().lambda()
                        .in(AppCouponTypeApplyCloth::getCouponTypeId
                                , appCouponItemVOS.stream().map(AppCouponItemVO::getCouponTypeId).collect(Collectors.toSet()))
                        .in(AppCouponTypeApplyCloth::getClothItemId, appCouponItemQueryByAppUserIdDTO.getClothIds()));
        List<AppCouponTypeApplyClothVO> appCouponTypeApplyClothVOS = new ArrayList<>();
        for (AppCouponTypeApplyCloth appCouponTypeApplyCloth : appCouponTypeApplyCloths) {
            AppCouponTypeApplyClothVO appCouponTypeApplyClothVO = new AppCouponTypeApplyClothVO();
            org.springframework.beans.BeanUtils.copyProperties(appCouponTypeApplyCloth, appCouponTypeApplyClothVO);
            appCouponTypeApplyClothVO.setClothItemName(clothItemMap.get(appCouponTypeApplyCloth.getClothItemId()).getName());
            appCouponTypeApplyClothVOS.add(appCouponTypeApplyClothVO);
        }
        Map<Long, List<AppCouponTypeApplyClothVO>> appCouponTypeApplyClothMap = appCouponTypeApplyClothVOS.stream()
                .collect(Collectors.groupingBy(AppCouponTypeApplyClothVO::getCouponTypeId));

        for (AppCouponItemVO appCouponItemVO : appCouponItemVOS) {
            if (appCouponItemVO.getUseScope().equals(2)) {
                appCouponItemVO.setAppCouponTypeApplyClothVOS(appCouponTypeApplyClothMap.get(appCouponItemVO.getCouponTypeId()));
            }
        }
        return R.ok(appCouponItemVOS);
    }

    private String getIsValidBy(AppCouponItem appCouponItem) {
        if (appCouponItem == null) {
            return SysBoolType.NO.getCode();
        }
        if (SysBoolType.NO.getCode().equals(appCouponItem.getIsUsed()) && appCouponItem.getEndDate().compareTo(DateUtils.getNowDate(DateUtils.YYYY_MM_DD)) >= 0) {
            return SysBoolType.YES.getCode();
        }
        return SysBoolType.NO.getCode();
    }

    @ApiOperation("查询优惠券适用组织")
    @GetMapping(value = "orgListByCouponId")
    public R<List<SysOrg>> orgListByCouponId(@RequestParam @ApiParam("优惠券ID") Long couponTypeId) {
        return R.ok(appCouponItemService.orgListByCouponId(couponTypeId));
    }

    @ApiOperation("查询优惠券适用衣服")
    @GetMapping(value = "clothListByCouponId")
    public R<List<ClothItem>> clothListByCouponId(@RequestParam @ApiParam("优惠券ID") Long couponTypeId) {
        List<Long> clothIds = appCouponTypeApplyClothService.list(new QueryWrapper<AppCouponTypeApplyCloth>().lambda()
                        .eq(AppCouponTypeApplyCloth::getCouponTypeId, couponTypeId)
                        .eq(AppCouponTypeApplyCloth::getDelFlag, DeleteStatus.OK.getCode())).stream()
                .map(AppCouponTypeApplyCloth::getClothItemId).collect(Collectors.toList());
        if (clothIds.size() == 0) {
            return R.ok(new ArrayList<>());
        }
        return R.ok(clothItemService.list(new QueryWrapper<ClothItem>().lambda().in(ClothItem::getId, clothIds)));
    }


    /**
     * 领券中心
     */
    @GetMapping("/receive/list")
    @ApiOperation(value = "领券中心")
    public R<List<AppCouponType>> receiveCouponList() {
        List<AppCouponType> list = appCouponTypeService.list(new QueryWrapper<AppCouponType>().lambda()
                .eq(AppCouponType::getStatus, StatusType.OK.getCode())
                .eq(AppCouponType::getSendWay, 1)
                .gt(AppCouponType::getCouponStock, 0)
                .eq(AppCouponType::getDelFlag, DeleteStatus.OK.getCode())
                .ge(AppCouponType::getEndDate, DateUtils.getNowDate(YYYY_MM_DD)));
        if (CollUtil.isEmpty(list)) {
            return R.ok();
        }
        return R.ok(list);
    }


    /**
     * 领券中心
     */
    @PostMapping("/receiveCoupon")
    @ApiOperation(value = "领券")
    public R<List<AppCouponType>> receiveCoupon(Long couponTypeId) {
        String key = couponTypeId + "";
        synchronized (key.intern()) {
            appCouponItemService.receiveCouponItemByUser(couponTypeId, AuthHolder.userId());
        }
        return R.ok();
    }
}
