package com.fzm.mall.server.admin.marketing.model;

import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.SystemClock;
import com.fzm.mall.server.admin.goods_center.model.Category;
import com.fzm.mall.server.admin.goods_center.service.ICategoryService;
import com.fzm.mall.server.admin.marketing.service.IPromotionCategoryService;
import com.fzm.mall.server.admin.marketing.service.IPromotionRuleService;
import com.fzm.mall.server.admin.marketing.service.IPromotionSkuService;
import com.fzm.mall.server.admin.util.UUIDUtil;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品促销
 * </p>
 *
 * @author wulixian
 * @since 2021-03-10
 */
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("marketing_promotion")
@ApiModel(value = "Promotion对象", description = "商品促销")
public class Promotion implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 促销-0.删除
     */
    public static final Integer PROMOTION_STATUS_DELETED = 0;

    /**
     * 促销-1.有效
     */
    public static final Integer PROMOTION_STATUS_EFFECTIVE = 1;

    /**
     * 促销-2.未开始
     */
    public static final Integer PROMOTION_STATUS_NOT_STARTED = 2;

    /**
     * 促销-3:已过期
     */
    public static final Integer PROMOTION_STATUS_EXPIRED = 3;

    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    @ApiModelProperty(value = "促销编号")
    private String promotionId;

    @ApiModelProperty(value = "类型  1:会员优惠  2:满减  3:满折  4:直降  5: 折扣  ")
    private Integer type;

    @ApiModelProperty(value = "促销名称")
    private String name;

    @ApiModelProperty(value = "活动范围 1.全部 2.APP 3.PC 4.微信小程序")
    private Integer scope;

    @ApiModelProperty(value = "范围类型1: 全部  2: 指定类目  3: 指定商品")
    private Integer rangeType;

    @ApiModelProperty(value = "描述")
    private String remark;

    @ApiModelProperty(value = "促销开始时间")
    private Long startTime;

    @ApiModelProperty(value = "促销结束时间")
    private Long endTime;

    @ApiModelProperty(value = "状态 0->不可用;1->进行中;2->未开始;3->已结束")
    private Integer status;

    @ApiModelProperty(value = "创建时间")
    @TableField(fill = FieldFill.INSERT)
    private Long createTime;

    @ApiModelProperty(value = "更新时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Long updateTime;

    @ApiModelProperty(value = "商户id")
    private String merchantId;

    @TableField(exist = false)
    @ApiModelProperty(value = "商品促销规则")
    private PromotionRule promotionRule;

    @TableField(exist = false)
    @ApiModelProperty(value = "商品规格集合")
    private List<PromotionSku> promotionSkuList;

    @TableField(exist = false)
    @ApiModelProperty(value = "优惠券对应的商品类目")
    private List<Category> categoryList;

    /**
     * 保存商品促销规则
     *
     * @param promotionRuleService
     * @param promotion
     */
    public void savePromotionRule(IPromotionRuleService promotionRuleService, Promotion promotion) {
        PromotionRule promotionRule = promotion.getPromotionRule();
        promotionRule.setPromotionRuleId(UUIDUtil.getUUID());
        promotionRule.setPromotionId(promotion.getPromotionId());
        promotionRule.setStatus(PromotionRule.PROMOTION_RULE_STATUS_EFFECTIVE);
        promotionRule.setMerchantId(promotion.getMerchantId());
        promotionRuleService.save(promotionRule);
    }

    /**
     * 保存促销的商品规格
     *
     * @param promotionSkuService
     * @param promotion
     */
    public void savePromotionSku(IPromotionSkuService promotionSkuService, Promotion promotion) {
        String pId = promotion.getPromotionId();
        String mId = promotion.getMerchantId();
        List<PromotionSku> promotionSkuList = promotion.getPromotionSkuList();
        promotionSkuList.forEach(promotionSku -> {
            promotionSku.setPromotionSkuId(UUIDUtil.getUUID());
            promotionSku.setPromotionId(pId);
            promotionSku.setStatus(PromotionSku.PROMOTION_SKU_STATUS_EFFECTIVE);
            promotionSku.setMerchantId(mId);
        });

        promotionSkuService.saveBatch(promotionSkuList);
    }

    /**
     * 逻辑删除促销归规则
     *
     * @param promotionRuleService
     * @param promotionId
     * @param merchantId
     */
    public void deletePromotionRule(IPromotionRuleService promotionRuleService, String promotionId, String merchantId) {
        UpdateWrapper<PromotionRule> wrapper = new UpdateWrapper<>();
        wrapper.eq("promotion_id", promotionId)
                .eq("merchant_id", merchantId)
                .set("status", PromotionRule.PROMOTION_RULE_STATUS_DELETED);
        promotionRuleService.update(wrapper);
    }

    /**
     * 逻辑删除参与促销的商品
     *
     * @param promotionSkuService
     * @param promotionId
     * @param merchantId
     */
    public void deletePromotionSku(IPromotionSkuService promotionSkuService, String promotionId, String merchantId) {
        UpdateWrapper<PromotionSku> wrapper = new UpdateWrapper<>();
        wrapper.eq("promotion_id", promotionId)
                .eq("merchant_id", merchantId)
                .set("status", PromotionSku.PROMOTION_SKU_STATUS_DELETED);
        promotionSkuService.update(wrapper);
    }

    /**
     * 获取促销活动规则
     *
     * @param promotionRuleService
     * @param promotionId
     * @param merchantId
     */
    public void readRule(IPromotionRuleService promotionRuleService, String promotionId, String merchantId) {
        QueryWrapper<PromotionRule> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("promotion_id", promotionId)
                .eq("merchant_id", merchantId);
        PromotionRule promotionRule = promotionRuleService.getOne(queryWrapper);

        setPromotionRule(promotionRule);
    }

    /**
     * 获取参与促销的商品规格
     *
     * @param promotionSkuService
     * @param promotionId
     * @param merchantId
     */
    public void listSku(IPromotionSkuService promotionSkuService, String promotionId, String merchantId) {

        List<PromotionSku> promotionSkuList = promotionSkuService.listSku(promotionId, merchantId);

        setPromotionSkuList(promotionSkuList);
    }

    public void updatePromotionRule(IPromotionRuleService promotionRuleService, Promotion promotion) {
        PromotionRule promotionRule = promotion.getPromotionRule();
        UpdateWrapper<PromotionRule> wrapper = new UpdateWrapper<>();
        wrapper.eq("promotion_rule_id", promotionRule.getPromotionRuleId())
                .eq("promotion_id", promotion.getPromotionId())
                .eq("merchant_id", promotion.getMerchantId())
                .eq("update_time", promotionRule.getUpdateTime());
        promotionRuleService.update(promotionRule, wrapper);
    }

    public void updatePromotionSku(IPromotionSkuService promotionSkuService, Promotion promotion) {
        String pId = promotion.getPromotionId();
        String mId = promotion.getMerchantId();

        List<PromotionSku> paramList = promotion.getPromotionSkuList();

        List<PromotionSku> toAddList = paramList.stream().filter(item -> StringUtils.isBlank(item.getPromotionSkuId())).collect(Collectors.toList());
        QueryWrapper<PromotionSku> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("promotion_id", pId)
                .eq("merchant_id", mId)
                .eq("status", PromotionSku.PROMOTION_SKU_STATUS_EFFECTIVE);
        List<PromotionSku> dataList = promotionSkuService.list(queryWrapper);

        toAddList.forEach(item -> {
            item.setPromotionSkuId(UUIDUtil.getUUID());
            item.setPromotionId(pId);
            item.setMerchantId(mId);
            item.setStatus(PromotionSku.PROMOTION_SKU_STATUS_EFFECTIVE);
        });
        promotionSkuService.saveBatch(toAddList);

        List<PromotionSku> reaminList = paramList;
        reaminList.removeAll(toAddList);

        List<String> reaminIdList = reaminList.stream().map(PromotionSku::getPromotionSkuId).collect(Collectors.toList());

        dataList.forEach(item -> {
            if(!reaminIdList.contains(item.getPromotionSkuId())){
                item.setStatus(PromotionSku.PROMOTION_SKU_STATUS_DELETED);
                UpdateWrapper<PromotionSku> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("promotion_id", pId)
                        .eq("merchant_id", mId);
                updateWrapper.eq("promotion_sku_id", item.getPromotionSkuId());
                promotionSkuService.update(item, updateWrapper);
            }
        });
    }

    public void saveCategory(IPromotionCategoryService promotionCategoryService) {
        if (CollectionUtils.isNotEmpty(this.categoryList)) {
            List<PromotionCategory> dataList = this.categoryList.stream().map(promotion -> {
                PromotionCategory promotionCategory = new PromotionCategory();
                promotionCategory.setCategoryId(promotion.getCategoryId());
                promotionCategory.setMerchantId(this.merchantId);
                promotionCategory.setPromotionId(this.promotionId);
                return promotionCategory;
            }).collect(Collectors.toList());
            promotionCategoryService.saveBatch(dataList);
        }
    }

    public void updateCatrgory(IPromotionCategoryService promotionCategoryService) {
        deleteCategory(promotionCategoryService);

        saveCategory(promotionCategoryService);
    }

    public void deleteCategory(IPromotionCategoryService promotionCategoryService) {
        //先删除中间关系
        QueryWrapper<PromotionCategory> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("promotion_id", this.getPromotionId())
                .eq("merchant_id", this.getMerchantId());
        promotionCategoryService.remove(queryWrapper);
    }

    public void listCategory(ICategoryService categoryService) {
        List<Category> categoryList = categoryService.listByPromotion(this.promotionId, this.merchantId);
        setCategoryList(categoryList);
    }

    public void init() {
        setPromotionId(UUIDUtil.getUUID());
        if (getStartTime() > SystemClock.now()) {
            setStatus(PROMOTION_STATUS_NOT_STARTED);
        } else if (getEndTime() < SystemClock.now()) {
            setStatus(PROMOTION_STATUS_EXPIRED);
        } else {
            setStatus(PROMOTION_STATUS_EFFECTIVE);
        }
        setStatus(Promotion.PROMOTION_STATUS_NOT_STARTED);
    }
}
