package com.jwipc.order.logic.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Pair;
import cn.hutool.core.util.StrUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.jwipc.constant.DelFlag;
import com.jwipc.constant.DictCode;
import com.jwipc.constant.FlagConst;
import com.jwipc.exception.DaoException;
import com.jwipc.order.convert.DeliveryOrderDetailConvert;
import com.jwipc.order.dto.DeliveryOrderDetailListDTO;
import com.jwipc.order.entity.DeliveryOrder;
import com.jwipc.order.entity.DeliveryOrderDetail;
import com.jwipc.order.entity.DeliveryOrderFile;
import com.jwipc.order.logic.DeliveryOrderDetailLogic;
import com.jwipc.order.logic.DeliveryOrderPushMesLogic;
import com.jwipc.order.logic.DeliveryOrderPushSapLogic;
import com.jwipc.order.model.po.DeliveryOrderDetailPO;
import com.jwipc.order.model.query.DeliveryOrderDetailQuery;
import com.jwipc.order.service.IDeliveryOrderDetailService;
import com.jwipc.order.service.IDeliveryOrderFileService;
import com.jwipc.order.service.IDeliveryOrderService;
import com.jwipc.page.PageUtil;
import com.jwipc.page.PageView;
import com.jwipc.prop.SysProp;
import com.jwipc.security.LoginUtil;
import com.jwipc.supplier.clent.dto.SupplierDTO;
import com.jwipc.supplier.client.SupplierClient;
import com.jwipc.sys.client.ProductClient;
import com.jwipc.sys.client.UserPurchaseGroupClient;
import com.jwipc.sys.client.dto.ProductInfoDTO;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.baomidou.dynamic.datasource.support.DdConstants.SLAVE;


/**
 * <p> </p>
 *
 * @author BOGON
 * @version 1.0
 * @since JDK 1.8
 */
@Service
@RequiredArgsConstructor
public class DeliveryOrderDetailLogicImpl implements DeliveryOrderDetailLogic {
    private final IDeliveryOrderDetailService deliveryOrderDetailService;
    private final IDeliveryOrderService deliveryOrderService;
    private final DeliveryOrderDetailConvert deliveryOrderDetailConvert;
    private final DeliveryOrderPushMesLogic deliveryOrderPushMesLogic;
    private final DeliveryOrderPushSapLogic deliveryOrderPushSapLogic;
    private final SupplierClient supplierClient;
    private final ProductClient productClient;
    private final UserPurchaseGroupClient userPurchaseGroupClient;
    private final SysProp sysProp;
    private final IDeliveryOrderFileService deliveryOrderFileService;

    @Override
    public PageView getList(DeliveryOrderDetailQuery query) {
        Page<DeliveryOrderDetailPO> orderDetailPOPage = PageUtil.toPage(query);
        List<DeliveryOrderDetailPO> list = getDeliveryOrderDetailPOS(orderDetailPOPage, query);
        List<DeliveryOrderDetailListDTO> dtos = deliveryOrderDetailConvert.pos2Dtos(list);
        for (DeliveryOrderDetailListDTO dto : dtos) {
            final List<DeliveryOrderFile> list1 = deliveryOrderFileService.list(
                    new LambdaUpdateWrapper<DeliveryOrderFile>().eq(DeliveryOrderFile::getMasterId, dto.getOrderId()));
            final String fileIds = list1.stream().map(a -> String.valueOf(a.getFileId()))
                    .collect(Collectors.joining(StrUtil.COMMA));
            dto.setFileIds(fileIds);
        }
        return PageUtil.getPV(dtos, orderDetailPOPage.getTotal());
    }

    @Override
    public List<DeliveryOrderDetailListDTO> getListAll(DeliveryOrderDetailQuery query) {
        //需要单独查询分页总数
        query.setRows(1);
        query.setPage(1);
        Page<DeliveryOrderDetailPO> orderDetailPOPage = PageUtil.toPage(query);
        getDeliveryOrderDetailPOS(orderDetailPOPage, query);
        if (orderDetailPOPage.getTotal() > sysProp.getExportMaxCount()) {
            throw new DaoException(StrUtil.format("导出数据超过{}条", sysProp.getExportMaxCount()));
        }
        final List<DeliveryOrderDetailPO> list = getDeliveryOrderDetailPOS(query);
        List<DeliveryOrderDetailListDTO> dtos = deliveryOrderDetailConvert.pos2Dtos(list);
        return dtos;
    }

