package cn.quantgroup.customer.service.impl;

import cn.quantgroup.customer.rest.param.thirdworkorder.WorkOrderParam;
import cn.quantgroup.customer.rest.vo.JsonResult;
import cn.quantgroup.customer.rest.vo.thirdworkorder.ThirdWorkOrderVo;
import cn.quantgroup.customer.service.IThirdWorkOrderService;
import cn.quantgroup.customer.service.IWorkOrderService;
import cn.quantgroup.third.customer.entity.LhpdsSysUser;
import cn.quantgroup.third.customer.entity.WorkflowProcessInstanceTaskAssignee;
import cn.quantgroup.third.customer.repo.LhpdsCustomer2Repo;
import cn.quantgroup.third.customer.repo.LhpdsSysUserRepo;
import cn.quantgroup.third.customer.repo.WorkflowProcessInstanceTaskAssigneeRepo;
import java.rmi.MarshalledObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

/**
 * @description:
 * @author:tao
 * @create: 2020-08-14 15:24
 */
@Slf4j
@Service
public class ThirdWorkOrderServiceImpl implements IThirdWorkOrderService {

    @Autowired
    private LhpdsCustomer2Repo customer2Repo;
    @Autowired
    private LhpdsSysUserRepo lhpdsSysUserRepo;
    @Autowired
    private WorkflowProcessInstanceTaskAssigneeRepo taskAssigneeRepo;
    @Autowired
    @Qualifier("entityManagerSecondary")
    private EntityManager entityManager;
    @Override
    public JsonResult<Map<String,Object>> queryWorkOrder(WorkOrderParam param) {
        long offset =  (param.getPageNo()-1) * param.getPageSize();

        StringBuffer sql = new StringBuffer();
        sql.append("SELECT "
            + "lc.id,lc.create_user createUser,assignee.assignee acceptUser ,lc.field10 orderId,lc.field17 problemDesc,"
            + "lwpi.process_instance_id processInstanceId,lwpi.priority priority,lwpi.global_state status,lwpi.process_definition_id processDefinitionId,lwpi.contact realContact "
            + "FROM lhpds_customer_2 lc  left join lhpds_workflow_process_instance lwpi on lc .id =lwpi.data_id "
            + "left join lhpds_workflow_process_instance_task_assignee assignee "
            + "on lwpi.process_instance_id = assignee.process_instance_id and assignee.task_name ='处理工单' and assignee.state =0 " );
        StringBuffer countSql = new StringBuffer();
        countSql.append("SELECT count(1)"
            + "FROM lhpds_customer_2 lc  left join lhpds_workflow_process_instance lwpi on lc .id =lwpi.data_id "
            + "left join lhpds_workflow_process_instance_task_assignee assignee "
            + "on lwpi.process_instance_id = assignee.process_instance_id and assignee.task_name ='处理工单' and assignee.state =0 " );

        StringBuffer conditionSql = new StringBuffer();
        if (param.getId()!=null){
            conditionSql.append("and lc.id="+param.getId()+" ");
        }
        if (StringUtils.isNotBlank(param.getOrderId())){
            conditionSql.append("and lc.field10='"+param.getOrderId()+"' ");
        }
        if (StringUtils.isNotBlank(param.getProcessInstanceId())){
            conditionSql.append("and lwpi.process_instance_id='"+param.getProcessInstanceId()+"' ");
        }
        if (StringUtils.isNotBlank(param.getPriority())){
            conditionSql.append("and lwpi.priority='"+param.getPriority()+"' ");
        }
        if (CollectionUtils.isNotEmpty(param.getStatusList())){
            StringBuffer statusSb  = new StringBuffer();
            for (String s : param.getStatusList()){
                statusSb.append(",'"+s+"'");
            }
            conditionSql.append("and lwpi.global_state in ("+statusSb.substring(1)+") ");
        }
        if (StringUtils.isNotBlank(param.getCreateUser())){
            conditionSql.append("and lc.create_user='"+param.getCreateUser()+"' ");
        }
        if (StringUtils.isNotBlank(param.getAcceptUser())){
            conditionSql.append("and assignee.assignee='"+param.getAcceptUser()+"' ");
        }

        if (StringUtils.isNotBlank(conditionSql.toString())){
            sql.append(" where "+conditionSql.toString().substring(3));
            countSql.append(" where "+conditionSql.toString().substring(3));
        }
        sql.append(" order by lc.id desc");
        sql.append( " limit "+offset+","+param.getPageSize());
        Query nativeQuery = entityManager.createNativeQuery(sql.toString());
        List<Object[]> result = nativeQuery.getResultList();
        Query countQuery = entityManager.createNativeQuery(countSql.toString());
        Object count = countQuery.getSingleResult();

        Set<String> userSet = new HashSet<>();
        Set<String> processInstanceIdSet = new HashSet<>();
        for (Object[] objects : result){
            if (objects[1] != null){
                userSet.add(objects[1].toString());
            }
            if (objects[2] != null){
                userSet.add(objects[2].toString());
            }
            if (objects[5] != null){
                processInstanceIdSet.add(objects[5].toString());
            }
        }

        //查询用户名称
        List<LhpdsSysUser> userList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(userSet)){
            userList = lhpdsSysUserRepo.getUserByAccountIdList(new ArrayList<>(userSet));
        }
        Map<String,String> userNameMap = userList.stream().collect(
            Collectors.toMap(LhpdsSysUser::getAccountId, LhpdsSysUser::getNickname,(key1,key2)->key2));

