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

import com.huigou.topsun.product.application.ProductApplication;
import com.huigou.topsun.product.application.ProductCategoryApplication;
import com.huigou.topsun.product.application.ProductLookedApplication;
import com.huigou.topsun.product.domain.Product;
import com.huigou.topsun.product.domain.ProductCategory;
import com.huigou.topsun.product.domain.ProductLooked;
import com.huigou.topsun.product.domain.ProductPublishedConf;
import com.huigou.topsun.product.repository.ProductPublishedConfRepository;
import com.huigou.topsun.product.repository.ProductRepository;
import com.huigou.topsun.proofing.application.ProofingApplyApplication;
import com.huigou.topsun.proofing.domain.model.ProofingApply;
import com.huigou.topsun.proofing.domain.query.ProofingApplyQuery;
import com.huigou.topsun.proofing.domain.vo.ProofingApplyAndLookedVo;
import com.huigou.topsun.proofing.mapper.ProofingApplyMapper;
import com.huigou.topsun.proofing.repository.ProofingApplyRepository;
import com.huigou.uasp.bmp.common.BizBillStatus;
import com.huigou.uasp.bpm.FlowBroker;
import com.huigou.util.ClassHelper;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.DelegateTask;
import org.springframework.beans.BeanUtils;
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.List;
import java.util.Map;
import java.util.UUID;

/**
 * @author yonghuan
 */
@Service("proofingApplyApplication")
public class ProofingApplyApplicationImpl extends FlowBroker implements ProofingApplyApplication {

    @Autowired
    private ProofingApplyRepository proofingApplyRepository;
    @Autowired
    private ProofingApplyMapper proofingApplyMapper;
    @Autowired
    private ProductLookedApplication productLookedApplication;
    @Autowired
    private ProductCategoryApplication productCategoryApplication;
    @Autowired
    private ProductRepository productRepository;
    @Autowired
    private ProductPublishedConfRepository productPublishedConfRepository;


    @Override
    public ProofingApply loadProofingApplyById(String id) {
        return proofingApplyRepository.findOne(id);
    }

    @Override
    public Map<String, Object> slicedQuery(ProofingApplyQuery query) {
        return proofingApplyMapper.slicedQuery(query);
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @Override
    protected String saveBizAndApprovalData() {
        super.saveBizAndApprovalData();
        //从vo类获得两个实体类的属性值
        ProofingApply proofingApply = getBizEntity(ProofingApply.class);
        if (proofingApply.isNew()) {
            proofingApply.setStatusId(BizBillStatus.APPLYING.getId());
        } else {
            proofingApply = (ProofingApply) commonDomainService.loadAndFillinProperties(proofingApply);
        }
        String id = UUID.randomUUID().toString().replace("-", "");
        proofingApply.setProofingApplyId(id);
        proofingApply = proofingApplyRepository.save(proofingApply);

        return proofingApply.getId();
    }


    @Override
    protected Map<String, Object> getProcessBizParams(String bizId) {
        // 返回业务数据给流程实例，
        return ClassHelper.toMap(proofingApplyRepository.getOne(bizId));
    }

    @Override
    protected void onEnd(DelegateExecution delegateExecution) {
        super.onEnd(delegateExecution);
        String bizId = delegateExecution.getProcessBusinessKey();
        BizBillStatus status = approvePassed() ? BizBillStatus.COMPLETED : BizBillStatus.ABORTED;
        ProofingApply proofingApply = proofingApplyRepository.findOne(bizId);
        proofingApply.setStatusId(status.getId());
        proofingApplyRepository.save(proofingApply);
    }

    @Override
    protected void onAbortProcessInstance(DelegateExecution delegateExecution) {
        super.onAbortProcessInstance(delegateExecution);
        String bizId = delegateExecution.getProcessBusinessKey();
        ProofingApply proofingApply = proofingApplyRepository.findOne(bizId);
        proofingApply.setStatusId(BizBillStatus.ABORTED.getId());
        proofingApplyRepository.save(proofingApply);
    }

    /**
     * @param delegateTask
     * @param destActivityId 回退到的目标节点id
     */
    @Override
    protected void onBack(DelegateTask delegateTask, String destActivityId) {
        super.onBack(delegateTask, destActivityId);
        if ("Apply".equalsIgnoreCase(destActivityId)) {
            String bizId = delegateTask.getExecution().getProcessBusinessKey();
            ProofingApply proofingApply = proofingApplyRepository.findOne(bizId);
            proofingApply.setStatusId(BizBillStatus.APPLYING.getId());
            proofingApplyRepository.save(proofingApply);
        }
    }

    @Override
    public List<ProofingApply> getProofingApplyList() {
        return proofingApplyRepository.findAll();
    }

    @Override
    public ProofingApplyAndLookedVo getProofingApplyByProofingApplyNo(String proofingApplyNo) {
        ProofingApply proofingApply = proofingApplyRepository.findByProofingApplyNo(proofingApplyNo);
        ProofingApplyAndLookedVo proofingApplyAndLookedVo = this.getProofingApplyAndLookedVoByPAId(proofingApply.getId());
        ProductPublishedConf productPublishedConf = productPublishedConfRepository.getProductPublishedConfByProductId(proofingApply.getProductId());

        if(productPublishedConf!=null){
            BeanUtils.copyProperties(productPublishedConf,proofingApplyAndLookedVo);
        }
        return proofingApplyAndLookedVo;
    }


    @Override
    public ProofingApplyAndLookedVo getProofingApplyAndLookedVoByPAId(String id) {
        ProofingApplyAndLookedVo proofingApplyAndLookedVo = new ProofingApplyAndLookedVo();
        ProofingApply proofingApply = this.loadProofingApplyById(id);
        ProductLooked productLooked =new ProductLooked();
        productLooked.setProductId(proofingApply.getProductId());
        ProductLooked newProductLooked = productLookedApplication.getProductLookedByEntity(productLooked);
        Product product = productRepository.findOne(proofingApply.getProductId());
        ProductCategory productCategory = productCategoryApplication.getProductCategoryById(product.getProductCategoryId());
        BeanUtils.copyProperties(proofingApply,proofingApplyAndLookedVo);
        BeanUtils.copyProperties(newProductLooked,proofingApplyAndLookedVo);
        proofingApplyAndLookedVo.setProductCategoryName(productCategory.getProductCategoryName());
        return proofingApplyAndLookedVo;
    }
}
