package com.huigou.topsun.sap.componentSupply.application.impl;

import cn.hutool.core.bean.BeanUtil;
import com.huigou.cache.DictUtil;
import com.huigou.context.Operator;
import com.huigou.context.OrgUnit;
import com.huigou.context.ThreadLocalUtil;
import com.huigou.data.query.model.QueryDescriptor;
import com.huigou.data.query.model.QueryModel;
import com.huigou.topsun.common.CommonUtils;
import com.huigou.topsun.sap.componentSupply.application.ComponentSupplyApplication;
import com.huigou.topsun.sap.componentSupply.application.ComponentSupplyItemApplication;
import com.huigou.topsun.sap.componentSupply.domain.ComponentSupply;
import com.huigou.topsun.sap.componentSupply.domain.ComponentSupplyItem;
import com.huigou.topsun.sap.componentSupply.domain.query.ComponentSupplyQueryRequest;
import com.huigou.topsun.sap.componentSupply.repository.ComponentSupplyItemRepository;
import com.huigou.topsun.sap.componentSupply.repository.ComponentSupplyRepository;

import com.huigou.topsun.sap.componentSupply.vo.ComponentSupplyItemVo;
import com.huigou.topsun.sap.componentSupply.vo.ComponentSupplyVo;
import com.huigou.uasp.bmp.common.BizBillStatus;
import com.huigou.uasp.bmp.operator.OperatorApplication;
import com.huigou.uasp.bpm.FlowBroker;
import com.huigou.uasp.bpm.ProcessAction;
import com.huigou.uasp.bpm.ProcessStartModel;
import com.huigou.uasp.bpm.engine.application.WorkflowApplication;
import com.huigou.util.*;
import freemarker.template.Template;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Auther: Lxh
 * @Date: 2024/06/03/11:35
 * @Description:
 */
@Service("componentSupplyApplication")
public class ComponentSupplyApplicationImpl extends FlowBroker implements ComponentSupplyApplication {
    @Autowired
    private ComponentSupplyRepository componentSupplyRepository;
    @Autowired
    private ComponentSupplyItemRepository componentSupplyItemRepository;
    @Autowired
    private ComponentSupplyItemApplication componentSupplyItemApplication;
    @Autowired
    private WorkflowApplication workflowApplication;
    @Autowired
    private OperatorApplication operatorApplication;


    @Override
    public Map<String, Object> getComponentSupplyList(ComponentSupplyQueryRequest queryRequest) {
        QueryDescriptor queryDescriptor = this.sqlExecutorDao.getQuery(QUERY_XML_FILE_PATH, "componentSupply");
        QueryModel queryModel = this.sqlExecutorDao.getQueryModel(queryDescriptor, queryRequest);
        queryModel.putDictionary("status", DictUtil.getDictionary("bizBillStatus"));
        queryModel.addCriteria(" order by bill_code desc ");
        Map<String, Object> map = this.sqlExecutorDao.executeSlicedQuery(queryModel);
        return map;
    }

    @Override
    public ComponentSupply getComponentSupplyById(String id) {
        return componentSupplyRepository.findOne(id);
    }

    @Override
    public void deleteByIds(List<String> ids) {
        ids.forEach(id->{
             componentSupplyRepository.delete(id);
            List<ComponentSupplyItem> list=componentSupplyItemRepository.findByComponentSupplyId(id);
            for (ComponentSupplyItem componentSupplyItem:list){
                componentSupplyItemRepository.delete(componentSupplyItem);
            }
        });
    }

    @Override
    protected void onBeforeComplete(DelegateTask delegateTask) {
        super.onBeforeComplete(delegateTask);
        String bizId = delegateTask.getExecution().getProcessBusinessKey();
        if (this.isApplyProcUnit(delegateTask) && this.getApprovalParameter().isAdvanceProcessAction()) {
            ComponentSupply componentSupply = componentSupplyRepository.findOne(bizId);
            componentSupply.setStatusId(BizBillStatus.APPROVING.getId());
            componentSupplyRepository.save(componentSupply);
        }
    }

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

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

    @Override
    protected void onBack(DelegateTask delegateTask, String destActivityId) {
        super.onBack(delegateTask, destActivityId);
        if ("Apply".equalsIgnoreCase(destActivityId)) {
            String bizId = delegateTask.getExecution().getProcessBusinessKey();
            ComponentSupply componentSupply = componentSupplyRepository.findOne(bizId);
            componentSupply.setStatusId(BizBillStatus.APPLYING.getId());
            componentSupplyRepository.save(componentSupply);
        }
    }

