package com.jwipc.order.logic.impl;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.jwipc.constant.DictCode;
import com.jwipc.exception.DaoException;
import com.jwipc.order.convert.DeliveryOrderControlConvert;
import com.jwipc.order.dto.DeliveryOrderControlBaseDTO;
import com.jwipc.order.dto.DeliveryOrderControlSaveDTO;
import com.jwipc.order.entity.DeliveryOrderControl;
import com.jwipc.order.logic.DeliveryOrderControlLogic;
import com.jwipc.order.model.po.DeliveryOrderControlSelectPO;
import com.jwipc.order.model.query.DeliveryOrderControlQuery;
import com.jwipc.order.service.IDeliveryOrderControlService;
import com.jwipc.order.service.IDeliveryOrderDetailService;
import com.jwipc.page.PageUtil;
import com.jwipc.page.PageView;
import com.jwipc.security.LoginUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * <p> </p>
 *
 * @author dengjsh
 * @version 1.0
 * @since JDK 1.8
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class DeliveryOrderControlLogicImpl implements DeliveryOrderControlLogic {

    private final DeliveryOrderControlConvert deliveryOrderControlConvert;
    private final IDeliveryOrderControlService deliveryOrderControlService;
    private final IDeliveryOrderDetailService deliveryOrderDetailService;

    @Override
    public PageView getList(DeliveryOrderControlQuery query) {
        final Page<DeliveryOrderControlSelectPO> page = PageUtil.toPage(query);
        if (LoginUtil.isSupplier()) {
            query.setSupplierId(LoginUtil.getSupplierId());
        }
        //判断当前的供应商是否有特殊角色编码
        final List<String> roleCodes = LoginUtil.getRoleCodes();
        if (roleCodes.contains(DictCode.SUPPLIER_SPECIAL_ROLE)) {
            if (StrUtil.isEmpty(query.getMaterialNameOrCode())) {
                return PageUtil.getPV(new ArrayList<>(), page.getTotal());
            }
        }
        initOrderQuery(query);
        List<DeliveryOrderControlSelectPO> selecctList = deliveryOrderControlService.getListForSelect(page, query);
        List<DeliveryOrderControlBaseDTO> supplierMaterialDemoBaseDTOS = deliveryOrderControlConvert.entities2SelectDtos(
                selecctList);
        return PageUtil.getPV(supplierMaterialDemoBaseDTOS, page.getTotal());
    }

    private void initOrderQuery(DeliveryOrderControlQuery query) {
        //排序
        if (StringUtils.isEmpty(query.getSort())) {
            query.setAsc("DESC");
            query.setOrderByName("create_time");
        } else {
            query.setAsc("DESC");
            if (query.getOrder().equals("asc")) {
                query.setAsc("asc");
            }
            if (query.getSort().equals("supplierCode")) {
                query.setOrderByName("supplier_code");
            } else if (query.getSort().equals("materialCode")) {
                query.setOrderByName("material_code");
            } else if (query.getSort().equals("supplierName")) {
                query.setOrderByName("supplier_name");
            } else if (query.getSort().equals("materialName")) {
                query.setOrderByName("material_name");
            } else if (query.getSort().equals("controlNum")) {
                query.setOrderByName("control_num");
            } else if (query.getSort().equals("createTime")) {
                query.setOrderByName("create_time");
            } else {
                query.setAsc("DESC");
                query.setOrderByName("create_time");
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveOrUpdate(DeliveryOrderControlSaveDTO saveDTO) {
        DeliveryOrderControl deliveryOrderControl = deliveryOrderControlConvert.dto2Entity(saveDTO);
        //如果id不存在，则生成清单号
        if (ObjectUtil.isNull(deliveryOrderControl.getId())) {
            deliveryOrderControl.setCreateId(LoginUtil.getUserId());
            deliveryOrderControl.setCreateTime(LocalDateTime.now());
        } else {
            deliveryOrderControl.setUpdateId(LoginUtil.getUserId());
            deliveryOrderControl.setUpdateTime(LocalDateTime.now());
        }
        deliveryOrderControl.setDeleteFlag(0);

        List<DeliveryOrderControlBaseDTO> deliveryOrderControlBaseDTOS = Lists.newArrayList();
        DeliveryOrderControlBaseDTO DeliveryOrderControlBaseDTO = deliveryOrderControlConvert.entity2Dto(deliveryOrderControl);
        deliveryOrderControlBaseDTOS.add(DeliveryOrderControlBaseDTO);
        //增加校验 2025-02-22 如果新增或修改管控数理，必须校验供应商当前物料已送货数量必须大于或等于管控数量。
        BigDecimal lastSendNum = deliveryOrderDetailService.findSendNumBySuplierCodeAndMaterialCode(deliveryOrderControl.getEffectiveDate(), deliveryOrderControl.getSupplierCode(), deliveryOrderControl.getMaterialCode(), 0);
        BigDecimal comNum = deliveryOrderControl.getControlNum().subtract(lastSendNum);
        //如果管控数量 < 以往已送货数量
        if (comNum.floatValue() < 0) {
            throw new DaoException(StrUtil.format("创建失败:供应商：{},物料编号：{}，送货管控数量：{}, 必须大于或等于已完成送货数量:{}", deliveryOrderControl.getSupplierCode(),deliveryOrderControl.getMaterialCode(),
                    deliveryOrderControl.getControlNum(), lastSendNum));
        }


        //增加相同条件过滤检查 重复性检查，物料编码，供应商编码，生产商中英文
        if (checkSameDeliveryOrderControl(deliveryOrderControl)) {
            throw new DaoException("该供应商物料管控已经存在类似清单");
        }
        deliveryOrderControlService.saveOrUpdate(deliveryOrderControl);
    }

    /**
     *
     * @param deliveryOrderControl
     * @return
     */
    private boolean checkSameDeliveryOrderControl (DeliveryOrderControl deliveryOrderControl) {
        List<DeliveryOrderControl> deliveryOrderControls = deliveryOrderControlService.list(
                new LambdaQueryWrapper<DeliveryOrderControl>().eq(DeliveryOrderControl::getSupplierCode, deliveryOrderControl.getSupplierCode())
                        .eq(DeliveryOrderControl::getMaterialCode, deliveryOrderControl.getMaterialCode())
                        .eq(DeliveryOrderControl::getDeleteFlag, 0));
        //如果根据以上参数没有查出对应的数据
        if (CollectionUtils.isEmpty(deliveryOrderControls) || deliveryOrderControls.size() == 0) {
            return false;
        //如果查出两个以上的数据清单
        } else if (deliveryOrderControls.size() >= 2) {
            return true;
        //如果是新增，证明数据库已经存在该数据清单
        } else if (null == deliveryOrderControl.getId()) {
            return true;
        } else {
            //如果数据库查出该数据，且id相同，证明是修改。
            if (deliveryOrderControl.getId().equals(deliveryOrderControls.get(0).getId())) {
                return false;
            //否则不是同一个管控清单，查出的管控清单，是另外一个不相同的管控清单，不允许修改
            } else {
                return true;
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void remove(List<String> idList) {
        List deliveryOrderControlBaseDTOS = Lists.newArrayList();
        for (String id : idList) {
            DeliveryOrderControl deliveryOrderControl = deliveryOrderControlService.getById(id);
            DeliveryOrderControlBaseDTO deliveryOrderControlBaseDTO = deliveryOrderControlConvert.entity2Dto(deliveryOrderControl);
            deliveryOrderControlBaseDTO.setDeleteFlag(1);
            deliveryOrderControlBaseDTOS.add(deliveryOrderControlBaseDTO);
        }
        deliveryOrderControlService.updateBatchById(deliveryOrderControlBaseDTOS);
    }

    @Override
    public DeliveryOrderControlBaseDTO getDetail(Long id) {
        final DeliveryOrderControl deliveryOrderControl = deliveryOrderControlService.getById(id);
        if (Objects.nonNull(deliveryOrderControl)) {
            return deliveryOrderControlConvert.entity2Dto(deliveryOrderControl);
        }
        DeliveryOrderControlBaseDTO deliveryOrderControlBaseDTO = new DeliveryOrderControlBaseDTO();
        return deliveryOrderControlBaseDTO;
    }

    @Override
    public DeliveryOrderControl getControlNum(String supplierCode, String materialCode) {
        final DeliveryOrderControl deliveryOrderControl = deliveryOrderControlService.getControlNum(supplierCode, materialCode);
//        if (Objects.nonNull(deliveryOrderControl) && deliveryOrderControl.getId() > 0l) {
//            return deliveryOrderControl.getControlNum();
//        }
        return deliveryOrderControl;
    }

}