package com.huigou.topsun.proofing.application.impl;

import com.huigou.cache.DictUtil;
import com.huigou.data.query.model.QueryDescriptor;
import com.huigou.data.query.model.QueryModel;
import com.huigou.topsun.proofing.application.WorkInstructionApplication;
import com.huigou.topsun.proofing.domain.vo.WorkInstructionVo;
import com.huigou.topsun.proofing.domain.workInstruction.model.*;
import com.huigou.topsun.proofing.domain.workInstruction.query.WorkInstructionBaseInfoQueryRequest;
import com.huigou.topsun.proofing.domain.workInstructionApply.model.WorkInstructionApply;
import com.huigou.topsun.proofing.repository.workInstruction.*;
import com.huigou.topsun.util.MyBaseUtil;
import com.huigou.uasp.bmp.common.application.BaseApplication;
import com.huigou.util.SDO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

@Service
public class WorkInstructionApplicationImpl extends BaseApplication implements WorkInstructionApplication {

    @Autowired
    WorkInstructionRepository workInstructionRepository;
    @Autowired
    WorkInstructionPdPublishedConfRepository workInstructionPdPublishedConfRepository;
    @Autowired
    WorkInstructionMaterialInfoRepository workInstructionMaterialInfoRepository;
    @Autowired
    WorkInstructionOptionalAttributeRepository workInstructionOptionalAttributeRepository;
    @Autowired
    WorkInstructionPrdLookedRepository workInstructionPrdLookedRepository;
    @Autowired
    WorkInstructionProductLossRepository workInstructionProductLossRepository;

    /**
     * 添加作业指导书及相关信息
     * @param sdo
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public Map<String,Object> saveWorkInstruction(SDO sdo) {
        HashMap<String, Object> idMap = new HashMap<>();
        WorkInstructionBaseInfo workInstruction = sdo.toObject(WorkInstructionBaseInfo.class);
        WorkInstructionPdPublishedConf workInstructionPdPublishedConf = sdo.toObject(WorkInstructionPdPublishedConf.class);
        WorkInstructionMaterialInfo workInstructionMaterialInfo = sdo.toObject(WorkInstructionMaterialInfo.class);
        WorkInstructionOptionalAttribute workInstructionOptionalAttribute = sdo.toObject( WorkInstructionOptionalAttribute.class);
        WorkInstructionPrdLooked workInstructionPrdLooked = sdo.toObject(WorkInstructionPrdLooked.class);
        WorkInstructionProductLoss workInstructionProductLoss = sdo.toObject(WorkInstructionProductLoss.class);

        WorkInstructionBaseInfo workInstructionBaseInfo = workInstructionRepository.save(workInstruction);
        idMap.put("workInstructionBaseInfoId",workInstructionBaseInfo.getWorkInstructionBaseInfoId());

        workInstructionPdPublishedConf.setWorkInstructionBaseInfoId(workInstructionBaseInfo.getWorkInstructionBaseInfoId());
        workInstructionPdPublishedConf = workInstructionPdPublishedConfRepository.save(workInstructionPdPublishedConf);
        idMap.put("workInstructionPdPublishedConfId",workInstructionPdPublishedConf.getWorkInstructionPdPublishedConfId());

        workInstructionMaterialInfo.setWorkInstructionBaseInfoId(workInstructionBaseInfo.getWorkInstructionBaseInfoId());
        workInstructionMaterialInfo= workInstructionMaterialInfoRepository.save(workInstructionMaterialInfo);
        idMap.put("workInstructionMaterialInfoId",workInstructionMaterialInfo.getWorkInstructionMaterialInfoId());

        workInstructionOptionalAttribute.setWorkInstructionBaseInfoId(workInstructionBaseInfo.getWorkInstructionBaseInfoId());
        workInstructionOptionalAttribute=workInstructionOptionalAttributeRepository.save(workInstructionOptionalAttribute);
        idMap.put("workInstructionOptionalAttributeId",workInstructionOptionalAttribute.getWorkInstructionOptionalAttributeId());

        workInstructionPrdLooked.setWorkInstructionBaseInfoId(workInstructionBaseInfo.getWorkInstructionBaseInfoId());
        workInstructionPrdLooked=workInstructionPrdLookedRepository.save(workInstructionPrdLooked);
        idMap.put("workInstructionPrdLookedId",workInstructionPrdLooked.getWorkInstructionPrdLookedId());

        workInstructionProductLoss.setWorkInstructionBaseInfoId(workInstructionBaseInfo.getWorkInstructionBaseInfoId());
        workInstructionProductLoss= workInstructionProductLossRepository.save(workInstructionProductLoss);
        idMap.put("productLossId",workInstructionProductLoss.getProductLossId());

        return idMap;
    }

    @Override
    public Map<String, Object> slicedWorkInstructionBaseInfoList(WorkInstructionBaseInfoQueryRequest queryRequest) {
        QueryDescriptor queryDescriptor = this.sqlExecutorDao.getQuery(QUERY_XML_FILE_PATH, "slicedWorkInstructionBaseInfoList");
        QueryModel model = this.sqlExecutorDao.getQueryModel(queryDescriptor, queryRequest);
        model.putDictionary("isOnlyCode", DictUtil.getDictionary("yesorno"));
        model.putDictionary("isBodyColor", DictUtil.getDictionary("yesorno"));
        model.putDictionary("isDisable", DictUtil.getDictionary("yesorno"));
        model.putDictionary("isNewSpecification", DictUtil.getDictionary("yesorno"));
        model.putDictionary("isBuildBom", DictUtil.getDictionary("yesorno"));

        return this.sqlExecutorDao.executeSlicedQuery(model);
    }

    @Override
    public WorkInstructionVo getWorkInstructionVoById(String id) {
        WorkInstructionVo workInstructionVo = new WorkInstructionVo();

        Stream.of(
                   workInstructionRepository.findOne(id),
                   workInstructionPdPublishedConfRepository.findByWorkInstructionBaseInfoId(id),
                   workInstructionMaterialInfoRepository.findByWorkInstructionBaseInfoId(id),
                   workInstructionOptionalAttributeRepository.findByWorkInstructionBaseInfoId(id),
                   workInstructionPrdLookedRepository.findByWorkInstructionBaseInfoId(id),
                   workInstructionProductLossRepository.findByWorkInstructionBaseInfoId(id)
                ).forEach(source -> MyBaseUtil.mergeObjects(workInstructionVo, source));
        return workInstructionVo;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void deleteWorkInstructionById(String id) {
        workInstructionPdPublishedConfRepository.deleteByWorkInstructionBaseInfoId(id);
        workInstructionMaterialInfoRepository.deleteByWorkInstructionBaseInfoId(id);
        workInstructionOptionalAttributeRepository.deleteByWorkInstructionBaseInfoId(id);
        workInstructionPrdLookedRepository.deleteByWorkInstructionBaseInfoId(id);
        workInstructionProductLossRepository.deleteByWorkInstructionBaseInfoId(id);
        workInstructionRepository.delete(id);
//        WorkInstructionBaseInfo workInstructionBaseInfo = workInstructionRepository.findOne(id);
//        workInstructionBaseInfo.setIsDelete("1");
//        workInstructionRepository.save(workInstructionBaseInfo);
    }

    @Override
    @Transactional
    public void deleteWorkInstructionByIds(List<String> ids) {
        ids.forEach(this::deleteWorkInstructionById);
    }
}
