package com.liquidnet.service.goblin.controller.manage;

import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.liquidnet.commons.lang.util.CurrentUtil;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.service.base.ErrorMapping;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.goblin.dto.vo.GoblinSelfGoodsCategoryVo;
import com.liquidnet.service.goblin.dto.vo.GoblinStoreGoodsCategoryVo;
import com.liquidnet.service.goblin.service.manage.IGoblinStoreMgtCategoryService;
import com.liquidnet.service.goblin.util.GoblinRedisUtils;
import com.liquidnet.service.goblin.util.ObjectUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@ApiSupport(order = 149006)
@Api(tags = "店铺商品分类")
@Slf4j
@Validated
@RestController
@RequestMapping("store/mgt/category")
public class GoblinStoreMgtCategoryController {
    @Autowired
    IGoblinStoreMgtCategoryService goblinStoreMgtCategoryService;
    @Autowired
    GoblinRedisUtils goblinRedisUtils;

    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "列表")
    @ApiImplicitParams({
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "storeId", value = "店铺ID[64]"),
    })
    @GetMapping("list")
    public ResponseDto<List<GoblinStoreGoodsCategoryVo>> list(@NotBlank(message = "店铺ID不能为空") @RequestParam String storeId) {
        return ResponseDto.success(goblinStoreMgtCategoryService.list(storeId));
    }

    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "添加")
    @ApiImplicitParams({
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "storeId", value = "店铺ID[64]"),
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "catefid", value = "平台分类ID[30]"),
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "catesid", value = "平台分类ID[30]"),
//            @ApiImplicitParam(type = "form", required = false, dataType = "String", name = "catetid", value = "平台分类ID[30]"),
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "catename", value = "店铺分类名称[50]"),
            @ApiImplicitParam(type = "form", required = false, dataType = "Integer", name = "sort", value = "排序[数值越小,排序越前]"),
    })
    @GetMapping("add")
    public ResponseDto<Object> add(@NotBlank(message = "店铺ID不能为空") @RequestParam String storeId,
                                   @NotBlank(message = "平台分类ID不能为空") @RequestParam String catefid,
                                   @NotBlank(message = "平台分类不能为空") @RequestParam String catesid,
//                                   @NotBlank(message = "平台分类不能为空") @RequestParam String catetid,
                                   @NotBlank(message = "店铺分类名称不能为空") @RequestParam String catename,
                                   @Min(value = 1, message = "排序不能小于0") @RequestParam(required = false) Integer sort) {
        String currentUid = CurrentUtil.getCurrentUid();
        if (!goblinRedisUtils.hasStoreId(currentUid, storeId)) {
            return ResponseDto.failure(ErrorMapping.get("149002"));
        }
        List<GoblinSelfGoodsCategoryVo> selfGoodsCategoryVos = goblinRedisUtils.getSelfGoodsCategoryVos();
        if (CollectionUtils.isEmpty(selfGoodsCategoryVos)) {
            log.warn("店铺商品分类管理:添加:平台分类未创建[UID={},storeId={},catefid={},catesid={},catename={}]", currentUid, storeId, catefid, catesid, catename);
            return ResponseDto.failure(ErrorMapping.get("149001"));
        }
        List<String> catePidList = Arrays.asList(catefid, catesid);
        Map<String, GoblinSelfGoodsCategoryVo> filterMap = selfGoodsCategoryVos.stream()
                .filter(r -> catePidList.contains(r.getCateId())).collect(Collectors.toMap(GoblinSelfGoodsCategoryVo::getCateId, Function.identity()));
        if (CollectionUtils.isEmpty(filterMap) || filterMap.size() < 2) {
            log.warn("店铺商品分类管理:添加:平台分类ID有误[UID={},storeId={},catefid={},catesid={},catename={}]", currentUid, storeId, catefid, catesid, catename);
            return ResponseDto.failure(ErrorMapping.get("149001"));
        }
        ArrayList<GoblinStoreGoodsCategoryVo> addStoreGoodsCategoryVoList = ObjectUtil.getGoblinStoreGoodsCategoryVoArrayList();
        LocalDateTime now = LocalDateTime.now();
        List<GoblinStoreGoodsCategoryVo> storeGoodsCategoryVosCache = goblinRedisUtils.getStoreGoodsCategoryVos(storeId);
        if (CollectionUtils.isEmpty(storeGoodsCategoryVosCache)) {// 不存在店铺商品分类，则直接初始化
            filterMap.forEach((k, v) -> {
                GoblinStoreGoodsCategoryVo storeGoodsCategoryVo = GoblinStoreGoodsCategoryVo.getNew().copy(v);
                storeGoodsCategoryVo.setDelFlg("0");
                storeGoodsCategoryVo.setStoreId(storeId);
                storeGoodsCategoryVo.setCreatedBy(currentUid);
                storeGoodsCategoryVo.setCreatedAt(now);
                addStoreGoodsCategoryVoList.add(storeGoodsCategoryVo);
            });
        } else {// 存在则判断，是否为已存在的父级分类
            if (storeGoodsCategoryVosCache.stream().anyMatch(r -> r.getName().equals(catename))) {
                log.warn("店铺商品分类管理:添加:分类名称重复[UID={},storeId={},catefid={},catesid={},catename={}]", currentUid, storeId, catefid, catesid, catename);
                return ResponseDto.failure(ErrorMapping.get("149008"));
            }

            Map<String, GoblinStoreGoodsCategoryVo> existFilterMap = storeGoodsCategoryVosCache.stream().filter(r -> catePidList.contains(r.getCateId()))
                    .collect(Collectors.toMap(GoblinStoreGoodsCategoryVo::getCateId, Function.identity()));
            GoblinStoreGoodsCategoryVo fStoreGoodsCategoryVo = existFilterMap.get(catefid);
            GoblinStoreGoodsCategoryVo sStoreGoodsCategoryVo = existFilterMap.get(catesid);
            if (null == fStoreGoodsCategoryVo) {
                GoblinStoreGoodsCategoryVo storeGoodsCategoryVo = GoblinStoreGoodsCategoryVo.getNew().copy(filterMap.get(catefid));
                storeGoodsCategoryVo.setDelFlg("0");
                storeGoodsCategoryVo.setStoreId(storeId);
                storeGoodsCategoryVo.setCreatedBy(currentUid);
                storeGoodsCategoryVo.setCreatedAt(now);
                addStoreGoodsCategoryVoList.add(storeGoodsCategoryVo);
            }
            if (null == sStoreGoodsCategoryVo) {
                GoblinStoreGoodsCategoryVo storeGoodsCategoryVo = GoblinStoreGoodsCategoryVo.getNew().copy(filterMap.get(catesid));
                storeGoodsCategoryVo.setDelFlg("0");
                storeGoodsCategoryVo.setStoreId(storeId);
                storeGoodsCategoryVo.setCreatedBy(currentUid);
                storeGoodsCategoryVo.setCreatedAt(now);
                addStoreGoodsCategoryVoList.add(storeGoodsCategoryVo);
            }
        }
        GoblinStoreGoodsCategoryVo storeGoodsCategoryVo = GoblinStoreGoodsCategoryVo.getNew();
        storeGoodsCategoryVo.setStoreId(storeId);
        storeGoodsCategoryVo.setCateId(IDGenerator.nextMilliId2());
        storeGoodsCategoryVo.setName(catename);
        storeGoodsCategoryVo.setSort(null == sort ? 1 : sort);
        storeGoodsCategoryVo.setGrade("3");
        storeGoodsCategoryVo.setCatePid(catesid);
        storeGoodsCategoryVo.setNeIsbn("0");
        storeGoodsCategoryVo.setDelFlg("0");
        storeGoodsCategoryVo.setCreatedBy(currentUid);
        storeGoodsCategoryVo.setCreatedAt(now);
        addStoreGoodsCategoryVoList.add(storeGoodsCategoryVo);

        goblinStoreMgtCategoryService.add(storeId, addStoreGoodsCategoryVoList, storeGoodsCategoryVosCache);

        return ResponseDto.success(storeGoodsCategoryVo.getCateId());
    }

    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "编辑")
    @ApiImplicitParams({
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "storeId", value = "店铺ID[64]"),
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "cateid", value = "店铺分类ID[30]"),
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "catename", value = "店铺分类名称[50]"),
            @ApiImplicitParam(type = "form", required = false, dataType = "Integer", name = "sort", value = "排序[数值越小,排序越前]"),
    })
    @GetMapping("edit")
    public ResponseDto<Object> edit(@NotBlank(message = "店铺ID不能为空") @RequestParam String storeId,
                                    @NotBlank(message = "店铺分类ID不能为空") @RequestParam String cateid,
                                    @NotBlank(message = "店铺分类名称不能为空") @RequestParam String catename,
                                    @Min(value = 1, message = "排序不能小于0") @RequestParam(required = false) Integer sort) {
        String currentUid = CurrentUtil.getCurrentUid();
        if (!goblinRedisUtils.hasStoreId(currentUid, storeId)) {
            return ResponseDto.failure(ErrorMapping.get("149002"));
        }
        List<GoblinStoreGoodsCategoryVo> storeGoodsCategoryVosCache = goblinRedisUtils.getStoreGoodsCategoryVos(storeId);
        if (CollectionUtils.isEmpty(storeGoodsCategoryVosCache)) {
            log.warn("店铺商品分类管理:编辑:请先添加商品分类[UID={},storeId={},cateid={},catename={}]", currentUid, storeId, cateid, catename);
            return ResponseDto.failure(ErrorMapping.get("149001"));
        }
        Optional<GoblinStoreGoodsCategoryVo> filterOpt = storeGoodsCategoryVosCache.stream().filter(r -> r.getCateId().equals(cateid)).findAny();
        if (!filterOpt.isPresent()) {
            log.warn("店铺商品分类管理:编辑:不存在的分类ID[UID={},storeId={},cateid={},catename={}]", currentUid, storeId, cateid, catename);
            return ResponseDto.failure(ErrorMapping.get("149001"));
        }
        GoblinStoreGoodsCategoryVo updateStoreGoodsCategoryVo = filterOpt.get();
        updateStoreGoodsCategoryVo.setName(catename);
        updateStoreGoodsCategoryVo.setSort(null == sort ? 1 : sort);
        updateStoreGoodsCategoryVo.setUpdatedBy(currentUid);
        updateStoreGoodsCategoryVo.setUpdatedAt(LocalDateTime.now());

        boolean result = goblinStoreMgtCategoryService.edit(updateStoreGoodsCategoryVo, storeGoodsCategoryVosCache);
        return result ? ResponseDto.success(result) : ResponseDto.failure();
    }

    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "删除")
    @ApiImplicitParams({
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "storeId", value = "店铺ID[64]"),
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "cateid", value = "店铺分类ID[30]"),
    })
    @GetMapping("del")
    public ResponseDto<Object> del(@NotBlank(message = "店铺ID不能为空") @RequestParam String storeId,
                                   @NotBlank(message = "店铺分类ID不能为空") @RequestParam String cateid) {
        String currentUid = CurrentUtil.getCurrentUid();
        if (!goblinRedisUtils.hasStoreId(currentUid, storeId)) {
            return ResponseDto.failure(ErrorMapping.get("149002"));
        }
        boolean resultFlg = goblinStoreMgtCategoryService.del(currentUid, storeId, cateid);
        return resultFlg ? ResponseDto.success() : ResponseDto.failure();
    }
}
