package com.yeejoin.amos.boot.module.hygf.biz.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yeejoin.amos.boot.module.hygf.api.Enum.PowerStationNodeEnum;
import com.yeejoin.amos.boot.module.hygf.api.Enum.PowerStationProcessStateEnum;
import com.yeejoin.amos.boot.module.hygf.api.dto.PowerStationDto;
import com.yeejoin.amos.boot.module.hygf.api.dto.WorkDto;
import com.yeejoin.amos.boot.module.hygf.api.entity.DesignInformation;
import com.yeejoin.amos.boot.module.hygf.api.entity.PeasantHousehold;
import com.yeejoin.amos.boot.module.hygf.api.entity.PowerStation;
import com.yeejoin.amos.boot.module.hygf.api.fegin.IdxFeginService;
import com.yeejoin.amos.boot.module.hygf.api.mapper.DesignInformationMapper;
import com.yeejoin.amos.boot.module.hygf.api.mapper.PowerStationMapper;
import com.yeejoin.amos.boot.module.hygf.api.service.IPowerStationService;
import com.yeejoin.amos.boot.module.hygf.biz.feign.WorkflowFeignClient;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.amos.feign.privilege.model.RoleModel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.typroject.tyboot.core.foundation.exception.BaseException;
import org.typroject.tyboot.core.rdbms.annotation.Condition;
import org.typroject.tyboot.core.rdbms.annotation.Operator;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 服务实现类
 *
 * @author system_generator
 * @date 2023-07-15
 */
@Service
@Slf4j
public class PowerStationServiceImpl extends BaseService<PowerStationDto, PowerStation, PowerStationMapper> implements IPowerStationService {

    @Autowired
    IdxFeginService idxFeginService;

    @Autowired
    IPowerStationService powerStationService;
    @Autowired
    DesignInformationMapper designInformationMapper;
    @Autowired
    DesignInformationServiceImpl designInformationService;
    @Autowired
    PeasantHouseholdServiceImpl peasantHouseholdService;

    private static final String IDX_REQUEST_STATE="200";
    private static final String VERIFY_RESULT_YES="0";
    private static final String VERIFY_RESULT_NO="1";

    @Autowired
    WorkflowFeignClient workflowFeignClient;

    public Page<PowerStationDto> queryForPowerStationUserRoles(Page<PowerStationDto> page, String powerStationCode, String ownersName, AgencyUserModel userInfo){
        String serviceAgent = "";
        Map<Long, List<RoleModel>> orgRoles = userInfo.getOrgRoles();
        Collection<List<RoleModel>> roleModels = orgRoles.values();
        if(roleModels !=null){
            List<String> roleTypes = new ArrayList<>();
            Iterator<List<RoleModel>> iterator = roleModels.iterator();
            while (iterator.hasNext()){
                List<RoleModel> next = iterator.next();
                roleTypes.addAll(next.stream().map(RoleModel::getRoleType).collect(Collectors.toList()));
            }
            if(roleTypes.size()>0){
                serviceAgent = !roleTypes.contains("HYGFGLY") ?  roleTypes.contains("HYGFJXS") ? userInfo.getCompanys().get(0).getCompanyName() : null : null ;
            }
        }
        return this.queryForPowerStationPage(page,powerStationCode,ownersName,serviceAgent);
    }
    /**
     * 分页查询
     */
    public Page<PowerStationDto> queryForPowerStationPage(Page<PowerStationDto> page,@Condition(Operator.like) String powerStationCode,@Condition(Operator.like) String ownersName,String serviceAgent)   {
        return this.queryForPage(page, "rec_date", false,powerStationCode,ownersName,serviceAgent);
    }

    /**
     * 列表查询 示例
     */
    public List<PowerStationDto> queryForPowerStationList()   {
        return this.queryForList("" , false);
    }