    private List<DeliveryOrderDetailPO> getDeliveryOrderDetailPOS(Page<DeliveryOrderDetailPO> orderDetailPOPage,
                                                                  DeliveryOrderDetailQuery query)
    {
        if (LoginUtil.isSupplier()) {
            query.setLoginSupplierCode(LoginUtil.getSupplierCode());
            //判断是否存在特殊角色 special 如果存在并且没有输入查询条件就返回空数据
            //判断当前的供应商是否有角色编码
            final List<String> roleCodes = LoginUtil.getRoleCodes();
            if (roleCodes.contains(DictCode.SUPPLIER_SPECIAL_ROLE)) {
                final Map<String, Object> map = BeanUtil.beanToMap(query, false, false);
                Set<String> keySet = Sets.newHashSet();
//                keySet.add("state");
//                keySet.add("delFlag");
//                keySet.add("closeCaseFlag");
//                keySet.add("orderCode");
//                keySet.add("createName");
//                keySet.add("factoryCode");
                keySet.add("material");
//                keySet.add("purchaseOrderCode");
//                keySet.add("notEq");
//                keySet.add("deliveryDateStart");
//                keySet.add("deliveryDateEnd");
//                keySet.add("createDateStart");
//                keySet.add("createDateEnd");
                boolean isOk = keySet.stream().allMatch(key -> {
                    if (Objects.nonNull(map.get(key))) {
                        if (Strings.isNullOrEmpty(map.get(key).toString())) {
                            return true;
                        } else {
                            return false;
                        }
                    } else {
                        return true;
                    }
                });
                if (isOk) {
                    return Collections.emptyList();
                }
            }
            query.setSupplierVisible(FlagConst.Y.getCode());
        } else {
            final Set<String> userPurchaseGroupCode = userPurchaseGroupClient.getUserPurchaseGroupCode(
                    LoginUtil.getUserId());
            query.setUserPurchaseGroupCodes(userPurchaseGroupCode);
        }
        //默认排序按送货单的创建时间倒序 邓京术 2025-05-30
        if (StringUtils.isEmpty(query.getSort())) {
            query.setSort("createDate");
            query.setOrder("desc");
        }
        List<DeliveryOrderDetailPO> list;
        if (Objects.nonNull(orderDetailPOPage)) {
            list = deliveryOrderDetailService.findForList(orderDetailPOPage, query);
        } else {
            list = deliveryOrderDetailService.findForList(query);
        }
        //设置缓存，提高查询速度
        Map<String,String> materialNameMap = Maps.newHashMap();
        //设置最新的物料名称，如果物料名称有变化，则取最新的物料名称， 2024-08-07 邓京术
        list.stream().forEach(item ->{
            if (materialNameMap.keySet().contains(item.getMaterialCode() + item.getFactoryCode())) {
                item.setMaterialName(materialNameMap.get(item.getMaterialCode() + item.getFactoryCode()));
            } else {
                ProductInfoDTO productInfoDTO = productClient.getByMaterialCodeAndFactoryCode(item.getMaterialCode(), item.getFactoryCode());
                if (Objects.nonNull(productInfoDTO)) {
                    item.setMaterialName(productInfoDTO.getMaterialName());
                    materialNameMap.put(item.getMaterialCode() + item.getFactoryCode(), productInfoDTO.getMaterialName());
                }
            }

        });
        return list;
    }

    private List<DeliveryOrderDetailPO> getDeliveryOrderDetailPOS(DeliveryOrderDetailQuery query)
    {
        return getDeliveryOrderDetailPOS(null, query);
    }

