package com.maintain.business.listener;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.maintain.business.domain.*;
import com.maintain.business.domain.vo.ErpCarVo;
import com.maintain.business.domain.vo.ErpMaterialVo;
import com.maintain.business.mapper.*;
import com.maintain.common.enums.IsDeleteStatus;
import com.maintain.common.excel.ExcelListener;
import com.maintain.common.excel.ExcelResult;
import com.maintain.common.exception.ServiceException;
import com.maintain.common.helper.LoginHelper;
import com.maintain.common.utils.StringUtils;
import com.maintain.common.utils.ValidatorUtils;
import com.maintain.common.utils.spring.SpringUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

/**
 * 车辆自定义导入
 *
 * @author liushuai
 */
@Slf4j
public class ErpMaterialImportListener extends AnalysisEventListener<ErpMaterialVo> implements ExcelListener<ErpMaterialVo> {

    private final ErpMaterialMapper materialMapper;
    private final ErpWarehouseMapper warehouseMapper;
    private final ErpMaterialVendorMapper materialVendorMapper;
    private final ErpMaterialTypeMapper materialTypeMapper;
    private final ErpWarehouseLocationMapper warehouseLocationMapper;

    private final Boolean isUpdateSupport;

    private final String operName;

    private int successNum = 0;
    private int failureNum = 0;
    private final StringBuilder successMsg = new StringBuilder();
    private final StringBuilder failureMsg = new StringBuilder();

    public ErpMaterialImportListener(Boolean isUpdateSupport) {
        this.materialMapper = SpringUtils.getBean(ErpMaterialMapper.class);
        this.warehouseMapper = SpringUtils.getBean(ErpWarehouseMapper.class);
        this.materialVendorMapper = SpringUtils.getBean(ErpMaterialVendorMapper.class);
        this.materialTypeMapper = SpringUtils.getBean(ErpMaterialTypeMapper.class);
        this.warehouseLocationMapper = SpringUtils.getBean(ErpWarehouseLocationMapper.class);
        this.isUpdateSupport = isUpdateSupport;
        this.operName = LoginHelper.getUsername();
    }

