package com.ximai.mes.md.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ximai.common.constant.UserConstants;
import com.ximai.common.core.domain.SapResult;
import com.ximai.common.core.domain.entity.MdItemType;
import com.ximai.common.core.domain.entity.SysDictData;
import com.ximai.common.exception.ServiceException;
import com.ximai.common.utils.bean.BeanUtils;
import com.ximai.common.utils.bean.BeanValidators;
import com.ximai.common.utils.data.DateUtils;
import com.ximai.common.utils.data.StringUtils;
import com.ximai.mes.md.domain.*;
import com.ximai.mes.md.mapper.ItemTypeMapper;
import com.ximai.mes.md.mapper.MdBaseInfoMapper;
import com.ximai.mes.md.mapper.MdItemMapper;
import com.ximai.mes.md.mapper.MdProductLookMapper;
import com.ximai.mes.md.service.*;
import com.ximai.mes.md.vo.ItemUpdateMesVo;
import com.ximai.mes.md.vo.MdItemVo;
import com.ximai.mes.md.vo.SapItemVo;
import com.ximai.mes.pro.domain.productionSolution.ProProductionSolutionBom;
import com.ximai.mes.pro.mapper.productionSolution.ProProductionSolutionBomMapper;
import com.ximai.mes.face.sap.SapService;
import com.ximai.system.service.ISysDictDataService;
import com.ximai.system.strategy.AutoCodeUtil;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.Validator;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class MdItemServiceImpl implements IMdItemService {

    private static final Logger log = LoggerFactory.getLogger(MdItemServiceImpl.class);

    @Autowired
    private MdItemMapper mdItemMapper;

    @Autowired
    private IMdBaseInfoService iMdBaseInfoService;

    @Autowired
    private IMdProductLookService iMdProductLookService;

    @Autowired
    private IMdProductPublishedConfService iMdProductPublishedConfService;

    @Autowired
    private IMdSaleUnitService iMdSaleUnitService;

    @Autowired
    private ISysDictDataService dictDataService;

    @Autowired
    private MdProductLookMapper productLookMapper;

    @Autowired
    private SapService sapService;
    @Autowired
    protected Validator validator;
    @Autowired
    private AutoCodeUtil autoCodeUtil;
    @Autowired
    private IMdUnitMeasureService mdUnitMeasureService;
    @Autowired
    private IItemTypeService iItemTypeService;

    @Autowired
    private ItemTypeMapper itemTypeMapper;

    @Autowired
    private ProProductionSolutionBomMapper proProductionSolutionBomMapper;

    @Autowired
    private MdBaseInfoMapper mdBaseInfoMapper;


    @Override
    public List<MdItemVo> selectMdItemList(MdItem mdItem) {
        return mdItemMapper.selectMdItemList(mdItem);
    }


    @Override
    public MdItemType getItemTypeByItemId(Long id) {
        //        List<MdItemType> collect = Stream.of(mdItemType).filter(x -> x.getAncestors().split(",").length == 2).collect(Collectors.toList());
//
//        if (collect==null) {
//            return null;
//        }

        return mdItemMapper.selectMdItemTypeById(id);
    }


    @Override
    public MdItem selectMdItemById(Long itemId) {
        return mdItemMapper.selectMdItemById(itemId);
    }


    @Override
    public String checkItemCodeUnique(MdItem mdItem) {
        MdItem item = mdItemMapper.checkItemCodeUnique(mdItem);
        Long itemId = mdItem.getItemId() == null ? -1L : mdItem.getItemId();
        if (StringUtils.isNotNull(item) && item.getItemId().longValue() != itemId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        } else {
            return UserConstants.UNIQUE;
        }
    }

    @Override
    public List<MdItem> selectListByQw(QueryWrapper<MdItem> query) {
        return mdItemMapper.selectListByQw(query);
    }

    @Override
    public String checkItemNameUnique(MdItem mdItem) {
        MdItem item = mdItemMapper.checkItemNameUnique(mdItem);
        Long itemId = mdItem.getItemId() == null ? -1L : mdItem.getItemId();
        if (StringUtils.isNotNull(item) && item.getItemId().longValue() != itemId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        } else {
            return UserConstants.UNIQUE;
        }
    }

    @Override
    public int insertMdItem(MdItem mdItem) {
        return mdItemMapper.insertMdItem(mdItem);
    }

    @Override
    public int updateMdItem(MdItem mdItem) {
        int i = mdItemMapper.updateMdItem(mdItem);
        //保存产品基本信息
        if (ObjectUtil.isNotEmpty(mdItem.getBaseInfo()) && mdItem.getBaseInfo().getItemId() != null) {
            MdBaseInfo baseInfo = mdItem.getBaseInfo();
            if (StringUtils.isEmpty(baseInfo.getCreateBy())) {
                baseInfo.setCreateBy(mdItem.getUpdateBy());
                iMdBaseInfoService.insertMdBaseInfo(mdItem.getBaseInfo());
            } else {
                baseInfo.setUpdateBy(mdItem.getUpdateBy());
                iMdBaseInfoService.updateMdBaseInfo(mdItem.getBaseInfo());
            }
        }

        //保存产品外观信息
        if (ObjectUtil.isNotEmpty(mdItem.getLook()) && mdItem.getLook().getItemId() != null) {
            MdProductLook look = mdItem.getLook();
            //如果创建信息是null，则新增
            if (StringUtils.isEmpty(look.getCreateBy())) {
                look.setCreateBy(mdItem.getUpdateBy());
                iMdProductLookService.insertMdProductLook(look);
            } else {
                look.setUpdateBy(mdItem.getUpdateBy());
                iMdProductLookService.updateMdProductLook(look);
            }
        }

        //保存产品参数配置信息
        if (ObjectUtil.isNotEmpty(mdItem.getPublishedConf()) && mdItem.getPublishedConf().getItemId() != null) {
            MdProductPublishedConf publishedConf = mdItem.getPublishedConf();
            if (StringUtils.isEmpty(publishedConf.getCreateBy())) {
                publishedConf.setCreateBy(mdItem.getUpdateBy());
                iMdProductPublishedConfService.insertMdProductPublishedConf(publishedConf);
            } else {
                publishedConf.setUpdateBy(mdItem.getUpdateBy());
                iMdProductPublishedConfService.updateMdProductPublishedConf(publishedConf);
            }
        }

        //保存销售单位转换信息
        if (ObjectUtil.isNotEmpty(mdItem.getSaleUnit()) && mdItem.getSaleUnit().getItemId() != null) {
            MdSaleUnit saleUnit = mdItem.getSaleUnit();
            if (StringUtils.isEmpty(saleUnit.getCreateBy())) {
                saleUnit.setCreateBy(mdItem.getUpdateBy());
                iMdSaleUnitService.insertMdSaleUnit(saleUnit);
            } else {
                saleUnit.setUpdateBy(mdItem.getUpdateBy());
                iMdSaleUnitService.updateMdSaleUnit(saleUnit);
            }
        }
        return i;
    }


    /**
     * 根据ep传mes进行修改
     *
     * @param mdItem
     * @return
     */
    @Override
    public int updateMdItems(MdItem mdItem, ItemUpdateMesVo mdItemVo) {
        int i = mdItemMapper.updateMdItem(mdItem);

        MdItem mdItem1 = mdItemMapper.selectMdItemByCodes(mdItem.getSapItemCode());
        //保存产品基本信息
        MdBaseInfo baseInfo = new MdBaseInfo();
        MdBaseInfo mdBaseInfo = mdBaseInfoMapper.selectMdBaseInfoByItemIds(mdItem.getItemId());
        if (ObjectUtil.isEmpty(mdBaseInfo)) {
            BeanUtils.copyProperties(mdItemVo, baseInfo);
            baseInfo.setUpdateBy("ep");
            baseInfo.setItemId(mdItem1.getItemId());
            iMdBaseInfoService.insertMdBaseInfo(baseInfo);
        } else {
            BeanUtils.copyProperties(mdItemVo, baseInfo);
            baseInfo.setUpdateBy("ep");
            baseInfo.setItemId(mdItem1.getItemId());
            iMdBaseInfoService.updateMdBaseInfo(baseInfo);
        }


        //保存产品外观信息
        if (ObjectUtil.isNotEmpty(mdItemVo.getProductLook())) {
            MdProductLook look = new MdProductLook();
            MdProductLook mdProductLook = iMdProductLookService.selectMdProductLookByItemId(mdItem.getItemId());
            //如果创建信息是null，则新增
            if (ObjectUtil.isEmpty(mdProductLook)) {
                BeanUtils.copyProperties(mdItemVo.getProductLook(), look);
                if (StringUtils.isNotNull(look.getFrontColor())) {
                    String[] frontColor = look.getFrontColor();
                    String join = String.join(",", frontColor);
                    look.setFrontColorName(join);
                }
                if (StringUtils.isNotNull(look.getOppositeColor())) {
                    String[] frontColor = look.getOppositeColor();
                    String join = String.join(",", frontColor);
                    look.setOppositeColorName(join);
                }
                look.setUpdateBy("ep");
                look.setItemId(mdItem1.getItemId());
                iMdProductLookService.insertMdProductLook(look);
            } else {
                BeanUtils.copyProperties(mdItemVo.getProductLook(), look);
                if (StringUtils.isNotNull(look.getFrontColor())) {
                    String[] frontColor = look.getFrontColor();
                    String join = String.join(",", frontColor);
                    look.setFrontColorName(join);

                }
                if (StringUtils.isNotNull(look.getOppositeColor())) {
                    String[] frontColor = look.getOppositeColor();
                    String join = String.join(",", frontColor);
                    look.setOppositeColorName(join);
                }
                look.setUpdateBy("ep");
                look.setItemId(mdItem1.getItemId());
                iMdProductLookService.updateMdProductLook(look);
            }
        }


        return i;
    }


    @Override
    public int deleteByItemIds(Long[] itemIds) {
        return mdItemMapper.deleteMdItemByIds(itemIds);
    }

    @Override
    public int deleteByItemId(Long itemId) {
        return mdItemMapper.deleteMdItemById(itemId);
    }

    @Override
    public SapResult becomeFormalProduct(Long[] itemIds) {
        int i = mdItemMapper.becomeFormalProduct(itemIds);
        Long itemId = Arrays.asList(itemIds).get(0);
        Map<String, Object> jsonObjectMap = new LinkedHashMap<>();
        SysDictData sysDictData = new SysDictData();
        //根据数据视图查询
        sysDictData.setDictType("sap_property_view");
        //产品特性
        sysDictData.setDictValue("2");
        List<SysDictData> list = dictDataService.selectDictDataList(sysDictData);
        List<String> sapDataTypeList = list.stream().map(SysDictData::getCssClass).collect(Collectors.toList());

        //明细数据
        List<Map<String, Object>> mapList = new ArrayList<>();
        mapList.add(jsonObjectMap);

        ObjectMapper objectMapper = new ObjectMapper();
        String s1;
        try {
            s1 = objectMapper.writeValueAsString(mapList);
            System.out.println(s1);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        String result = sapService.syncMdItemData(s1);
        final JSONArray resultObj = JSONUtil.parseArray(result);
        JSONObject resultJSONObject = resultObj.get(0, JSONObject.class);
        String message = resultJSONObject.get("MESSAGE", String.class);
        String type = resultJSONObject.get("TYPE", String.class);
        String sapItemCode = resultJSONObject.get("MESSAGE_V1", String.class);
        this.handleResult(itemId, sapItemCode, message);
        System.out.println(result);
        return new SapResult(type, message);
    }

    public void handleResult(Long itemId, String sapItemCode, String message) {
        MdItem mdItem = mdItemMapper.selectMdItemById(itemId);
        mdItem.setSapItemCode(sapItemCode);
        mdItem.setMessage(message);
        mdItemMapper.updateMdItem(mdItem);
    }

    @Override
    public String importMdItem(List<MdItem> itemList, boolean updateSupport, String operaName) {
        if (StringUtils.isNull(itemList) || itemList.size() == 0) {
            throw new ServiceException("导入物料/产品数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (MdItem mdItem : itemList) {
            try {
                // 验证是否存在这个用户
                MdItem item = mdItemMapper.selectMdItemByItemName(mdItem.getItemName());
                if (StringUtils.isNull(item)) {
                    BeanValidators.validateWithException(validator, mdItem);
                    String itemCode = autoCodeUtil.genSerialCode(UserConstants.ITEM_CODE, "");
                    mdItem.setItemCode(itemCode);
                    //处理计量单位
                    if (StringUtils.isNotEmpty(mdItem.getUnitOfMeasure())) {
                        MdUnitMeasure mdUnitMeasure = mdUnitMeasureService.selectMdUnitMeasureByMeasureName(mdItem.getUnitOfMeasure());
                        mdItem.setUnitOfMeasure(mdUnitMeasure.getMeasureCode());
                    }
                    //处理物料/产品类型
                    if (StringUtils.isNotEmpty(mdItem.getItemTypeName())) {
                        MdItemType mdItemType = iItemTypeService.selectItemTypeByItemTypeName(mdItem.getItemTypeName());
                        if (StringUtils.isNotNull(mdItemType)) {
                            mdItem.setItemTypeId(mdItemType.getItemTypeId());
                            mdItem.setItemTypeCode(mdItemType.getItemTypeCode());
                            mdItem.setItemTypeName(mdItemType.getItemTypeName());
                            mdItem.setItemOrProduct(mdItemType.getItemOrProduct());
                        }
                    }
                    mdItem.setEnableFlag("Y");
                    mdItem.setCreateBy(operaName);
                    this.insertMdItem(mdItem);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、物料/产品 " + mdItem.getItemName() + " 导入成功");
                } else if (updateSupport) {
                    BeanValidators.validateWithException(validator, mdItem);
                    mdItem.setUpdateBy(operaName);
                    this.updateMdItem(mdItem);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、物料/产品 " + mdItem.getItemName() + " 更新成功");
                } else {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、物料/产品 " + mdItem.getItemName() + " 已存在");
                }
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、物料/产品 " + mdItem.getItemName() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        } else {
            successMsg.insert(0, "数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    /**
     * 产品物料接收EP
     *
     * @param mdItemVo
     * @return
     */
    @Override
    @Transactional
    public int itemCreate(ItemUpdateMesVo mdItemVo) {
        // TODO 产品物料EP传MES
        MdItem mdItem = new MdItem();
        BeanUtils.copyProperties(mdItemVo, mdItem);
        int i = 0;
        //新增
        if (mdItemVo.getUpdateLog().equals("I")) {
            if(StringUtils.isEmpty(mdItem.getSapItemCode())){
                throw new ServiceException("没有sap_item_code编码");
            }
            MdItem mdItem1 = mdItemMapper.selectMdItemByCodes(mdItem.getSapItemCode());
            if (Objects.isNull(mdItem1)) {
                List<MdItem> mdItems = mdItemMapper.selectMdItemByCode(mdItem.getItemCode());
                if (CollUtil.isNotEmpty(mdItems)) {
                    throw new ServiceException("新增物料" + mdItem.getItemCode() + "失败，物料编码已存在");
                }
                MdItem item = new MdItem();
                item.setItemName(mdItem.getItemName());
                List<MdItemVo> mdItemVos = mdItemMapper.selectMdItemLists(item);
                if (CollUtil.isNotEmpty(mdItemVos)) {
                    throw new ServiceException("新增物料" + mdItem.getItemCode() + "失败，物料名称已存在");
                }

                mdItem.setCreateBy("ep");
                mdItem.setCreateTime(DateUtils.getNowDate());
                MdItemType type = itemTypeMapper.selectItemTypeCode(mdItemVo.getItemTypeCode());
                if (StringUtils.isNotNull(type)) {
                    mdItem.setItemTypeId(type.getItemTypeId());
                    mdItem.setItemTypeCode(type.getItemTypeCode());
                    mdItem.setItemTypeName(type.getItemTypeName());
                    mdItem.setItemOrProduct(type.getItemOrProduct());
                }
                mdItem.setItemOrProduct(mdItemVo.getItemOrProduct());
                insertEpMdItem(mdItem, mdItemVo);
                return 1;
            } else {
                if(StringUtils.isEmpty(mdItem.getSapItemCode())){
                    throw new ServiceException("没有sap_item_code编码");
                }
                //修改

                if (Objects.isNull(mdItem1)) {
                    throw new ServiceException("该物理数据异常！");
                }
                mdItem.setUpdateBy("ep");
                mdItem.setUpdateTime(DateUtils.getNowDate());
                mdItem.setItemId(mdItem1.getItemId());
                MdItemType type = itemTypeMapper.selectItemTypeCode(mdItemVo.getItemTypeCode());
                if (StringUtils.isNotNull(type)) {
                    mdItem.setItemTypeId(type.getItemTypeId());
                    mdItem.setItemTypeCode(type.getItemTypeCode());
                    mdItem.setItemTypeName(type.getItemTypeName());
                    mdItem.setItemOrProduct(type.getItemOrProduct());
                }
                mdItem.setItemOrProduct(mdItemVo.getItemOrProduct());
                updateMdItems(mdItem, mdItemVo);
                return 2;
            }

        } else if (mdItemVo.getUpdateLog().equals("D")) {
            //删除
            List<MdItem> mdItems = mdItemMapper.selectMdItemByCode(mdItem.getItemCode());
            if (CollUtil.isEmpty(mdItems)) {
                throw new ServiceException("该数据已经被删除");
            }
            mdItems.forEach(c -> {
                ProProductionSolutionBom proProductionSolutionBom = new ProProductionSolutionBom();
                proProductionSolutionBom.setItemId(c.getItemId());
                List<ProProductionSolutionBom> proProductionSolutionBoms = proProductionSolutionBomMapper.selectProProductionSolutionBomList(proProductionSolutionBom);
                if (proProductionSolutionBoms.size() != 0) {
                    throw new ServiceException("该物理数据已被使用，不能删除！");
                }
            });
            MdItem mdItem1 = mdItemMapper.selectMdItemByCodes(mdItem.getSapItemCode());
            mdItemMapper.deleteMdItemByEpItemCode(mdItem.getItemCode());
            mdBaseInfoMapper.deleteMdBaseInfoByItemId(mdItem1.getItemId());
            productLookMapper.deleteMdProductLookByItemId(mdItem1.getItemId());

            return 3;
        }
        return i;
    }

    //ep传mes新增接口
    private int insertEpMdItem(MdItem mdItem, ItemUpdateMesVo mdItemVo) {

        mdItemMapper.insertMdItems(mdItem);
        //根据编码查看数据，替换子类的ID
        MdItem mdItem1 = mdItemMapper.selectMdItemByCodes(mdItem.getSapItemCode());

        //保存产品基本信息
        MdBaseInfo baseInfo = new MdBaseInfo();
        BeanUtils.copyProperties(mdItemVo, baseInfo);
        baseInfo.setCreateBy("ep");
        baseInfo.setItemId(mdItem1.getItemId());
        iMdBaseInfoService.insertMdBaseInfo(baseInfo);


        //保存产品外观信息
        if (ObjectUtil.isNotEmpty(mdItemVo.getProductLook())) {
            MdProductLook look = new MdProductLook();
            //如果创建信息是null，则新增
            BeanUtils.copyProperties(mdItemVo.getProductLook(), look);

            if (StringUtils.isNotNull(look.getFrontColor())) {
                String[] frontColor = look.getFrontColor();
                String join = String.join(",", frontColor);
                look.setFrontColorName(join);

            }
            if (StringUtils.isNotNull(look.getOppositeColor())) {
                String[] frontColor = look.getOppositeColor();
                String join = String.join(",", frontColor);
                look.setOppositeColorName(join);
            }
            look.setCreateBy("ep");
            look.setItemId(mdItem1.getItemId());
            iMdProductLookService.insertMdProductLook(look);
        }


        int i = 0;
        return i;
    }


    /**
     * 产品物料接收SAP
     *
     * @param mdItemVo
     * @return
     */
    @Override
    public int sapitemCreate(SapItemVo mdItemVo) {

        // TODO 产品物料SAP传MES
        int i = 0;
        boolean bool = false;
        MdItem mdItem = new MdItem();

        BeanUtils.copyProperties(mdItemVo, mdItem);
//        String sapItemCode = mdItem.getSapItemCode();
//        String s = sapItemCode.replaceFirst("^0+", "");
//        mdItem.setCreateBy("sap");
//        mdItem.setSapItemCode(s);

        QueryWrapper<MdItem> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("sap_item_code", mdItem.getSapItemCode());
        List<MdItem> mdItems = mdItemMapper.selectListByQw(queryWrapper);
        MdItem mdItem1 = mdItemMapper.selectMdItemBySapItemCode(mdItemVo.getSapItemCode());
        if (Objects.isNull(mdItem1)) {
            if (UserConstants.NOT_UNIQUE.equals(checkItemNameUnique(mdItem))) {
                throw new ServiceException("新增物料" + mdItem.getSapItemCode() + "失败，物料名称已存在");
            }

            MdItemType type = itemTypeMapper.selectItemTypeCode(mdItemVo.getItemTypeCode());
            if (StringUtils.isNotNull(type)) {
                mdItem.setItemTypeId(type.getItemTypeId());
                mdItem.setItemTypeCode(type.getItemTypeCode());
                mdItem.setItemTypeName(type.getItemTypeName());
                mdItem.setItemOrProduct(type.getItemOrProduct());
            }


            mdItem.setItemCode(mdItem.getSapItemCode());
            mdItem.setCreateBy("sap");
            mdItem.setCreateTime(DateUtils.getNowDate());
            mdItem.setItemEnglishName(mdItem.getSapEnglishName());

            mdItemMapper.insertMdItems(mdItem);
            return 1;
        } else {
            //修改

                mdItem.setItemId(mdItem1.getItemId());
                MdItemType type = itemTypeMapper.selectItemTypeCode(mdItemVo.getItemTypeCode());
                if (StringUtils.isNotNull(type)) {
                    mdItem.setItemTypeId(type.getItemTypeId());
                    mdItem.setItemTypeCode(type.getItemTypeCode());
                    mdItem.setItemTypeName(type.getItemTypeName());
                    mdItem.setItemOrProduct(type.getItemOrProduct());
                }


                mdItem.setItemCode(mdItem.getSapItemCode());
                mdItem.setUpdateBy("sap");
                mdItem.setUpdateTime(DateUtils.getNowDate());
                mdItem.setItemCode(mdItem1.getItemCode());
                updateMdItem(mdItem);
                return 2;


        }
    }
}