    @Override
    protected Map<String, Object> getProcessBizParams(String bizId) {
        return ClassHelper.toMap(componentSupplyRepository.getOne(bizId));
    }

    @Override
    protected String saveBizAndApprovalData() {
        super.saveBizAndApprovalData();
        ComponentSupply componentSupply = getBizEntity(ComponentSupply.class);
        if (componentSupply.isNew()) {
            componentSupply.setStatusId(BizBillStatus.APPLYING.getId());
        } else {
            componentSupply = (ComponentSupply) commonDomainService.loadAndFillinProperties(componentSupply);
        }
        componentSupply = componentSupplyRepository.save(componentSupply);
        List<ComponentSupplyItem> items = getBizEntities(ComponentSupplyItem.class, "items");
        if (items.size()<1){
           throw new IllegalArgumentException("没有补充发料明细信息!");
        }
        componentSupplyItemApplication.saveComponentSupplyItems(componentSupply.getId(),items);
        //更新附件ID为主键ID
//        if (!(componentSupply.getId().equals(componentSupply.getAttbizId()))) {
//            List<Attachment> attachmentList = attachmentApplication.queryAttachments("sapRetirementInfo", componentSupply.getAttbizId());
//            for (Attachment attachment : attachmentList) {
//                attachment.setBizId(componentSupply.getId());
//                attachmentApplication.saveAttachment(attachment);
//            }
//        }
        return componentSupply.getId();
    }

    @Override
    public void saveComponentSupplyVo(ComponentSupplyVo componentSupplyVo){
        ComponentSupply ComponentSupply = new ComponentSupply();
        BeanUtil.copyProperties(componentSupplyVo,ComponentSupply);
        //初始化用户信息
        Operator operator = operatorApplication.createOperatorByPersonMemberId(componentSupplyVo.getApplyPerson());
        ComponentSupply.setDefaultValues(new OrgUnit(operator.getFullId(), operator.getFullName()));

        Map<String, Object> formData = BeanUtil.beanToMap(ComponentSupply);
        //保存明细
        List<ComponentSupplyItemVo> itemVos = componentSupplyVo.getItemVos();
        List<ComponentSupplyItem> ComponentSupplyItems = new ArrayList<>();
        if (!CollectionUtils.isEmpty(itemVos)){
            ComponentSupplyItems= itemVos
                    .stream()
                    .map(itemVo -> {
                        ComponentSupplyItem ComponentSupplyItem = new ComponentSupplyItem();
                        BeanUtil.copyProperties(itemVo, ComponentSupplyItem);
                        return ComponentSupplyItem;
                    }).collect(Collectors.toList());
        formData.put("items", JSONUtil.toString(ComponentSupplyItems));
        //启动流程实例
        this.startProcessInstance(ComponentSupplyApplication.PROCESS_DEFINITION_KEY, formData);
        //ComponentSupply.setId(bizId);
        //this.ComponentSupplyRepository.save(ComponentSupply);
        }
    }

    public String startProcessInstance(String processDefinitionKey,Map<String, Object> formData){
        Map<String, Object> variables = new HashMap();
        SDO localSdo = this.buildSDO(formData);
        ThreadLocalUtil.putVariable(Constants.SDO, localSdo);
        variables.put("startModel", ProcessStartModel.MANUAL.getId());
        Operator operator = localSdo.getOperator();
        variables.put("executorFullId", operator.getFullId());
        variables.put("executorFullName", operator.getFullName());
        ThreadLocalUtil.putOperator(operator);
        ThreadLocalUtil.putVariable("client.ip", "127.0.0.1");
        ProcessInstance processInstance = this.workflowApplication.startProcessInstanceByKey(processDefinitionKey, variables);
        String businessKey = processInstance.getBusinessKey();
        return businessKey;
    }

    private SDO buildSDO(Map<String, Object> formData) {
        String createdById = (String) formData.get("applyPerson");
        Operator operator = operatorApplication.createOperatorByPersonMemberId(createdById);
        SDO localSdo = new SDO();
        // 将业务数据传递给工作流
        formData.forEach(localSdo::putProperty);
        // 将业务流程信息传递给工作流
        localSdo.putProperty("processAction", ProcessAction.SAVE);
        localSdo.putProperty("procUnitId", "Apply");
        localSdo.setOperator(operator);
        return localSdo;
    }


}