        //查询任务id
        List<WorkflowProcessInstanceTaskAssignee> taskAssigneeList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(processInstanceIdSet)){
            taskAssigneeList = taskAssigneeRepo.getByInstanceIds(new ArrayList<>(processInstanceIdSet));
        }
        Map<String,String> taskAssigneeMap = taskAssigneeList.stream().collect(
            Collectors.toMap(WorkflowProcessInstanceTaskAssignee::getProcessInstanceId,
                WorkflowProcessInstanceTaskAssignee::getTaskId,(key1,key2)->key2));


        List<ThirdWorkOrderVo> resultList = new ArrayList<>();
        for (Object[] objects : result){
            ThirdWorkOrderVo vo = new ThirdWorkOrderVo();
            vo.setId(Long.parseLong(objects[0].toString()));
            if (objects[1] != null){
                String name = userNameMap.get(objects[1].toString());
                name = StringUtils.isBlank(name) ? objects[1].toString():objects[1].toString()+"("+userNameMap.get(objects[1].toString())+")";
                vo.setCreateUser(name);
            }
            if (objects[2] != null){
                String name = userNameMap.get(objects[2].toString());
                name = StringUtils.isBlank(name) ? objects[2].toString():objects[2].toString()+"("+userNameMap.get(objects[2].toString())+")";
                vo.setAcceptUser(name);
            }
            if (objects[3] != null){
                vo.setOrderId(objects[3].toString());
            }
            if (objects[4] != null){
                vo.setProblemDesc(objects[4].toString());
            }
            if (objects[5] != null){
                vo.setProcessInstanceId(objects[5].toString());
            }
            if (objects[6] != null){
                vo.setPriority(objects[6].toString());
            }
            if (objects[7] != null){
                vo.setStatus(objects[7].toString());
            }
            if (objects[8] != null){
                vo.setProcessDefinitionId(objects[8].toString());
            }
            if (objects[9] != null){
                vo.setRealContact(objects[9].toString());
            }
            vo.setTaskId(taskAssigneeMap.get(vo.getProcessInstanceId()));
            resultList.add(vo);
        }

        Map<String,Object> map = new HashMap<>();
        map.put("total",Integer.parseInt(count.toString()));
        map.put("records",resultList);
        return JsonResult.buildSuccessResult("查询成功",map);
    }
}
