package com.foreverwin.mesnac.common.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.foreverwin.mesnac.common.constant.Constants;
import com.foreverwin.mesnac.common.enums.HandleEnum;
import com.foreverwin.mesnac.common.enums.InspectionTypeEnum;
import com.foreverwin.mesnac.common.mapper.InspectionItemMapper;
import com.foreverwin.mesnac.common.model.InspectionItem;
import com.foreverwin.mesnac.common.model.InspectionItemAddition;
import com.foreverwin.mesnac.common.model.InspectionItemDetail;
import com.foreverwin.mesnac.common.service.InspectionItemAdditionService;
import com.foreverwin.mesnac.common.service.InspectionItemDetailService;
import com.foreverwin.mesnac.common.service.InspectionItemService;
import com.foreverwin.mesnac.common.util.StringUtil;
import com.foreverwin.mesnac.meapi.model.Item;
import com.foreverwin.mesnac.meapi.model.Operation;
import com.foreverwin.mesnac.meapi.model.ResourceType;
import com.foreverwin.mesnac.meapi.service.ItemService;
import com.foreverwin.mesnac.meapi.service.OperationService;
import com.foreverwin.mesnac.meapi.service.ResourceTypeService;
import com.foreverwin.modular.core.exception.BaseException;
import com.foreverwin.modular.core.util.CommonMethods;
import com.foreverwin.modular.core.util.FrontPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 * 检验项目维护主表 服务实现类
 * </p>
 *
 * @author Philip
 * @since 2021-06-09
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class InspectionItemServiceImpl extends ServiceImpl<InspectionItemMapper, InspectionItem> implements InspectionItemService {

    @Autowired
    private ItemService itemService;
    @Autowired
    private OperationService operationService;
    @Autowired
    private ResourceTypeService resourceTypeService;
    @Autowired
    private InspectionItemMapper inspectionItemMapper;
    @Autowired
    private InspectionItemDetailService inspectionItemDetailService;
    @Autowired
    private InspectionItemAdditionService inspectionItemAdditionService;

    @Override
    public IPage<InspectionItem> selectPage(FrontPage<InspectionItem> frontPage, InspectionItem inspectionItem) {
        QueryWrapper<InspectionItem> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(inspectionItem);
        return super.page(frontPage.getPagePlus(), queryWrapper);
    }

    @Override
    public List<InspectionItem> selectList(InspectionItem inspectionItem) {
        QueryWrapper<InspectionItem> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(inspectionItem);
        return super.list(queryWrapper);
    }

    @Override
    public String findRevisionByCurrentRevision(String inspectionItemNo) {
        String site = CommonMethods.getSite();
        LambdaQueryWrapper<InspectionItem> lambdaQuery = new LambdaQueryWrapper<>();
        lambdaQuery.eq(InspectionItem::getInspectionItemNo, inspectionItemNo);
        lambdaQuery.eq(InspectionItem::getCurrentRevision, Constants.BOOL_TRUE);
        lambdaQuery.eq(InspectionItem::getSite, site);
        InspectionItem one = getOne(lambdaQuery, false);
        if (one != null) {
            return one.getRevision();
        }
        return null;
    }

    @Override
    public String inspectItemNoGenerationRules(InspectionItem inspectionItem) {
        List<InspectionItemAddition> inspectionItemAdditionList = inspectionItem.getInspectionItemAdditionList();
        StringBuilder inspectionItemNo = new StringBuilder();
        inspectionItemNo.append(inspectionItem.getInspectionType());
        inspectionItemAdditionList.forEach(inspectionItemAddition -> inspectionItemNo.append(inspectionItemAddition.getAdditionalObject()));
        return inspectionItemNo.toString();
    }

    @Override
    public InspectionItem saveAll(InspectionItem inspectionItem) {
        String site = CommonMethods.getSite();
        boolean b = false;
        if(StringUtil.isEmpty(inspectionItem.getInspectionItemNo())&&inspectionItem.getInspectionItemAdditionList().isEmpty()){
            throw new BaseException("检验项目编号不能为空");
        }
        if (StringUtil.isBlank(inspectionItem.getInspectionItemNo())) {
            b = true;
            inspectionItem.setInspectionItemNo(inspectItemNoGenerationRules(inspectionItem));
        }
        if (inspectionItem.getInspectionType().length() > 1) {
            inspectionItem.setCategory("EQ");
        } else {
            inspectionItem.setCategory("QC");
        }
        inspectionItem.setSite(site);
        if (StringUtil.isBlank(inspectionItem.getRevision())) {
            inspectionItem.setRevision("1");
        }
        inspectionItem.setHandle(HandleEnum
                .INSPECTION_ITEM.getHandle(inspectionItem.getSite(), inspectionItem.getInspectionItemNo(), inspectionItem.getRevision()));
        //保存检验项目维护-副
        //移除
        HashMap<String, Object> removeCondition = new HashMap<>();
        removeCondition.put(InspectionItemDetail.INSPECTION_ITEM_BO, inspectionItem.getHandle());
        inspectionItemDetailService.removeByMap(removeCondition);
        inspectionItemAdditionService.removeByMap(removeCondition);

        if (null != inspectionItem.getInspectionItemDetailList() && inspectionItem.getInspectionItemDetailList().size() > 0) {
            List<InspectionItemDetail> inspectionItemDetailList = inspectionItem.getInspectionItemDetailList();
            for (InspectionItemDetail inspectionItemDetail : inspectionItemDetailList) {
                inspectionItemDetail.setHandle(UUID.randomUUID().toString());
                inspectionItemDetail.setInspectionItemBo(inspectionItem.getHandle());
                inspectionItemDetail.setCreatedDateTime(LocalDateTime.now());
                inspectionItemDetail.setCreateUser(CommonMethods.getUser());
                inspectionItemDetail.setModifiedDateTime(LocalDateTime.now());
                inspectionItemDetail.setModifyUser(CommonMethods.getUser());
            }
            //保存
            inspectionItemDetailService.saveBatch(inspectionItemDetailList);
        }
        if (null != inspectionItem.getInspectionItemAdditionList() && inspectionItem.getInspectionItemAdditionList().size() > 0) {
            List<InspectionItemAddition> inspectionItemAdditionList = inspectionItem.getInspectionItemAdditionList();
            long count = inspectionItemAdditionList.stream().filter(inspectionItemAddition -> inspectionItemAddition.getAdditionalObject().equals("*")).count();
            if (count>0 && inspectionItemAdditionList.size()!=count){
                throw new BaseException("检验对象不能部分为*");
            }
            for (InspectionItemAddition inspectionItemAddition : inspectionItemAdditionList) {
                String additionalObject = inspectionItemAddition.getAdditionalObject();
                String additionalObjectType = inspectionItemAddition.getAdditionalObjectType();
                if (additionalObjectType.equals(Constants.ADDITIONAL_OBJECT_TYPE_ITEM) && !additionalObject.equals("*")) {
                    Item item = itemService.selectCurrent(CommonMethods.getSite(), additionalObject);
                    if (item == null) {
                        throw new BaseException("物料[" + additionalObject + "]不存在");
                    }
                }
                if (additionalObjectType.equals(Constants.ADDITIONAL_OBJECT_TYPE_OPERATION) && !additionalObject.equals("*")) {
                    String[] split = additionalObject.split("/");
                    String operation = split[0];
                    String step = split[1];
                    Integer integer = inspectionItemMapper.checkRouterStep(site, operation, step);
                    if (integer < 1) {
                        throw new BaseException("工序/步骤[" + additionalObject + "]不存在");
                    }
                }
                if (additionalObjectType.equals(Constants.ADDITIONAL_OBJECT_TYPE_RESOURCE_TYPE) && !additionalObject.equals("*")) {
                    String handle = HandleEnum.RESOURCE_TYPE.getHandle(site, additionalObject);
                    ResourceType byId = resourceTypeService.getById(handle);
                    if (byId == null) {
                        throw new BaseException("设备类型[" + additionalObject + "]不存在");
                    }
                }
                inspectionItemAddition.setHandle(UUID.randomUUID().toString());
                inspectionItemAddition.setInspectionItemBo(inspectionItem.getHandle());
                inspectionItemAddition.setCreatedDateTime(LocalDateTime.now());
                inspectionItemAddition.setCreateUser(CommonMethods.getUser());
                inspectionItemAddition.setModifiedDateTime(LocalDateTime.now());
                inspectionItemAddition.setModifyUser(CommonMethods.getUser());
            }
            //保存
            inspectionItemAdditionService.saveBatch(inspectionItemAdditionList);
        }

        //保存检验项目维护-主
        if (inspectionItem.getCurrentRevision().equals(Constants.BOOL_TRUE)) {
            String inspectionItemNo = inspectionItem.getInspectionItemNo();
            UpdateWrapper<InspectionItem> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq(InspectionItem.INSPECTION_ITEM_NO, inspectionItemNo);
            updateWrapper.eq(InspectionItem.SITE, inspectionItem.getSite());
            updateWrapper.ne(InspectionItem.REVISION, inspectionItem.getRevision());
            InspectionItem entity=new InspectionItem();
            entity.setCurrentRevision(Constants.BOOL_FALSE);
            update(entity,updateWrapper);
        }
        if (inspectionItem.selectById(inspectionItem.getHandle()) == null) {
            inspectionItem.setCreatedDateTime(LocalDateTime.now());
            inspectionItem.setCreateUser(CommonMethods.getUser());
            inspectionItem.setModifiedDateTime(LocalDateTime.now());
            inspectionItem.setModifyUser(CommonMethods.getUser());
            save(inspectionItem);
        } else {
            inspectionItem.setModifiedDateTime(LocalDateTime.now());
            inspectionItem.setModifyUser(CommonMethods.getUser());
            if (b) {
                throw new BaseException("请先检索再保存");
            }
            saveOrUpdate(inspectionItem);
        }
        return inspectionItem;
    }

    @Override
    public void deleteServece(InspectionItem inspectionItem) {
        if (StringUtil.isBlank(inspectionItem.getInspectionItemNo())) {
            throw new BaseException("请输入编号");
        }
        if (StringUtil.isBlank(inspectionItem.getRevision())) {
            throw new BaseException("请输入版本");
        }
        inspectionItem.setSite(CommonMethods.getSite());
        String handle = HandleEnum.INSPECTION_ITEM.getHandle(inspectionItem.getSite(), inspectionItem.getInspectionItemNo(), inspectionItem.getRevision());
        inspectionItem.setHandle(handle);
        Integer num=inspectionItemMapper.resrcePlanCheck(handle);
        if (num>0){
            throw new BaseException("检验项目已被使用，无法删除");
        }
        num=inspectionItemMapper.resrceTaskCheck(handle);
        if (num>0){
            throw new BaseException("检验项目已被使用，无法删除");
        }
        num=inspectionItemMapper.inspectTaskCheck(handle);
        if (num>0){
            throw new BaseException("检验项目已被使用，无法删除");
        }
        HashMap<String, Object> removeCondition = new HashMap<>();
        removeCondition.put(InspectionItemAddition.INSPECTION_ITEM_BO, inspectionItem.getHandle());
        inspectionItemAdditionService.removeByMap(removeCondition);
        inspectionItemDetailService.removeByMap(removeCondition);
        removeById(inspectionItem.getHandle());
    }

    //是否存在质量自检互检任务
    @Override
    public List<InspectionItemDetail> selectQualityInspection(String sfc, String operation, String stepId, String inspectionType) {
        String site = CommonMethods.getSite();
        List<InspectionItemDetail> inspectionItemDetails = inspectionItemMapper.selectQualityInspection(site, sfc, operation, stepId, inspectionType);
        if (inspectionItemDetails.isEmpty()) {
            //是否有维护*的项目
            inspectionItemDetails = inspectionItemMapper.selectWidestQualityInspection(site, inspectionType, "*");
        }

        return inspectionItemDetails;
    }

    @Override
    public void insert(JSONObject jsonObject) {
        String user = CommonMethods.getUser();
        LocalDateTime now = LocalDateTime.now();
        String description = jsonObject.getString("description");
        String site = jsonObject.getString("site");
        String inspectionType = jsonObject.getString("inspectionType");
        inspectionType = InspectionTypeEnum.getValue(inspectionType);
        if (inspectionType==null){
            throw new BaseException("不存在的检验类型");
        }
        String inspectionItemNo = jsonObject.getString("inspectionItemNo");
        if (StringUtil.isBlank(inspectionItemNo)){
            throw new BaseException("检验项目编号不能为空");
        }
        String revision = jsonObject.getString("revision");
        if (StringUtil.isBlank(revision)){
            throw new BaseException("版本不能为空");
        }
        String item = jsonObject.getString("item");
        String operation = jsonObject.getString("operation");
        String resrceType = jsonObject.getString("resrceType");
        String paramNo = jsonObject.getString("paramNo");
        if (StringUtil.isBlank(paramNo)){
            throw new BaseException("参数名称不能为空");
        }
        String paramDescription = jsonObject.getString("paramDescription");
        String inspectionMethod = jsonObject.getString("inspectionMethod");
        if (StringUtil.isBlank(inspectionMethod)){
            throw new BaseException("检验方法不能为空");
        }
        String paramType = jsonObject.getString("paramType");
        paramType = InspectionTypeEnum.getValue(paramType);
        if (StringUtil.isBlank(paramType)){
            throw new BaseException("不存在的参数类型");
        }
        String decimalNum = jsonObject.getString("decimalNum");
        String paramUnit = jsonObject.getString("paramUnit");
        String maxValue = jsonObject.getString("maxValue");
        String standardValue = jsonObject.getString("standardValue");
        String minValue = jsonObject.getString("minValue");
        String falseValue = jsonObject.getString("falseValue");
        String trueValue = jsonObject.getString("trueValue");
        String isRequired = jsonObject.getString("isRequired");
        if (StringUtil.isBlank(isRequired)){
            throw new BaseException("是否重要项不能为空");
        }
        String checkNum = jsonObject.getString("checkNum");
        String handle = HandleEnum.INSPECTION_ITEM.getHandle(site, inspectionItemNo, revision);
        InspectionItem byId = getById(handle);
        if (byId==null){
            InspectionItem entity=new InspectionItem();
            entity.setHandle(HandleEnum.INSPECTION_ITEM.getHandle(site,inspectionItemNo,revision));
            entity.setSite(site);
            entity.setInspectionItemNo(inspectionItemNo);
            if (inspectionType.length() > 1) {
                entity.setCategory("EQ");
            } else {
                entity.setCategory("QC");
            }
            entity.setInspectionType(inspectionType);
            entity.setRevision(revision);
            entity.setCurrentRevision(Constants.BOOL_TRUE);
            entity.setDescription(description);
            entity.setStatus(Constants.STATUS_Y);
            entity.setCreateUser(user);
            entity.setCreatedDateTime(now);
            entity.setModifyUser(user);
            entity.setModifiedDateTime(now);
            entity.setCategory(user);
            save(entity);
        }
        ResourceType selectResourceType = null;
        Item currentItem = null;
        Operation currentRevisionRef = null;
        if (inspectionType.length() == 1) {
            if (StringUtil.isBlank(item)){
                throw new BaseException("物料不能为空");
            }
            if (StringUtil.isBlank(operation)){
                throw new BaseException("工序不能为空");
            }
            if ( !item.equals("*")) {
                currentItem = itemService.selectCurrent(CommonMethods.getSite(), item);
                if (currentItem == null) {
                    throw new BaseException("物料[" + item + "]不存在");
                }
            }
            if (!operation.equals("*")) {
                String[] split = operation.split("/");
                String op = split[0];
                currentRevisionRef = operationService.getCurrentRevisionRef(site, op);
                String step = split[1];
                Integer integer = inspectionItemMapper.checkRouterStep(site, op, step);
                if (integer < 1) {
                    throw new BaseException("工序/步骤[" + operation + "]不存在");
                }
            }
        }else {
            if (StringUtil.notBlank(resrceType)&&!resrceType.equals("*")) {
                String resourceTypeHandle = HandleEnum.RESOURCE_TYPE.getHandle(site, resrceType);
                selectResourceType = resourceTypeService.getById(resourceTypeHandle);
                if (selectResourceType == null) {
                    throw new BaseException("设备类型[" + resrceType + "]不存在");
                }
            }
        }
        QueryWrapper queryWrapper=new QueryWrapper<InspectionItemAddition>();
        queryWrapper.eq(InspectionItemAddition.INSPECTION_ITEM_BO,handle);
        List<InspectionItemAddition> additionList = inspectionItemAdditionService.list(queryWrapper);
        if (additionList.size()>0){
            for (InspectionItemAddition inspectionItemAddition : additionList) {
                if (inspectionItemAddition.getAdditionalObjectType().equals(Constants.ADDITIONAL_OBJECT_TYPE_ITEM)&&!inspectionItemAddition.getAdditionalObject().equals(item)){
                    throw new BaseException("检验项目中物料[" + item + "]不相同");
                }
                if (inspectionItemAddition.getAdditionalObjectType().equals(Constants.ADDITIONAL_OBJECT_TYPE_OPERATION)&&!inspectionItemAddition.getAdditionalObject().equals(operation)){
                    throw new BaseException("检验项目中工序[" + operation + "]不相同");
                }
                if (inspectionItemAddition.getAdditionalObjectType().equals(Constants.ADDITIONAL_OBJECT_TYPE_RESOURCE_TYPE)&&!inspectionItemAddition.getAdditionalObject().equals(resrceType)){
                    throw new BaseException("检验项目中设备类型[" + resrceType + "]不相同");
                }

            }
        }else {
            if (inspectionType.length()==1){
                InspectionItemAddition itemAddition = new InspectionItemAddition();
                itemAddition.setHandle(UUID.randomUUID().toString());
                itemAddition.setInspectionItemBo(handle);
                itemAddition.setSeq(1L);
                itemAddition.setAdditionalObjectType(Constants.ADDITIONAL_OBJECT_TYPE_ITEM);
                itemAddition.setAdditionalObject(item);
                itemAddition.setDescription(currentItem.getDescription());
                itemAddition.setCreateUser(user);
                itemAddition.setCreatedDateTime(now);
                itemAddition.setModifyUser(user);
                itemAddition.setModifiedDateTime(now);
                inspectionItemAdditionService.save(itemAddition);
                InspectionItemAddition operationAddition = new InspectionItemAddition();
                operationAddition.setHandle(UUID.randomUUID().toString());
                operationAddition.setInspectionItemBo(handle);
                operationAddition.setSeq(2L);
                operationAddition.setAdditionalObjectType(Constants.ADDITIONAL_OBJECT_TYPE_OPERATION);
                operationAddition.setAdditionalObject(operation);
                operationAddition.setDescription(currentRevisionRef.getDescription());
                operationAddition.setCreateUser(user);
                operationAddition.setCreatedDateTime(now);
                operationAddition.setModifyUser(user);
                operationAddition.setModifiedDateTime(now);
                inspectionItemAdditionService.save(operationAddition);
            }else {
                if (StringUtil.notBlank(resrceType)){
                    InspectionItemAddition inspectionItemAddition = new InspectionItemAddition();
                    inspectionItemAddition.setHandle(UUID.randomUUID().toString());
                    inspectionItemAddition.setInspectionItemBo(handle);
                    inspectionItemAddition.setSeq(1L);
                    inspectionItemAddition.setAdditionalObjectType(Constants.ADDITIONAL_OBJECT_TYPE_RESOURCE_TYPE);
                    inspectionItemAddition.setAdditionalObject(resrceType);
                    inspectionItemAddition.setDescription(selectResourceType.getDescription());
                    inspectionItemAddition.setCreateUser(user);
                    inspectionItemAddition.setCreatedDateTime(now);
                    inspectionItemAddition.setModifyUser(user);
                    inspectionItemAddition.setModifiedDateTime(now);
                    inspectionItemAdditionService.save(inspectionItemAddition);
                }
            }

        }
        queryWrapper=new QueryWrapper<InspectionItemDetail>();
        queryWrapper.eq(InspectionItemDetail.INSPECTION_ITEM_BO,handle);
        List<InspectionItemDetail> inspectionItemDetailList = inspectionItemDetailService.list(queryWrapper);
        if (inspectionItemDetailList.size()>0){
            long count = inspectionItemDetailList.stream().filter(inspectionItemDetail ->
            inspectionItemDetail.getParamNo().equals(paramNo)
            ).count();
            if (count>0){
                throw new BaseException("检验名称不能重复");
            }
        }
        InspectionItemDetail inspectionItemDetail = new InspectionItemDetail();
        inspectionItemDetail.setHandle(UUID.randomUUID().toString());
        inspectionItemDetail.setInspectionItemBo(handle);
        inspectionItemDetail.setSeq(new Long(inspectionItemDetailList.size())+1L);
        inspectionItemDetail.setParamNo(paramNo);
        inspectionItemDetail.setDescription(paramDescription);
        inspectionItemDetail.setInspectionMethod(inspectionMethod);
        inspectionItemDetail.setParamType(paramType);
        inspectionItemDetail.setParamUnit(paramUnit);
        inspectionItemDetail.setDecimalNum(StringUtil.isBlank(decimalNum)?null:new Long(decimalNum));
        inspectionItemDetail.setMinValue(StringUtil.isBlank(minValue)?null:new BigDecimal(minValue));
        inspectionItemDetail.setStandardValue(standardValue);
        inspectionItemDetail.setMaxValue(StringUtil.isBlank(maxValue)?null:new BigDecimal(maxValue));
        inspectionItemDetail.setFalseValue(falseValue);
        inspectionItemDetail.setTrueValue(trueValue);
        inspectionItemDetail.setIsRequired(isRequired.equals("是")?"Y":"N");
        inspectionItemDetail.setCheckNum(StringUtil.isBlank(checkNum)?null:new Long(checkNum));
        inspectionItemDetail.setCreateUser(user);
        inspectionItemDetail.setCreatedDateTime(now);
        inspectionItemDetail.setModifyUser(user);
        inspectionItemDetail.setModifiedDateTime(now);
        inspectionItemDetailService.save(inspectionItemDetail);
    }


}