    @Override
    @Transactional
    public boolean savePowerStation(PowerStation powerStation, boolean flag) {
        try{
            //流程节点code
            if (flag) {
                String flowTaskIdnext = this.getTaskNoAuth(powerStation.getProcessInstanceId());
                WorkDto workDto=this.getNodeInfoCode(flowTaskIdnext);
                powerStation.setNextProcessNode(workDto.getNextProcessNode());
                powerStation.setNodeRole(workDto.getNodeRole());
                powerStation.setNodeRouting(workDto.getNodeRouting());
            }
            return this.saveOrUpdate(powerStation);
        }catch (Exception e){
            throw new  BaseException("获取工作流节点失败！","400","获取工作流节点失败！");
        }
    }

    @Override
    public PowerStation getObjByNhId(String id, String state) {
        LambdaQueryWrapper<PowerStation> wrapper = new LambdaQueryWrapper<>();
        wrapper.ne(PowerStation::getProcessStatus, state);
        wrapper.eq(PowerStation::getPeasantHouseholdId, id);
        return this.baseMapper.selectOne(wrapper);
    }

    @Override
    @Transactional
    public String powerStationExamine(long pageId, String nodeCode, String stationId, String taskId, String planInstanceId, Map<String, Object> kv) {
        // 1. 业务相关数据落表
        PowerStation powerStation = this.baseMapper.selectById(stationId);
        PowerStationNodeEnum nodeByCode = PowerStationNodeEnum.getNodeByCode(nodeCode);
        boolean flag = true;
        if (PowerStationNodeEnum.设计上传图纸.getCode().equals(nodeCode)||PowerStationNodeEnum.经销商上传图纸.getCode().equals(nodeCode)) {
            this.updateSeve(powerStation.getPeasantHouseholdId(),kv);
        }  else {
            String result = String.valueOf(kv.get("approvalStatue"));
            if (VERIFY_RESULT_NO.equals(result)) {
                powerStation.setProcessStatus(PowerStationProcessStateEnum.不通过.getName());
            }
            PowerStationProcessStateEnum resultObj = PowerStationProcessStateEnum.getStateByResult(result);
            switch (nodeByCode) {
                case 设计审核:
                    powerStation.setTechnologyStatus(resultObj.getName());
                    break;
                case 投融审核:
                    powerStation.setDesignStatus(resultObj.getName());
                    break;
                case 法务审核:
                    powerStation.setBusinessStatus(resultObj.getName());
                    break;
                case 文件审核:
                    if (VERIFY_RESULT_YES.equals(result)) {
                        flag = false;
                        powerStation.setProcessStatus(PowerStationProcessStateEnum.完成.getName());
                    }
                    powerStation.setDrawingReview(resultObj.getName());
                    break;
                default:
                    break;
            }
        }

        // 2. 更新流程状态
        String code = null;
        try{
            // 3. 工作流执行
            FeignClientResult<String> submit = idxFeginService.submit(pageId, taskId, planInstanceId, null, null, null, kv);
            if (IDX_REQUEST_STATE.equals(String.valueOf(submit.getStatus()))) {
                code = submit.getResult();
                log.info("流程执行成功：{}", code);
                // 获取流程信息
                FeignClientResult<JSONObject> record = idxFeginService.getRecord(code);
                if (IDX_REQUEST_STATE.equals(String.valueOf(record.getStatus()))) {
                    JSONObject resultObj = record.getResult();
                    String flowTaskId = String.valueOf(resultObj.get("flowTaskId"));
                    powerStation.setFlowTaskId(flowTaskId);
                }
                powerStationService.savePowerStation(powerStation, flag);
                if(!flag){
                    //更新农户状态
                    String peasantHouseholdId = powerStation.getPeasantHouseholdId();
                    PeasantHousehold peasantHousehold = peasantHouseholdService.getBaseMapper().selectById(Long.valueOf(peasantHouseholdId));
                    peasantHousehold.setSurveyOrNot(3);
                    peasantHouseholdService.saveOrUpdate(peasantHousehold);
                }
            }
        }catch (Exception e){
            throw new  BaseException("获取工作流节点失败！","400","获取工作流节点失败！");

        }
        return code;
    }


