package cn.iocoder.yudao.module.smartfactory.service.handlingspecifications;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.datapermission.core.util.DataPermissionUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
import cn.iocoder.yudao.module.smartfactory.controller.admin.handlingspecifications.vo.HandlingSpecificationsImportRespVO;
import cn.iocoder.yudao.module.smartfactory.controller.admin.handlingspecifications.vo.HandlingSpecificationsImportVO;
import cn.iocoder.yudao.module.smartfactory.controller.admin.handlingspecifications.vo.HandlingSpecificationsPageReqVO;
import cn.iocoder.yudao.module.smartfactory.controller.admin.handlingspecifications.vo.HandlingSpecificationsSaveReqVO;
import cn.iocoder.yudao.module.smartfactory.dal.dataobject.handlingspecifications.HandlingSpecificationsDO;
import cn.iocoder.yudao.module.smartfactory.dal.mysql.handlingspecifications.HandlingSpecificationsMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.smartfactory.enums.ErrorCodeConstants.FACTORY_HANDLING_SPECIFICATION_EXISTS;
import static cn.iocoder.yudao.module.smartfactory.enums.ErrorCodeConstants.IMPORT_LIST_IS_EMPTY;

/**
 * 工厂搬运规格 Service 实现类
 *
 * @author 艾楷
 */
@Service
@Validated
public class HandlingSpecificationsServiceImpl extends ServiceImpl<HandlingSpecificationsMapper, HandlingSpecificationsDO> implements HandlingSpecificationsService {

    @Resource
    private HandlingSpecificationsMapper handlingSpecificationsMapper;

    @Override
    public Long createHandlingSpecifications(HandlingSpecificationsSaveReqVO createReqVO) {
        // 插入
        HandlingSpecificationsDO handlingSpecifications = BeanUtils.toBean(createReqVO, HandlingSpecificationsDO.class);
        handlingSpecificationsMapper.insert(handlingSpecifications);
        // 返回
        return handlingSpecifications.getId();
    }

    @Override
    public void updateHandlingSpecifications(HandlingSpecificationsSaveReqVO updateReqVO) {
        // 更新
        HandlingSpecificationsDO updateObj = BeanUtils.toBean(updateReqVO, HandlingSpecificationsDO.class);
        handlingSpecificationsMapper.updateById(updateObj);
    }

    @Override
    public void deleteHandlingSpecifications(Long id) {
        // 删除
        handlingSpecificationsMapper.deleteById(id);
    }

    @Override
    public HandlingSpecificationsDO getHandlingSpecifications(Long id) {
        return handlingSpecificationsMapper.getHandlingSpecifications(id);
    }

    @Override
    public PageResult<HandlingSpecificationsDO> getHandlingSpecificationsPage(HandlingSpecificationsPageReqVO pageReqVO) {
        IPage<HandlingSpecificationsDO> page = handlingSpecificationsMapper.getHandlingSpecificationsPage(MyBatisUtils.buildPage(pageReqVO) ,pageReqVO);
        return new PageResult<>(page.getRecords(), page.getTotal());
    }

    @Override
    public List<HandlingSpecificationsDO> getHandlingSpecificationsList(HandlingSpecificationsPageReqVO pageReqVO) {
        return handlingSpecificationsMapper.getHandlingSpecificationsList(pageReqVO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class) // 添加事务，异常则回滚所有导入
    public HandlingSpecificationsImportRespVO importList(List<HandlingSpecificationsImportVO> list, Boolean updateSupport) {

        if (CollUtil.isEmpty(list)) {
            throw exception(IMPORT_LIST_IS_EMPTY);
        }
        HandlingSpecificationsImportRespVO respVO = HandlingSpecificationsImportRespVO.builder()
                .createUsernames(new ArrayList<>())
                .updateUsernames(new ArrayList<>())
                .failureUsernames(new HashMap<>()).build();

        list.forEach(importUser -> {
            if (importUser.getFactoryName() == null) {
                return;
            }

            // 解析工厂名称数据 格式为 id:name
            Long factoryId = Long.valueOf(importUser.getFactoryName().split(":")[0]);
            String factoryName = importUser.getFactoryName().split(":")[1];

            //校验，判断是否有不符合的原因
            try {
                if (!updateSupport) {
                    validateForCreate(factoryId, importUser.getSpecificationsName());
                }
            } catch (ServiceException ex) {
                respVO.getFailureUsernames().put(factoryName, ex.getMessage());
                return;
            }

            HandlingSpecificationsDO updateDo = new HandlingSpecificationsDO();
            // 设置工厂编号
            updateDo.setFactoryId(factoryId);
            // 设置规格名称
            updateDo.setSpecificationsName(importUser.getSpecificationsName());
            // 设置重量
            updateDo.setWeight(importUser.getWeight());
            // 设置单价
            updateDo.setUnitPrice(importUser.getUnitPrice());

            Integer type = null;
            if (importUser.getType() != null) {
                // 解析类型数据
                type = Integer.valueOf(importUser.getType().split(":")[0]);
                updateDo.setType(type);
            }

            // 判断如果不存在，在进行插入
            if (updateSupport) {
                HandlingSpecificationsDO handlingSpecificationsDO = handlingSpecificationsMapper.selectOne(new LambdaQueryWrapperX<HandlingSpecificationsDO>()
                        .eqIfPresent(HandlingSpecificationsDO::getFactoryId, factoryId)
                        .eqIfPresent(HandlingSpecificationsDO::getSpecificationsName, importUser.getSpecificationsName()));

                updateDo.setId(handlingSpecificationsDO.getId());
                handlingSpecificationsMapper.updateById(updateDo);
                respVO.getUpdateUsernames().add(factoryName);
                return;
            }

            // 插入用户
            handlingSpecificationsMapper.insert(updateDo);
            respVO.getCreateUsernames().add(factoryName);
        });

        return respVO;
    }

    private void validateForCreate(Long factoryId, String specificationsName) {

        // 关闭数据权限，避免因为没有数据权限，查询不到数据，进而导致唯一校验不正确
        DataPermissionUtils.executeIgnore(() -> {

            // 校验用户名、身份证号是否已经存在
            Long cunt = handlingSpecificationsMapper.selectCount(new LambdaQueryWrapperX<HandlingSpecificationsDO>()
                    .eqIfPresent(HandlingSpecificationsDO::getFactoryId, factoryId)
                    .eqIfPresent(HandlingSpecificationsDO::getSpecificationsName, specificationsName));
            if (cunt > 0) {
                throw exception(FACTORY_HANDLING_SPECIFICATION_EXISTS);
            }
        });
    }

}
