package com.cf.imes.module.manage.service.plate;

import cn.hutool.core.collection.CollUtil;
import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.common.exception.util.ServiceExceptionUtil;
import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.framework.organ.core.context.OrganContextHolder;
import com.cf.imes.module.manage.controller.admin.plate.vo.plate.PlateImportExcelVO;
import com.cf.imes.module.manage.controller.admin.plate.vo.plate.PlateImportRespVO;
import com.cf.imes.module.manage.controller.admin.plate.vo.plate.PlatePageReqVO;
import com.cf.imes.module.manage.controller.admin.plate.vo.plate.PlateSaveReqVO;
import com.cf.imes.module.system.api.organ.OrganApi;
import com.cf.imes.module.system.enums.ErrorCodeConstants;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import com.cf.imes.module.manage.dal.dataobject.plate.PlateDO;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.common.util.object.BeanUtils;

import com.cf.imes.module.manage.dal.mysql.plate.PlateMapper;

import javax.annotation.Resource;

import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.PLATE_NOT_EXISTS;

/**
 * 板材信息表 plate_{N} Service 实现类
 *
 * @author 晨丰科技
 */
@Service
@Validated
public class PlateServiceImpl implements PlateService {

    @Resource
    private PlateMapper plateMapper;

    @Resource
    private OrganApi organApi;

    @Override
    public Long createPlate(PlateSaveReqVO createReqVO) {
        PlateDO plate = BeanUtils.toBean(createReqVO, PlateDO.class);
        if (createReqVO.getOrganId() != null && createReqVO.getOrganId() != 0 ){
            validateOrganExists(createReqVO.getOrganId());
            validateGoodExists(createReqVO.getGoodsId(), createReqVO.getOrganId());
            plate.setOrganId(OrganContextHolder.getOrganId());
        }
//        判断板材是否存在
        PlateDO existPlate = plateMapper.selectByGoodID(createReqVO.getGoodsId(), OrganContextHolder.getOrganId());
        System.out.println(" existPlate " + existPlate);
        if (existPlate != null){
            throw exception(ErrorCodeConstants.PLATE_EXISTS);
        }
        plateMapper.insert(plate);// 组织id未传输
        // 返回
        return plate.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePlate(PlateSaveReqVO updateReqVO) {
        // 更新 判断是否有组织id
        if (updateReqVO.getOrganId() == null || updateReqVO.getOrganId() == 0){
            updateReqVO.setOrganId(OrganContextHolder.getOrganId());
        }else {
            validateOrganExists(updateReqVO.getOrganId());
        }
        // 校验存在
        validatePlateExists(updateReqVO.getId(), updateReqVO.getOrganId());
        PlateDO updateObj = BeanUtils.toBean(updateReqVO, PlateDO.class);
        plateMapper.updateById(updateObj);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deletePlate(Long id,Long organId) {
        if (organId == null || organId == 0){
            organId = OrganContextHolder.getOrganId();
        }
        // 校验存在
        validatePlateExists(id,organId);
        // 删除
        plateMapper.deleteById(id);
    }

    private void validatePlateExists(Long id,Long organId) {
        if (plateMapper.selectOneById(id,organId) == null) {
            throw exception(PLATE_NOT_EXISTS);
        }
    }

    @Override
    public PlateDO getPlate(Long id) {
        return plateMapper.selectById(id);
    }

    @Override
    public PlateDO getPlateGoods(Long id) {
        return plateMapper.selectOne(PlateDO::getGoodsId,id);
    }

    @Override
    public PageResult<PlateDO> getPlatePage(PlatePageReqVO pageReqVO) {
        if (pageReqVO.getOrganId() == null || pageReqVO.getOrganId() == 0){
            pageReqVO.setOrganId(OrganContextHolder.getOrganId());
        }
        return plateMapper.selectPage(pageReqVO);
    }


    @Override
    @Transactional(rollbackFor = Exception.class) // 添加事务，异常则回滚所有导入
    public PlateImportRespVO importPlateList(List<PlateImportExcelVO> importPlates, boolean isUpdateSupport , Long organId) {
        if (CollUtil.isEmpty(importPlates)) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.PLATE_IMPORT_LIST_IS_EMPTY);
        }
        validateOrganExists(organId);
        PlateImportRespVO respVO = PlateImportRespVO.builder().createPlateNames(new ArrayList<>())
                .updatePlateNames(new ArrayList<>()).failurePlateNames(new LinkedHashMap<>()).build();
//        批量插入集合
        List<PlateDO> insertList = new ArrayList<>();
//        批量更新集合
        List<PlateDO> updateList = new ArrayList<>();
        importPlates.forEach(importPlate -> {
            // 判断如果不存在，在进行插入
            PlateDO existPlate = plateMapper.selectByGoodID(importPlate.getGoodsId(), organId);
            if (existPlate == null) {
                respVO.getCreatePlateNames().add(importPlate.getGoodsName());
                insertList.add(BeanUtils.toBean(importPlate, PlateDO.class).setOrganId(organId));
                return;
            }
            // 判断是否允许更新
            if (!isUpdateSupport) {
                respVO.getFailurePlateNames().put(importPlate.getGoodsName(), ErrorCodeConstants.PLATE_EXISTS.getMsg());
                PlateDO plateDO = BeanUtils.toBean(importPlate, PlateDO.class).setOrganId(organId).setId(existPlate.getId());
                updateList.add(plateDO);
            }
        });
//        批量插入，批量更新
        if (insertList.size() > 0 && insertList != null) {
            plateMapper.insertBatch(insertList);
        }
        if (updateList.size() > 0 && updateList != null) {
            plateMapper.updateBatch(updateList);
        }
        return respVO;
    }

    private void validateOrganExists(Long organId) {
        CommonResult<Boolean> index =  organApi.validOrgan(organId);
        if (!index.isSuccess()) {
            throw exception(ErrorCodeConstants.ORGAN_NOT_EXISTS);
        }
    }

    //    当前组织中板材是否存在
    private void validateGoodExists(String goodsId ,Long organId) {
        if (plateMapper.selectByGoodID(goodsId ,organId) != null){
            throw exception(ErrorCodeConstants.PLATE_EXISTS);
        }
    }

}