    public WorkDto getNodeInfoCode(String flowTaskId){
        WorkDto workDto=null;
     try{
            FeignClientResult<JSONObject> jSONObject= workflowFeignClient.getNodeInfo(flowTaskId);
        if(IDX_REQUEST_STATE.equals(String.valueOf(jSONObject.getStatus()))){
            JSONObject js=jSONObject.getResult();
            if(js==null){
                throw new BaseException("获取工作流节点失败！","400","获取工作流节点失败！");
            }
            LinkedHashMap  taskInfo= js.get("taskInfo")!=null?(LinkedHashMap)js.get("taskInfo"):null;
            String nextProcessNode=taskInfo!=null?taskInfo.get("taskDefinitionKey").toString():null;
            List<LinkedHashMap>  executor= js.get("executor")!=null?( List<LinkedHashMap>)js.get("executor"):null;
            String nodeRole=null;
            if(!executor.isEmpty()){
                List<String> idList = executor.stream().map(e->e.get("groupId").toString()).collect(Collectors.toList());
                nodeRole=StringUtils.join(idList,",");
            }

            LinkedHashMap  extensionInfo= js.get("extensionInfo")!=null?(LinkedHashMap)js.get("extensionInfo"):null;
            String nodeRouting=extensionInfo!=null?extensionInfo.get("nodeRole").toString():null;

            workDto=new WorkDto(nodeRouting,  nodeRole,  nextProcessNode);
        }

        return  workDto;
    }catch (Exception e){
        e.printStackTrace();
        throw new  BaseException("获取工作流节点失败！","400","获取工作流节点失败！");

    }
}

    public String getTaskNoAuth(String processInstanceId){
        String flowTaskId=null;
     try{
            JSONObject jSONObject= workflowFeignClient.getTaskNoAuth(processInstanceId);
        if(IDX_REQUEST_STATE.equals(String.valueOf(jSONObject.get("code")))){
            LinkedHashMap jsd= jSONObject.get("data")!=null?(LinkedHashMap)jSONObject.get("data"):null;
            flowTaskId=jsd!=null?jsd.get("id").toString():null;
        }
        if(flowTaskId==null){
            throw new BaseException("获取工作流节点失败！","400","获取工作流节点失败！");
        }
        return  flowTaskId;
    }catch (Exception e){
         e.printStackTrace();
        throw new  BaseException("获取工作流节点失败！","400","获取工作流节点失败！");

    }
    }

   // 设计信息填充


public void updateSeve(String peasantHouseholdId, Map<String, Object> kv ){
    LambdaQueryWrapper<DesignInformation> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(DesignInformation::getPeasantHouseholdId, peasantHouseholdId);
    DesignInformation  designInformation=designInformationMapper.selectOne(wrapper);
    if(designInformation!=null){
        DesignInformation designInformationnew=this.mapToBean(kv,DesignInformation.class);
        designInformationnew.setTypicalDiagram(designInformation.getTypicalDiagram());
        designInformationnew.setPeasantHouseholdId(peasantHouseholdId);
        designInformationnew.setSequenceNbr(designInformation.getSequenceNbr());
        designInformationnew.setRecDate(designInformation.getRecDate());
        designInformationnew.setRecUserId(designInformation.getRecUserId());
        designInformationnew.setRecUserName(designInformation.getRecUserName());
        designInformationnew.setIsDelete(designInformation.getIsDelete());
        designInformationMapper.updateById(designInformationnew);

    }else{
        DesignInformation designInformationnew=this.mapToBean(kv,DesignInformation.class);
        designInformationnew.setTypicalDiagram((List<Object>)kv.get("typicalDiagram")) ;
        designInformationnew.setPeasantHouseholdId(peasantHouseholdId);
        designInformationMapper.insert(designInformationnew);

    }

}


 public  <T> T mapToBean(Map<String, Object> map, Class<T> clazz) {
     ObjectMapper objectMapper= new ObjectMapper();

        T bean =null;
        try {
            bean = clazz.newInstance();
            bean = objectMapper.convertValue(map,clazz);

        }catch (Exception e){
            throw new BaseException(" 数据转化异常！","400","数据转化异常！");
        }
        return bean;
    }


//    private CollectionToList(Collection<? extends E> c){
//        Object[] objects = c.toArray();
//    }

}