/*
 * Copyright [2022] [https://www.xiaonuo.vip]
 *
 * Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：
 *
 * 1.请不要删除和修改根目录下的LICENSE文件。
 * 2.请不要删除和修改Snowy源码头部的版权声明。
 * 3.本项目代码可免费商业使用，商业使用请保留源码和相关描述文件的项目出处，作者声明等。
 * 4.分发源码时候，请注明软件出处 https://www.xiaonuo.vip
 * 5.不可二次分发开源参与同类竞品，如有想法可联系团队xiaonuobase@qq.com商议合作。
 * 6.若您的项目无法满足以上几点，需要更多功能代码，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
package vip.xiaonuo.biz.modular.goodsConf.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tencentcloudapi.ses.v20201002.models.Simple;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.xiaonuo.biz.modular.goods.entity.BizGoods;
import vip.xiaonuo.biz.modular.goods.service.BizGoodsService;
import vip.xiaonuo.biz.modular.goodsConf.enums.BizGoodsConfEnum;
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.page.CommonPageRequest;
import vip.xiaonuo.biz.modular.goodsConf.entity.BizGoodsConf;
import vip.xiaonuo.biz.modular.goodsConf.mapper.BizGoodsConfMapper;
import vip.xiaonuo.biz.modular.goodsConf.param.BizGoodsConfAddParam;
import vip.xiaonuo.biz.modular.goodsConf.param.BizGoodsConfEditParam;
import vip.xiaonuo.biz.modular.goodsConf.param.BizGoodsConfIdParam;
import vip.xiaonuo.biz.modular.goodsConf.param.BizGoodsConfPageParam;
import vip.xiaonuo.biz.modular.goodsConf.service.BizGoodsConfService;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 提货时间配置表Service接口实现类
 *
 * @author sandy
 * @date  2025/03/27 10:54
 **/
@Service
public class BizGoodsConfServiceImpl extends ServiceImpl<BizGoodsConfMapper, BizGoodsConf> implements BizGoodsConfService {

    @Resource
    private BizGoodsService bizGoodsService;

    @Override
    public Page<BizGoodsConf> page(BizGoodsConfPageParam goodsConfPageParam) {
        QueryWrapper<BizGoodsConf> queryWrapper = new QueryWrapper<BizGoodsConf>().checkSqlInjection();
        if(ObjectUtil.isNotEmpty(goodsConfPageParam.getGoodsName())) {
            queryWrapper.lambda().like(BizGoodsConf::getGoodsName, goodsConfPageParam.getGoodsName());
        }
        if(ObjectUtil.isNotEmpty(goodsConfPageParam.getStartConfStartTime()) && ObjectUtil.isNotEmpty(goodsConfPageParam.getEndConfStartTime())) {
            queryWrapper.lambda().between(BizGoodsConf::getConfStartTime, goodsConfPageParam.getStartConfStartTime(), goodsConfPageParam.getEndConfStartTime());
        }
        if(ObjectUtil.isNotEmpty(goodsConfPageParam.getStartConfEndTime()) && ObjectUtil.isNotEmpty(goodsConfPageParam.getEndConfEndTime())) {
            queryWrapper.lambda().between(BizGoodsConf::getConfEndTime, goodsConfPageParam.getStartConfEndTime(), goodsConfPageParam.getEndConfEndTime());
        }
        queryWrapper.lambda().eq(BizGoodsConf::getDeleteFlag, BizGoodsConfEnum.NOT_DELETE.getValue());
        if(ObjectUtil.isAllNotEmpty(goodsConfPageParam.getSortField(), goodsConfPageParam.getSortOrder())) {
            CommonSortOrderEnum.validate(goodsConfPageParam.getSortOrder());
            queryWrapper.orderBy(true, goodsConfPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
                    StrUtil.toUnderlineCase(goodsConfPageParam.getSortField()));
        } else {
            queryWrapper.lambda().orderByDesc(BizGoodsConf::getConfStartTime).orderByDesc(BizGoodsConf::getConfEndTime).orderByDesc(BizGoodsConf::getId);
        }
        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
    }