    @Override
    public void invoke(ErpMaterialVo materialImportVo, AnalysisContext context) {
        LambdaQueryWrapper<ErpMaterial> materialLambdaQueryWrapper = new LambdaQueryWrapper<>();
        materialLambdaQueryWrapper.eq(ErpMaterial::getMaterialCode, materialImportVo.getMaterialCode())
            .eq(ErpMaterial::getMaterialName, materialImportVo.getMaterialName()).eq(ErpMaterial::getIsDelete, IsDeleteStatus.NO.getCode());
        ErpMaterial material = materialMapper.selectOne(materialLambdaQueryWrapper);
        try {
            // 验证是否存在
            if (ObjectUtil.isNull(material)) {
                material = BeanUtil.toBean(materialImportVo, ErpMaterial.class);
                ValidatorUtils.validate(material);
                /**
                 * 物资仓库
                 */
                if (StringUtils.isNotEmpty(material.getWarehouseName())) {
                    ErpWarehouse erpWarehouse = warehouseMapper.selectOne(new LambdaQueryWrapper<ErpWarehouse>().eq(ErpWarehouse::getName, material.getWarehouseName()));
                    if (ObjectUtil.isNull(erpWarehouse)) {
//                        ErpWarehouse warehouse = new ErpWarehouse();
//                        warehouse.setCode(material.getWarehouseName());
//                        warehouse.setName(material.getWarehouseName());
//                        warehouseMapper.insert(warehouse);
//                        material.setWarehouseId(warehouse.getId());
                        throw new RuntimeException("所属仓库不存在，创建仓库后再次导入");
                    }else {
                        material.setDeptId(erpWarehouse.getDeptId());
                        material.setDeptName(erpWarehouse.getDeptName());
                        material.setWarehouseId(erpWarehouse.getId());
                    }
                }
                /**
                 * 物资类型
                 */
                if (StringUtils.isNotEmpty(material.getMaterialTypeName())) {
                    List<ErpMaterialType> materialTypes = materialTypeMapper.selectList(new LambdaQueryWrapper<ErpMaterialType>().eq(ErpMaterialType::getTypeName, material.getMaterialTypeName()));
                    if (materialTypes.isEmpty()) {
                        ErpMaterialType materialType = new ErpMaterialType();
                        materialType.setTypeName(material.getMaterialTypeName());
                        materialType.setParentId(1L);
                        materialType.setAncestors("0,1");
                        materialTypeMapper.insert(materialType);
                        material.setMaterialTypeId(materialType.getTypeId());
                    }else {
                        material.setMaterialTypeId(materialTypes.get(0).getTypeId());
                    }
                }
                /**
                 * 供应商
                 */
                if (StringUtils.isNotEmpty(material.getVendorName())) {
                    ErpMaterialVendor erpMaterialVendor = materialVendorMapper.selectOne(new LambdaQueryWrapper<ErpMaterialVendor>().eq(ErpMaterialVendor::getVendorName, material.getVendorName()));
                    if (ObjectUtil.isNull(erpMaterialVendor)) {
                        ErpMaterialVendor vendor = new ErpMaterialVendor();
                        vendor.setVendorName(material.getVendorName());
                        materialVendorMapper.insert(vendor);
                        material.setVendorId(vendor.getId());
                    } else {
                        material.setVendorId(erpMaterialVendor.getId());
                    }
                }
                /**
                 * 仓库货位
                 */
                if (StringUtils.isNotEmpty(material.getWarehouseLocationType())) {
                    ErpWarehouseLocation warehouseLocation = warehouseLocationMapper.selectOne(new LambdaQueryWrapper<ErpWarehouseLocation>().eq(ErpWarehouseLocation::getLocationType, material.getWarehouseLocationType()));
                    if (ObjectUtil.isNull(warehouseLocation)) {
                        ErpWarehouseLocation location = new ErpWarehouseLocation();
                        location.setLocationCode(material.getWarehouseLocationType());
                        location.setLocationType(material.getWarehouseLocationType());
                        warehouseLocationMapper.insert(location);
                        material.setWarehouseLocationCode(location.getLocationCode());
                        material.setWarehouseLocationId(location.getId());
                    } else {
                        material.setWarehouseLocationCode(warehouseLocation.getLocationCode());
                        material.setWarehouseLocationId(warehouseLocation.getId());
                    }
                }
                materialMapper.insert(material);
                successNum++;
                successMsg.append("<br/>").append(successNum).append("、物料 【").append(material.getMaterialName()).append("】 导入成功");
            } else if (isUpdateSupport) {
                Long materialId = material.getId();
                material = BeanUtil.toBean(materialImportVo, ErpMaterial.class);
                material.setId(materialId);
                ValidatorUtils.validate(material);
                /**
                 * 物资类型
                 */
                if (StringUtils.isNotEmpty(material.getMaterialTypeName())) {
                    List<ErpMaterialType> materialTypes = materialTypeMapper.selectList(new LambdaQueryWrapper<ErpMaterialType>().eq(ErpMaterialType::getTypeName, material.getMaterialTypeName()));
                    if (materialTypes.isEmpty()) {
                        ErpMaterialType materialType = new ErpMaterialType();
                        materialType.setTypeName(material.getMaterialTypeName());
                        materialType.setParentId(1L);
                        materialType.setAncestors("0,1");
                        materialTypeMapper.insert(materialType);
                        material.setMaterialTypeId(materialType.getTypeId());
                    }else {
                        material.setMaterialTypeId(materialTypes.get(0).getTypeId());
                    }
                }
                /**
                 * 物资仓库
                 */
                if (StringUtils.isNotEmpty(material.getWarehouseName())) {
                    ErpWarehouse erpWarehouse = warehouseMapper.selectOne(new LambdaQueryWrapper<ErpWarehouse>().eq(ErpWarehouse::getName, material.getWarehouseName()));
                    if (ObjectUtil.isNull(erpWarehouse)) {
                        ErpWarehouse warehouse = new ErpWarehouse();
                        warehouse.setCode(material.getWarehouseName());
                        warehouse.setName(material.getWarehouseName());
                        warehouseMapper.insert(warehouse);
                        material.setWarehouseId(warehouse.getId());
                    }else {
                        material.setWarehouseId(erpWarehouse.getId());
                    }
                }
                /**
                 * 供应商
                 */
                if (StringUtils.isNotEmpty(material.getVendorName())) {
                    ErpMaterialVendor erpMaterialVendor = materialVendorMapper.selectOne(new LambdaQueryWrapper<ErpMaterialVendor>().eq(ErpMaterialVendor::getVendorName, material.getVendorName()));
                    if (ObjectUtil.isNull(erpMaterialVendor)) {
                        ErpMaterialVendor vendor = new ErpMaterialVendor();
                        vendor.setVendorName(material.getVendorName());
                        materialVendorMapper.insert(vendor);
                        material.setVendorId(vendor.getId());
                    } else {
                        material.setVendorId(erpMaterialVendor.getId());
                    }
                }
                /**
                 * 仓库货位
                 */
                if (StringUtils.isNotEmpty(material.getWarehouseLocationType())) {
                    ErpWarehouseLocation warehouseLocation = warehouseLocationMapper.selectOne(new LambdaQueryWrapper<ErpWarehouseLocation>().eq(ErpWarehouseLocation::getLocationType, material.getWarehouseLocationType()));
                    if (ObjectUtil.isNull(warehouseLocation)) {
                        ErpWarehouseLocation location = new ErpWarehouseLocation();
                        location.setLocationCode(material.getWarehouseLocationType());
                        location.setLocationType(material.getWarehouseLocationType());
                        warehouseLocationMapper.insert(location);
                        material.setWarehouseLocationId(location.getId());
                    } else {
                        material.setWarehouseLocationId(warehouseLocation.getId());
                    }
                }
                materialMapper.updateById(material);
                successNum++;
                successMsg.append("<br/>").append(successNum).append("、物料 ").append(material.getMaterialName()).append(" 更新成功");
            } else {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、物料 【").append(material.getMaterialName()).append("】 已存在");
            }
        } catch (Exception e) {
            failureNum++;
            String msg = "<br/>" + failureNum + "、物料 【" + material.getMaterialName() + "】 导入失败：";
            failureMsg.append(msg).append(e.getMessage());
            log.error(msg, e);
        }

    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {

    }

    @Override
    public ExcelResult<ErpMaterialVo> getExcelResult() {
        return new ExcelResult<ErpMaterialVo>() {

            @Override
            public String getAnalysis() {
                if (failureNum > 0) {
                    failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
                    throw new ServiceException(failureMsg.toString());
                } else {
                    successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
                }
                return successMsg.toString();
            }

            @Override
            public List<ErpMaterialVo> getList() {
                return null;
            }

            @Override
            public List<String> getErrorList() {
                return null;
            }
        };
    }
}