    @Override
    public PageView getListForDeliverOrder(Long id) {
        DeliveryOrderDetailQuery query = new DeliveryOrderDetailQuery();
        query.setOrderId(id);
        final DeliveryOrder order = deliveryOrderService.getById(id);
        final Pair<Boolean, List<SupplierDTO>> agentList;
        if (LoginUtil.isSupplier()) {
            query.setLoginSupplierCode(LoginUtil.getSupplierCode());
        }
        if (LoginUtil.isSupplier()){
            if (!LoginUtil.getRoleCodes().contains("logistics_provider")){
                query.setSupplierCode(LoginUtil.getSupplierCode());
            }
        }
        List<DeliveryOrderDetailPO> list = deliveryOrderDetailService.findForList(query);
        //设置最新的物料名称，如果物料名称有变化，则取最新的物料名称， 2024-08-07 邓京术
        list.stream().forEach(item -> {
            ProductInfoDTO productInfoDTO = productClient.getByMaterialCodeAndFactoryCode(item.getMaterialCode(), item.getFactoryCode());
            if (Objects.nonNull(productInfoDTO)) {
                item.setMaterialName(productInfoDTO.getMaterialName());
            }
        });

        List<DeliveryOrderDetailListDTO> dtos = deliveryOrderDetailConvert.pos2Dtos(list);
        return PageUtil.getPV(dtos, dtos.size());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @DS(SLAVE)
    public void remove(String ids) {
        final List<String> idList = StrUtil.split(ids, StrUtil.COMMA);
        if (CollUtil.isNotEmpty(idList)) {
            deliveryOrderDetailService.update(
                    new LambdaUpdateWrapper<DeliveryOrderDetail>().set(DeliveryOrderDetail::getDelFlag,
                            DelFlag.DELETE.getStatus()).in(DeliveryOrderDetail::getId, idList));
            final DeliveryOrderDetail orderDetail = deliveryOrderDetailService.getById(idList.get(0));
            long count = deliveryOrderDetailService.count(
                    new LambdaQueryWrapper<DeliveryOrderDetail>().eq(DeliveryOrderDetail::getOrderId,
                            orderDetail.getOrderId()).eq(DeliveryOrderDetail::getDelFlag, DelFlag.NORMAL.getStatus()));
            if (count == 0L) {
                deliveryOrderService.update(new LambdaUpdateWrapper<DeliveryOrder>().set(DeliveryOrder::getDelFlag,
                        DelFlag.DELETE.getStatus()).eq(DeliveryOrder::getId, orderDetail.getOrderId()));
            }
            //需要推送mes
            final List<DeliveryOrderDetail> details = deliveryOrderDetailService.listByIds(idList);
            final Long orderId = details.get(0).getOrderId();
            final DeliveryOrder order = deliveryOrderService.getById(orderId);
            deliveryOrderPushMesLogic.processor(details, Lists.newArrayList(order), "X");//X标识删除

            deliveryOrderPushSapLogic.pushDeleteDeliveryToSap(idList);
        }
    }

    @Override
    public void updateClose(String ids) {
        //结案
        List<DeliveryOrderDetail> deliveryOrderDetail = deliveryOrderDetailService.listByIds(StrUtil.split(ids, ','));
        if (CollUtil.isEmpty(deliveryOrderDetail)) {
            throw new DaoException("数据不存在!");
        }
        DeliveryOrder devDeliveryOrder = deliveryOrderService.getById(deliveryOrderDetail.get(0).getOrderId());
        //订单状态是新建的无法操作
        if (devDeliveryOrder.getState() == 1) {
            throw new DaoException("新建状态无法手动关闭!");
        }
        final Date now = new Date();
        for (DeliveryOrderDetail orderDetail : deliveryOrderDetail) {
            orderDetail.setCloseCaseFlag(1);
            orderDetail.setUpdateId(LoginUtil.getUserId());
            orderDetail.setUpdateTime(LocalDateTime.now());
        }
        final LambdaUpdateWrapper<DeliveryOrderDetail> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(DeliveryOrderDetail::getCloseCaseFlag, FlagConst.Y.getCode())
                .set(DeliveryOrderDetail::getUpdateId, LoginUtil.getUserId())
                .set(DeliveryOrderDetail::getUpdateTime, LocalDateTime.now()).in(DeliveryOrderDetail::getId,
                        deliveryOrderDetail.stream().map(DeliveryOrderDetail::getId).collect(Collectors.toSet()));
        deliveryOrderDetailService.update(updateWrapper);

        final long count = deliveryOrderDetailService.count(
                new LambdaQueryWrapper<DeliveryOrderDetail>().eq(DeliveryOrderDetail::getOrderId,
                        devDeliveryOrder.getId()).eq(DeliveryOrderDetail::getCloseCaseFlag, FlagConst.N.getCode()));
        if (count == 0) {
            devDeliveryOrder.setState(3);
        } else {
            devDeliveryOrder.setState(2);
        }
        deliveryOrderService.updateById(devDeliveryOrder);
    }
}