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

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yeejoin.amos.boot.module.hygf.api.Enum.HouseholdContractEnum;
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.Enum.TaskTypeStationEnum;
import com.yeejoin.amos.boot.module.hygf.api.dto.PowerStationDto;
import com.yeejoin.amos.boot.module.hygf.api.dto.UserUnitInformationDto;
import com.yeejoin.amos.boot.module.hygf.api.dto.WorkDto;
import com.yeejoin.amos.boot.module.hygf.api.entity.*;
import com.yeejoin.amos.boot.module.hygf.api.fegin.IdxFeginService;
import com.yeejoin.amos.boot.module.hygf.api.mapper.*;
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.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.typroject.tyboot.component.emq.EmqKeeper;
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.*;
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;
    @Autowired
    HouseholdContractServiceImpl householdContractServiceImpl;
    @Autowired
    PersonnelBusinessMapper personnelBusinessMapper;
    @Autowired
    ToDoTasksMapper toDoTasksMapper;
    @Autowired
    protected EmqKeeper emqKeeper;
    @Autowired
    ToDoTasksServiceImpl toDoTasksServiceImpl;
    @Autowired
    UserMessageMapper userMessageMapper;
    public Page<PowerStationDto> queryForPowerStationUserRoles(Page<PowerStationDto> page, String powerStationCode, String ownersName, AgencyUserModel userInfo){
        String serviceAgent =null;
//        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 ;
//            }
//        }

        //获取用户所在经销商单位
        UserUnitInformationDto userUnitInformationDto=personnelBusinessMapper.getUserUnitInformationDto(userInfo.getUserId());

        if(userUnitInformationDto!=null&&userUnitInformationDto.getAmosDealerName()!=null){
            serviceAgent=userUnitInformationDto.getAmosDealerName();
        }

        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,String name,String meg) {
        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());
            }
            Boolean fl= this.saveOrUpdate(powerStation);

            PowerStationNodeEnum powerStationNodeEnum=   PowerStationNodeEnum.getNodeByCode(powerStation.getNextProcessNode());

            if (flag){

                ToDoTasks toDoTasks=null;
                if(PowerStationNodeEnum.经销商上传图纸.getCode().equals(powerStationNodeEnum.getCode())||PowerStationNodeEnum.经销商审核.getCode().equals(powerStationNodeEnum.getCode())){
                    //获取经销商orgcode
                    PeasantHousehold peasantHouseholdd=   peasantHouseholdService.getById(powerStation.getPeasantHouseholdId());
                     toDoTasks=  new ToDoTasks (  TaskTypeStationEnum.电站审核.getCode(),  powerStation.getSequenceNbr(),   "用户"+name+"电站勘察待"+powerStationNodeEnum.getName(),peasantHouseholdd.getDeveloperCode());
                    if(PowerStationNodeEnum.经销商审核.getCode().equals(powerStationNodeEnum.getCode())){
                        toDoTasksServiceImpl.addToDoTasksByUserId(peasantHouseholdd.getDeveloperUserId(),toDoTasks,meg);
                    }else{
                        toDoTasksServiceImpl.addToDoTasksByRole(powerStation.getNodeRole(),toDoTasks,meg);
                    }
                }else{
                    toDoTasks=  new ToDoTasks (  TaskTypeStationEnum.电站审核.getCode(),  powerStation.getSequenceNbr(),   "用户"+name+"电站勘察待"+powerStationNodeEnum.getName(),null);
                    toDoTasksServiceImpl.addToDoTasksByRole(powerStation.getNodeRole(),toDoTasks,meg);
                }
            }else{
                LambdaQueryWrapper<ToDoTasks> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(ToDoTasks::getType, TaskTypeStationEnum.电站审核.getCode());
                wrapper.eq(ToDoTasks::getState, "待办");
                wrapper.eq(ToDoTasks::getBusinessId, powerStation.getSequenceNbr());
                ToDoTasks doTasks= toDoTasksMapper.selectOne(wrapper);
                if(doTasks!=null){
                    doTasks.setState("已办");
                    doTasks.setCompleteTime(new Date());

                    toDoTasksMapper.updateById(doTasks);
                    emqKeeper.getMqttClient().publish("TASK_MESSAGE" ,JSON.toJSONString(doTasks).getBytes(), 2 ,false);

                    UserMessage userMessage=  new UserMessage( doTasks.getType(),  doTasks.getBusinessId(),  doTasks.getAmosUserId(),  new Date(),  doTasks.getTaskName()+"已完成."+meg,  doTasks.getAmosOrgCode());
                    userMessageMapper.insert(userMessage);
                    emqKeeper.getMqttClient().publish("MY_MESSAGE" , JSON.toJSONString(userMessage).getBytes(), 2 ,false);

                }
            }

            return fl;
        }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) {
        String meg="";
        // 1. 业务相关数据落表
        PowerStation powerStation = this.baseMapper.selectById(stationId);
        PowerStationNodeEnum nodeByCode = PowerStationNodeEnum.getNodeByCode(nodeCode);
        String result = String.valueOf(kv.get("approvalStatue"));
        boolean flag = true;
        if (PowerStationNodeEnum.设计上传图纸.getCode().equals(nodeCode)||PowerStationNodeEnum.经销商上传图纸.getCode().equals(nodeCode)) {
            this.updateSeve(powerStation.getPeasantHouseholdId(),kv);
        }  else {

            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());

                    if (VERIFY_RESULT_YES.equals(result)) {
                        LambdaUpdateWrapper<HouseholdContract> lambdaUw = new LambdaUpdateWrapper<>();
                        lambdaUw.eq(HouseholdContract::getPeasantHouseholdId, powerStation.getPeasantHouseholdId());
                        lambdaUw.set(HouseholdContract::getSurveyStatus, HouseholdContractEnum.勘察状态_已勘察.getCode());
                        householdContractServiceImpl.update(lambdaUw);
                    }

                    break;
                case 文件审核:
                    if (VERIFY_RESULT_YES.equals(result)) {
                        flag = false;
                        powerStation.setProcessStatus(PowerStationProcessStateEnum.完成.getName());
                    }
                    powerStation.setDrawingReview(resultObj.getName());
                    break;
                default:
                    break;
            }
        }
        meg="任务明细："+nodeByCode+(VERIFY_RESULT_YES.equals(result)?"通过":"不通过");
        // 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,powerStation.getOwnersName(),meg);
                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();
//    }

}