package com.gree.mall.manager.logic.trade;


import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gree.mall.manager.bean.admin.AdminUserCom;
import com.gree.mall.manager.bean.goods.GoodsCategoryBean;
import com.gree.mall.manager.bean.trade.GoodsCategoryItemVO;
import com.gree.mall.manager.bean.trade.GoodsCategoryOtherItemVO;
import com.gree.mall.manager.commonmapper.JxMapper;
import com.gree.mall.manager.enums.CategoryOptionTypeEnum;
import com.gree.mall.manager.enums.material.StateEnum;
import com.gree.mall.manager.exception.RemoteServiceException;
import com.gree.mall.manager.logic.common.CommonLogic;
import com.gree.mall.manager.plus.entity.GoodsCategory;
import com.gree.mall.manager.plus.entity.GoodsCategoryItem;
import com.gree.mall.manager.plus.service.GoodsCategoryItemService;
import com.gree.mall.manager.plus.service.GoodsCategoryService;
import com.gree.mall.manager.zfire.bean.ZfireParamBean;
import com.gree.mall.manager.zfire.util.FieldUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class TradeLogic {

    @Autowired
    CommonLogic commonLogic;

    @Autowired
    GoodsCategoryService goodsCategoryService;

    @Autowired
    JxMapper jxMapper;

    @Autowired
    GoodsCategoryItemService goodsCategoryItemService;


    public List<GoodsCategoryBean> list( HttpServletRequest request) {

        //获取当前登录企业微信id
        AdminUserCom adminUser = commonLogic.getAdminUser(request);
        List<String> companyWechatIds = adminUser.getCompanyWechatIds();

        List<GoodsCategory> list = goodsCategoryService.lambdaQuery()
                .eq(GoodsCategory::getStatus, true)
                .eq(GoodsCategory::getLevel, 1)
                .eq(GoodsCategory::getType, 2)
                .in(!CollectionUtils.isEmpty(companyWechatIds),GoodsCategory::getCompanyWechatId, companyWechatIds)
                .list();

        List<GoodsCategoryBean> goodsCategoryBeans = new ArrayList<>();


        for (GoodsCategory goodsCategory : list) {
            GoodsCategoryBean goodsCategoryBean = BeanUtil.toBean(goodsCategory, GoodsCategoryBean.class);

            List<GoodsCategory> children = goodsCategoryService.lambdaQuery()
                    .eq(GoodsCategory::getParentId, goodsCategory.getCategoryId())
                    .list();
            List<GoodsCategoryBean> childrenBean = new ArrayList<>();
            for (GoodsCategory child : children) {

                GoodsCategoryBean childOne = BeanUtil.toBean(child, GoodsCategoryBean.class);
                List<GoodsCategory> childrenTwo = goodsCategoryService.lambdaQuery()
                        .eq(GoodsCategory::getParentId, child.getCategoryId())
                        .list();
                List<GoodsCategoryBean> goodsCategoryBeans1 = BeanUtil.copyToList(childrenTwo, GoodsCategoryBean.class);

                childOne.setChildren(goodsCategoryBeans1);

                childrenBean.add(childOne);
            }
            goodsCategoryBean.setChildren(childrenBean);

            goodsCategoryBeans.add(goodsCategoryBean);

        }

        return goodsCategoryBeans;

    }

    public void add(GoodsCategory goodsCategory, HttpServletRequest request) {
        AdminUserCom adminUser = commonLogic.getAdminUser();

        if (goodsCategoryService.lambdaQuery().eq(GoodsCategory::getType,3)
                .eq(GoodsCategory::getTypeAttribute ,"SPEC")
                .eq(GoodsCategory::getParentId ,goodsCategory.getParentId())
                .count() > 0 && goodsCategory.getTypeAttribute().equals("SPEC")
            ){
            throw new RemoteServiceException("只允许存在一个型号分类");
        }

        if (goodsCategoryService.lambdaQuery().eq(GoodsCategory::getParentId,goodsCategory.getParentId()).eq(GoodsCategory::getType,3)
                .eq(GoodsCategory::getName,goodsCategory.getName()).count() > 0) {
            throw new RemoteServiceException("存在相同名称");
        }

        goodsCategory.setCompanyWechatId(adminUser.getCompanyWechatId());
        goodsCategory.setCompanyName(adminUser.getCompanyName());


        goodsCategory.setLevel(3);
        goodsCategory.setType(3);
        goodsCategory.insert();
    }

    public IPage<GoodsCategoryItemVO> pageV2(ZfireParamBean zfireParamBean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        List<String> companyWechatIds = adminUser.getCompanyWechatIds();

        //1.组装查询条件
        ZfireParamBean zfireParam = FieldUtils.supplyParam(zfireParamBean, GoodsCategoryItemVO.class);

        IPage<GoodsCategoryItemVO> goodsCategoryItemVOIPage = jxMapper.pageV2(new Page(zfireParamBean.getPageNum(),
                        zfireParamBean.getPageSize()),
                zfireParam
                , companyWechatIds);

        return goodsCategoryItemVOIPage;

    }

    public void addItem(GoodsCategoryItem goodsCategoryItem, HttpServletRequest request) {
        AdminUserCom adminUser = commonLogic.getAdminUser();

        GoodsCategory three = goodsCategoryService.getById(goodsCategoryItem.getServiceCategoryId());
        GoodsCategory two = goodsCategoryService.getById(three.getParentId());
        GoodsCategory one = goodsCategoryService.getById(two.getParentId());

        if (goodsCategoryItemService.lambdaQuery()
                .eq(GoodsCategoryItem::getSmallId,two.getCategoryId())
                .eq(GoodsCategoryItem::getCompanyWechatId,adminUser.getCompanyWechatId())
                .eq(GoodsCategoryItem::getDictName,goodsCategoryItem.getDictName()).count() > 0) {
            throw new RemoteServiceException("存在相同名称");
        }


        goodsCategoryItem.setMainId(one.getCategoryId());
        goodsCategoryItem.setMainName(one.getName());

        goodsCategoryItem.setSmallId(two.getCategoryId());
        goodsCategoryItem.setSmallName(two.getName());

        goodsCategoryItem.setCompanyWechatId(adminUser.getCompanyWechatId());
        goodsCategoryItem.setCompanyName(adminUser.getCompanyName());
        goodsCategoryItem.setMainImg(two.getImgUrl());
        goodsCategoryItem.setTypeOption(three.getTypeOption());

        goodsCategoryItem.insert();

        this.priceMaxMin(goodsCategoryItem.getSmallId());
    }

    private void priceMaxMin(String smallId) {

        AdminUserCom adminUser = commonLogic.getAdminUser();

        List<GoodsCategory> goodsCategories = goodsCategoryService.lambdaQuery()
                .eq(GoodsCategory::getParentId, smallId)
                .eq(GoodsCategory::getCompanyWechatId, adminUser.getCompanyWechatId())
                .eq(GoodsCategory::getType, 3)
                .eq(GoodsCategory::getStatus,true)
                .list();

        List<String> collect = goodsCategories.stream().map(GoodsCategory::getCategoryId).collect(Collectors.toList());

        List<GoodsCategoryItem> serviceCategoryItems = goodsCategoryItemService.lambdaQuery()
                .eq(GoodsCategoryItem::getCompanyWechatId, adminUser.getCompanyWechatId())
                .eq(GoodsCategoryItem::getStatus, StateEnum.ON.getKey())
                .in(GoodsCategoryItem::getServiceCategoryId, collect).list();


        BigDecimal priceMin = new BigDecimal("0");
        BigDecimal priceMax = new BigDecimal("0");

        for (GoodsCategory goodsCategory : goodsCategories) {
            if (goodsCategory.getTypeAttribute().equals("SPEC")) {
                continue;
            }
            if (goodsCategory.getTypeOption().equals(CategoryOptionTypeEnum.SIGIN.getKey())) {
                //单选 整机
                List<BigDecimal> zsMax = serviceCategoryItems.stream()
                        .filter(item -> item.getServiceCategoryId().equals(goodsCategory.getCategoryId()))
                        .map(GoodsCategoryItem::getPrice)
                        .sorted(Comparator.reverseOrder()).collect(Collectors.toList());

                List<BigDecimal> zxmin = serviceCategoryItems.stream()
                        .filter(item -> item.getServiceCategoryId().equals(goodsCategory.getCategoryId()))
                        .map(GoodsCategoryItem::getPrice)
                        .sorted().collect(Collectors.toList());

                //整机取第一个

                priceMin = com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(zxmin) ? priceMin : priceMin.add(zxmin.get(0));
                priceMax = com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(zsMax) ? priceMax : priceMax.add(zsMax.get(0));
            }

            if (goodsCategory.getTypeOption().equals(CategoryOptionTypeEnum.MANY.getKey())) {

                //多选累加 整机
                BigDecimal zxMax = serviceCategoryItems.stream()
                        .filter(item -> item.getPrice().compareTo(new BigDecimal("0")) > 0)
                        .filter(item -> item.getServiceCategoryId().equals(goodsCategory.getCategoryId()))
                        .map(GoodsCategoryItem::getPrice)
                        .reduce(BigDecimal::add).orElse(new BigDecimal("0"));

                BigDecimal zxMin = serviceCategoryItems.stream()
                        .filter(item -> item.getPrice().compareTo(new BigDecimal("0")) < 0)
                        .filter(item -> item.getServiceCategoryId().equals(goodsCategory.getCategoryId()))
                        .map(GoodsCategoryItem::getPrice)
                        .reduce(BigDecimal::add).orElse(new BigDecimal("0"));

                List<BigDecimal> zxmin = serviceCategoryItems.stream()
                        .filter(item -> item.getServiceCategoryId().equals(goodsCategory.getCategoryId()))
                        .map(GoodsCategoryItem::getPrice)
                        .sorted().collect(Collectors.toList());

                //整机取第一个

                priceMin =  priceMin.add(zxMin.doubleValue() == 0 ?zxmin.get(0):zxMin);
                priceMax =  priceMax.add(zxMax);
            }
        }

        List<GoodsCategoryItem> spec = serviceCategoryItems.stream().filter(item -> item.getTypeAttribute().equals("SPEC")).collect(Collectors.toList());


        for (GoodsCategoryItem goodsCategoryItem : spec) {
            goodsCategoryItem.setMaxPrice(goodsCategoryItem.getPrice().add(priceMax));
            goodsCategoryItem.setMinPrice(goodsCategoryItem.getPrice().add(priceMin));
            goodsCategoryItem.updateById();
        }
    }

    public void updateItem(GoodsCategoryItem goodsCategoryItem) {
        AdminUserCom adminUser = commonLogic.getAdminUser();

        if (goodsCategoryItemService.lambdaQuery()
                .eq(GoodsCategoryItem::getSmallId,goodsCategoryItem.getSmallId())
                .eq(GoodsCategoryItem::getCompanyWechatId,adminUser.getCompanyWechatId())
                .eq(GoodsCategoryItem::getDictName,goodsCategoryItem.getDictName())
                .ne(GoodsCategoryItem::getId,goodsCategoryItem.getId())
                .count() > 0) {
            throw new RemoteServiceException("存在相同名称");
        }

        goodsCategoryItem.setCompanyWechatId(adminUser.getCompanyWechatId());
        goodsCategoryItem.setCompanyName(adminUser.getCompanyName());
        goodsCategoryItem.updateById();
        this.priceMaxMin(goodsCategoryItem.getSmallId());
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteItem(String categoryId) {
        GoodsCategoryItem goodsCategoryItem = goodsCategoryItemService.getById(categoryId);
        goodsCategoryItemService.removeById(categoryId);
        this.priceMaxMin(goodsCategoryItem.getSmallId());
    }

    public GoodsCategoryItem detailItem(String categoryId) {
        GoodsCategoryItem goodsCategoryItem = goodsCategoryItemService.getById(categoryId);
        return goodsCategoryItem;
    }

    public IPage<GoodsCategoryOtherItemVO> listOther(ZfireParamBean zfireParamBean) {

        AdminUserCom adminUser = commonLogic.getAdminUser();
        List<String> companyWechatIds = adminUser.getCompanyWechatIds();

        //1.组装查询条件
        ZfireParamBean zfireParam = FieldUtils.supplyParam(zfireParamBean, GoodsCategoryOtherItemVO.class);

        IPage<GoodsCategoryOtherItemVO> goodsCategoryItemVOIPage = jxMapper.listOther(new Page(zfireParamBean.getPageNum(),
                        zfireParamBean.getPageSize()),
                zfireParam
                , companyWechatIds);

        return goodsCategoryItemVOIPage;
    }




    /**
    * 计算价格
     * ids 所有型号属性
    * */
    public BigDecimal price(List<String> ids) {

        List<GoodsCategoryItem> list = goodsCategoryItemService.lambdaQuery().in(GoodsCategoryItem::getId, ids).list();

        BigDecimal bigDecimal = list.stream().map(GoodsCategoryItem::getPrice).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
        return bigDecimal;
    }
}