    @Override
    public List<BizGoodsConf> list(BizGoodsConfPageParam goodsConfPageParam) {
        QueryWrapper<BizGoodsConf> queryWrapper = new QueryWrapper<BizGoodsConf>().checkSqlInjection();
        if(ObjectUtil.isNotEmpty(goodsConfPageParam.getGoodsCode())) {
            queryWrapper.lambda().eq(BizGoodsConf::getGoodsCode, goodsConfPageParam.getGoodsCode());
        }
        if(ObjectUtil.isNotEmpty(goodsConfPageParam.getGoodsName())) {
            queryWrapper.lambda().eq(BizGoodsConf::getGoodsName, goodsConfPageParam.getGoodsName());
        }
        queryWrapper.lambda().ge(BizGoodsConf::getConfStartTime, DateUtil.date());
        queryWrapper.lambda().gt(BizGoodsConf::getConfEndTime, DateUtil.date());

        if(ObjectUtil.isNotEmpty(goodsConfPageParam.getNeedWeight())) {
            queryWrapper.lambda().ge(BizGoodsConf::getLastWeight, goodsConfPageParam.getNeedWeight());
        }else{
            queryWrapper.lambda().gt(BizGoodsConf::getLastWeight, 0);
        }
        queryWrapper.lambda().eq(BizGoodsConf::getDeleteFlag, BizGoodsConfEnum.NOT_DELETE.getValue());
        queryWrapper.lambda().orderByAsc(BizGoodsConf::getConfStartTime).orderByAsc(BizGoodsConf::getConfEndTime).orderByAsc(BizGoodsConf::getId);
        return this.list(queryWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(BizGoodsConfAddParam goodsConfAddParam) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String goodsJson = goodsConfAddParam.getGoodsJson();
        List<BizGoodsConf> goodsConfAddList = new ArrayList<>();
        if (ObjectUtil.isNotEmpty(goodsJson)) {
            JSONUtil.parseArray(goodsJson).forEach(object -> {
                JSONObject jsonObject = JSONUtil.parseObj(object);
                String goodsId = jsonObject.getStr("goodsId");
                Double confWeight = jsonObject.getDouble("confWeight");
                if (ObjectUtil.isNotEmpty(goodsId)) {
                    // 查询货品
                    BizGoods bizGoods = this.bizGoodsService.queryEntity(goodsId);
                    if (ObjectUtil.isNotEmpty(bizGoods)) {
                        BizGoodsConf goodsConf = new BizGoodsConf();
                        try {
                            /** 提货开始时间 */
                            goodsConf.setConfStartTime(sdf.parse(goodsConfAddParam.getConfStartTime()));
                            /** 提货结束时间 */
                            goodsConf.setConfEndTime(sdf.parse(goodsConfAddParam.getConfEndTime()));
                        } catch (ParseException e) {
                            throw new RuntimeException(e);
                        }
                        /** 货物id */
                        goodsConf.setGoodsId(goodsId);
                        if(!checkGoodsConf(goodsConf)){
                            // 当前时间段内的提货配置重叠了
                            throw new CommonException("货品在当前的提货时间段内已存在其他配置信息("+ bizGoods.getGoodsName() +")，请重新选择。");
                        }else {
                            /** 货品编码 */
                            goodsConf.setGoodsCode(bizGoods.getGoodsCode());
                            /** 货品名称 */
                            goodsConf.setGoodsName(bizGoods.getGoodsName());
                            /** 货品规格 */
                            goodsConf.setGoodsModel(bizGoods.getGoodsModel());
                            /** 可提重量（KG） */
                            goodsConf.setConfWeight(confWeight);
                            /** 已提重量（KG） */
                            goodsConf.setUsedWeight(0.0);
                            /** 剩余提货重量（KG） */
                            goodsConf.setLastWeight(goodsConf.getConfWeight());

                            goodsConfAddList.add(goodsConf);
                        }
                    }
                }
            });

            for (int i = 0; i < goodsConfAddList.size(); i++) {
                this.save(goodsConfAddList.get(i));
            }
        }

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(BizGoodsConfEditParam goodsConfEditParam) {
        BizGoodsConf goodsConf = this.queryEntity(goodsConfEditParam.getId());
        BeanUtil.copyProperties(goodsConfEditParam, goodsConf);
        if(!checkGoodsConf(goodsConf)){
            // 当前时间段内的提货配置重叠了
            throw new CommonException("提货配置信息时间段重叠，请重新选择。");
        }

        /** 可提重量（KG） */
        Double confWeight = goodsConf.getConfWeight();
        /** 已提重量（KG） */
        Double usedWeight = goodsConf.getUsedWeight();
        /** 剩余提货重量（KG） */
        goodsConf.setLastWeight(confWeight-usedWeight);
        this.updateById(goodsConf);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<BizGoodsConfIdParam> goodsConfIdParamList) {
        // 执行删除
        this.removeByIds(CollStreamUtil.toList(goodsConfIdParamList, BizGoodsConfIdParam::getId));
    }

    @Override
    public BizGoodsConf detail(BizGoodsConfIdParam goodsConfIdParam) {
        return this.queryEntity(goodsConfIdParam.getId());
    }

    @Override
    public BizGoodsConf queryEntity(String id) {
        BizGoodsConf goodsConf = this.getById(id);
        if(ObjectUtil.isEmpty(goodsConf)) {
            throw new CommonException("提货时间配置表不存在，id值为：{}", id);
        }
        return goodsConf;
    }

    // 校验 货品在当前时间段内是否已有配置信息
    public Boolean checkGoodsConf(BizGoodsConf bizGoodsConf){
        QueryWrapper<BizGoodsConf> queryWrapper = new QueryWrapper<BizGoodsConf>().checkSqlInjection();
        queryWrapper.lambda().ne(ObjectUtil.isNotEmpty(bizGoodsConf.getId()), BizGoodsConf::getId, bizGoodsConf.getId());
        queryWrapper.lambda().eq(BizGoodsConf::getGoodsId, bizGoodsConf.getGoodsId());
        queryWrapper.lambda().lt(BizGoodsConf::getConfStartTime, bizGoodsConf.getConfEndTime());
        queryWrapper.lambda().gt(BizGoodsConf::getConfEndTime, bizGoodsConf.getConfStartTime());
        queryWrapper.lambda().eq(BizGoodsConf::getDeleteFlag, BizGoodsConfEnum.NOT_DELETE.getValue());
        long count = this.count(queryWrapper);
        if(count > 0){
            return false;
        }else{
            return true;
        }
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void editUsedWeight(String goodsConfId, Double newUsedWeight) {
        BizGoodsConf goodsConf = this.queryEntity(goodsConfId);
        if(null != goodsConf){
            /** 最大可提货重量（KG） */
            Double confWeight = goodsConf.getConfWeight();
            /** 原已提重量（KG） */
            Double usedWeight = goodsConf.getUsedWeight();
            usedWeight = usedWeight + newUsedWeight;
            // 更新已提货重量
            goodsConf.setUsedWeight(usedWeight);
            /** 剩余提货重量（KG） */
            goodsConf.setLastWeight(confWeight-usedWeight);
            this.updateById(goodsConf);
        }
    }

}
