package com.ho.flow.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ho.business.entity.Station;
import com.ho.business.vo.resp.DeviceRespVO;
import com.ho.common.tools.constant.CommonConstant;
import com.ho.common.tools.entity.OrderDept;
import com.ho.common.tools.exception.BaseResponseCode;
import com.ho.common.tools.exception.BusinessException;
import com.ho.common.tools.exception.DataResult;
import com.ho.common.tools.util.PageResult;
import com.ho.common.tools.util.PageUtils;
import com.ho.flow.entity.WorkOrder;
import com.ho.flow.entity.WorkOrderSub;
import com.ho.flow.feignclient.BusinessFeignClient;
import com.ho.flow.feignclient.UserFeignClient;
import com.ho.flow.mapper.WorkOrderMapper;
import com.ho.flow.mapper.WorkOrderSubMapper;
import com.ho.flow.service.EventService;
import com.ho.flow.service.WorkOrderPictureService;
import com.ho.flow.service.WorkOrderService;
import com.ho.flow.vo.Event;
import com.ho.flow.vo.req.workorder.WorkOrderAddReqVO;
import com.ho.flow.vo.req.workorder.WorkOrderPageReq;
import com.ho.flow.vo.req.workorder.WorkOrderUpdateReqVO;
import com.ho.flow.vo.resp.workorder.WorkOrderRespVO;
import com.ho.user.api.vo.req.OrderUserSelectReqVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description 工单业务
 * Author yule
 * Date 2023/2/4 12:46
 */
@Service
@Slf4j
public class WorkOrderServiceImpl implements WorkOrderService {

    @Autowired
    WorkOrderMapper workOrderMapper;

    @Autowired
    EventService eventService;

    @Autowired
    WorkOrderPictureService pictureService;

    @Autowired
    BusinessFeignClient businessFeignClient;

    //注入自身, 防止事务失效
    @Autowired
    WorkOrderService workOrderService;

    @Autowired
    WorkOrderSubMapper workOrderSubMapper;

    @Autowired
    UserFeignClient userFeignClient;

    @Override
    @Transactional
    public int add(WorkOrderAddReqVO vo) {
        //先对图片进行赋值(类型和工单业务id)
        //也可能没图片,所以入库前先判断
        if (vo.getPictureIds() != null && !vo.getPictureIds().isEmpty()) {
            pictureService.insertWorkOrderIdAndType(vo);
        }

        //对工单业务数据新增
        int i = workOrderMapper.insertSelective(vo);
        //新增子表数据
        addWorkOrderSub(vo);
        return i;
    }

    @Override
    public int delete(List<Long> ids) {
        int i = 0;
        if (!ids.isEmpty()) {
            i = workOrderMapper.deleteByIds(ids);
        }
        return i;
    }

    @Override
    public int update(WorkOrder vo) {
        int i = workOrderMapper.updateByPrimaryKeySelective(vo);
        if (vo.getEventId() == null){
            workOrderMapper.setEventNull(vo.getId());
        }
        return i;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateWorkOrder(WorkOrderUpdateReqVO vo) {
        //修改表单和图片
        pictureService.updatePicture(vo);
        //先删除子表信息在更新子表数据
        workOrderSubMapper.deleteByPid(vo.getId());
        //在新增
        WorkOrderAddReqVO addReqVO = new WorkOrderAddReqVO();
        BeanUtils.copyProperties(vo, addReqVO);
        addWorkOrderSub(addReqVO);
        //调用自己的
        if (vo.getProcessId() != null) {
            int i = workOrderService.update(vo);
        }
        return 0;
    }

    @Override
    public WorkOrderRespVO getOne(Long id) {
        if (id != null) {
            WorkOrder workOrder = workOrderMapper.selectByPrimaryKey(id);
            WorkOrderRespVO vo = new WorkOrderRespVO();
            BeanUtils.copyProperties(workOrder, vo);
            List<WorkOrderSub> workOrderSubs = workOrderSubMapper.selectByPid(vo.getId());
            //根据类型对子表进行分组
            Map<Integer, List<WorkOrderSub>> map = workOrderSubs.stream().collect(Collectors.groupingBy(WorkOrderSub::getType));
            //电站类型
            List<WorkOrderSub> stations = map.get(CommonConstant.WorkOrderPlanSubType.STATION);
            if (stations != null) {
                List<Integer> stationIds = stations.stream().map(s-> {
                    return s.getSrcId().intValue();
                }).collect(Collectors.toList());
                if (stationIds != null && !stationIds.isEmpty()) {
                    DataResult<List<Station>> stationDataResult = businessFeignClient.selectByStationIds(stationIds);
                    if (stationDataResult.getData() != null) {
                        List<Station> stationList = stationDataResult.getData();
                        vo.setStationList(stationList);
                    }
                }
            } else {
                vo.setStationList(new ArrayList<>());
            }
            //设备类型
            List<WorkOrderSub> devices = map.get(CommonConstant.WorkOrderPlanSubType.DEVICE);
            if (devices != null) {
                List<Integer> deviceIds = devices.stream().map(s-> {
                    return s.getSrcId().intValue();
                }).collect(Collectors.toList());
                if (deviceIds != null && !deviceIds.isEmpty()) {
                    DataResult<List<DeviceRespVO>> deviceDataResult = businessFeignClient.selectByDeviceIds(deviceIds);
                    if (deviceDataResult.getData() != null) {
                        List<DeviceRespVO> deviceList = deviceDataResult.getData();
                        vo.setDeviceList(deviceList);
                    }
                }
            } else {
                vo.setDeviceList(new ArrayList<>());
            }
            return vo;
        } else {
            throw new BusinessException(BaseResponseCode.WORK_ORDER_INPUT_ID);
        }
    }

    @Override
    public WorkOrderRespVO findByOrderId(String orderId) {
        WorkOrderRespVO workOrder = workOrderMapper.selectByOrderId(orderId);
        return workOrder;
    }

    @Override
    public WorkOrderRespVO findByOrderIdAndTitle(String orderId, String title) {
        WorkOrderRespVO workOrder = workOrderMapper.selectByOrderIdAndTitle(orderId, title);
        return workOrder;
    }

    @Override
    public WorkOrderRespVO findByProcInstId(String orderId) {
        WorkOrderRespVO workOrder = workOrderMapper.selectByProcessInstId(orderId);
        return workOrder;
    }

    @Override
    public WorkOrderRespVO findByProcInstIdAndTitle(String processInstanceId, String title) {
        WorkOrderRespVO workOrder = workOrderMapper.selectByProcessInstIdAndTitle(processInstanceId, title);
        return workOrder;
    }

    //工单列表
    @Override
    public List<WorkOrderRespVO> findList(WorkOrderPageReq vo) {
        List<WorkOrderRespVO> workOrders = workOrderMapper.selectByInfo(vo);
        return workOrders;
    }

    @Override
    public PageResult<WorkOrderRespVO> getPage(WorkOrderPageReq vo) {
        PageHelper.startPage(vo.getPageNum(), vo.getPageSize());
        List<WorkOrderRespVO> workOrders = workOrderMapper.selectByInfo(vo);
        for (WorkOrderRespVO workOrder : workOrders) {
            List<WorkOrderSub> workOrderSubs = workOrderSubMapper.selectByPid(workOrder.getId());
            //根据类型对子表进行分组
            Map<Integer, List<WorkOrderSub>> map = workOrderSubs.stream().collect(Collectors.groupingBy(WorkOrderSub::getType));
            //电站类型
            List<WorkOrderSub> stations = map.get(CommonConstant.WorkOrderPlanSubType.STATION);
            List<Integer> stationIds = stations.stream().map(s-> {
                return s.getSrcId().intValue();
            }).collect(Collectors.toList());
            if (stationIds != null && !stationIds.isEmpty()) {
                DataResult<List<Station>> stationDataResult = businessFeignClient.selectByStationIds(stationIds);
                if (stationDataResult.getData() != null) {
                    List<Station> stationList = stationDataResult.getData();
                    workOrder.setStationList(stationList);
                }

            }
            //设备类型
            List<WorkOrderSub> devices = map.get(CommonConstant.WorkOrderPlanSubType.DEVICE);
            List<Integer> deviceIds = stations.stream().map(s-> {
                return s.getSrcId().intValue();
            }).collect(Collectors.toList());
            if (deviceIds != null && !deviceIds.isEmpty()) {
                DataResult<List<DeviceRespVO>> deviceDataResult = businessFeignClient.selectByDeviceIds(deviceIds);
                if (deviceDataResult.getData() != null) {
                    List<DeviceRespVO> deviceList = deviceDataResult.getData();
                    workOrder.setDeviceList(deviceList);
                }
            }
        }
        PageResult pageResult = PageUtils.getPageResult(new PageInfo<>(workOrders));
        return pageResult;
    }

    @Override
    public List<OrderDept> selectOrderUser(Integer groupId, List<String> postCodes) {
        //根据postCodes 查询到人
        OrderUserSelectReqVo vo = new OrderUserSelectReqVo();
        vo.setGroupId(groupId);
        vo.setPostCodes(postCodes);
        DataResult<List<OrderDept>> listDataResult = userFeignClient.selectByPostCodeTree(vo);
        if (!listDataResult.isSuccess() || listDataResult.getData() == null || listDataResult.getData().isEmpty()) {
            //throw new BusinessException(BaseResponseCode.NO_QUALIFIED_PERSONNEL_IN_ALL_DEPARTMENTS);
            return new ArrayList<>();
        }
        List<OrderDept> data = listDataResult.getData();
        return data;
    }

    @Override
    public WorkOrderRespVO selectByProcessInstId(String processInstId) {
        if (processInstId != null) {
            WorkOrderRespVO vo = workOrderMapper.selectByProcessInstId(processInstId);
            List<WorkOrderSub> workOrderSubs = workOrderSubMapper.selectByPid(vo.getId());
            //根据类型对子表进行分组
            Map<Integer, List<WorkOrderSub>> map = workOrderSubs.stream().filter(s -> {
                return s.getSrcId() != null;
            }).collect(Collectors.groupingBy(WorkOrderSub::getType));
            //电站类型
            List<WorkOrderSub> stations = map.get(CommonConstant.WorkOrderPlanSubType.STATION);
            if (stations != null) {
                List<Integer> stationIds = stations.stream().map(s-> {
                    return s.getSrcId().intValue();
                }).collect(Collectors.toList());
                if (stationIds != null && !stationIds.isEmpty()) {
                    DataResult<List<Station>> stationDataResult = businessFeignClient.selectByStationIds(stationIds);
                    if (stationDataResult.getData() != null) {
                        List<Station> stationList = stationDataResult.getData();
                        vo.setStationList(stationList);
                    }
                }
            } else {
                vo.setStationList(new ArrayList<>());
            }
            //设备类型
            List<WorkOrderSub> devices = map.get(CommonConstant.WorkOrderPlanSubType.DEVICE);
            if (devices != null) {
                List<Long> deviceLongIds = devices.stream().filter(s->{
                   return s.getSrcId() != null ;
                }).map(s->{
                    return s.getSrcId();
                }).collect(Collectors.toList());
                List<Integer> deviceIds = deviceLongIds.stream().map(Long::intValue).collect(Collectors.toList());
                if (deviceIds != null && !deviceIds.isEmpty()) {
                    DataResult<List<DeviceRespVO>> deviceDataResult = businessFeignClient.selectByDeviceIds(deviceIds);
                    if (deviceDataResult.getData() != null) {
                        List<DeviceRespVO> deviceList = deviceDataResult.getData();
                        vo.setDeviceList(deviceList);
                    }
                }
            } else {
                vo.setDeviceList(new ArrayList<>());
            }
            //告警类型
            List<WorkOrderSub> events = map.get(CommonConstant.WorkOrderPlanSubType.EVENT);
            if (events != null) {
                List<Long> eventIds = events.stream().map(s->{
                    return s.getSrcId();
                }).collect(Collectors.toList());
                if (eventIds != null && !eventIds.isEmpty()) {
                   List<Event> eventList =  eventService.selectByIds(eventIds);
                    vo.setEventList(eventList);
                }
            } else {
                vo.setEventList(new ArrayList<>());
            }

            /*log.info("selectByProcessInstId vo.getEventId:{}", vo.getEventId());
            if (vo.getEventId() != null) {
                Event event = eventService.selectById(vo.getEventId());
                if (event != null) {
                    log.info("selectByProcessInstId event :{}", event);
                    vo.setDescription(event.getDescription());
                    Event result = eventService.selectByParams(event);
                    if (result != null) {
                        log.info("selectByProcessInstId result.getIsRecovery :{}", result.getIsRecovery());
                        vo.setFlag(result.getIsRecovery());
                    }
                }
            }*/
            //存什么值 就返回给你什么值
            //查询字典表中优先级的值
            /*DataResult<SysSubDict> result = userFeignClient.getDictById(vo.getPriority());
            if (result.getData() != null){
                vo.setPriority(Integer.valueOf(result.getData().getValue()));
            }*/
            return vo;
        } else {
            throw new BusinessException(BaseResponseCode.WORK_ORDER_INPUT_ID);
        }
    }

    @Override
    public Integer selectByStationId(Integer stationId) {
        Integer orderNums = workOrderMapper.selectByStationId(stationId);
        return orderNums;
    }

    private int addWorkOrderSub(WorkOrderAddReqVO vo) {
        //已经配置好的集合
        if (vo.getWorkOrderSubs() != null) {
            List<WorkOrderSub> workOrderSubs = vo.getWorkOrderSubs();
            for (WorkOrderSub workOrderSub : workOrderSubs) {
                workOrderSub.setPid(vo.getId());
            }
            if (!workOrderSubs.isEmpty()) {
                return workOrderSubMapper.insertBatch(vo.getWorkOrderSubs());
            }
        }
        //生成一个工单子表对象
        List<WorkOrderSub> list = new ArrayList<>();
        if (vo.getStationIds() != null) {
            if (!vo.getStationIds().isEmpty()) {
                List<Integer> stationIds = vo.getStationIds();
                for (Integer stationId : stationIds) {
                    WorkOrderSub workOrderSub = new WorkOrderSub();
                    workOrderSub.setPid(vo.getId());
                    workOrderSub.setSrcId(stationId.longValue());
                    workOrderSub.setType(CommonConstant.WorkOrderPlanSubType.STATION);
                    list.add(workOrderSub);
                }

            }
        }
        if (vo.getDeviceIds() != null) {
            if (!vo.getDeviceIds().isEmpty()) {
                List<Integer> deviceIds = vo.getDeviceIds();
                for (Integer deviceId : deviceIds) {
                    WorkOrderSub workOrderSub = new WorkOrderSub();
                    workOrderSub.setPid(vo.getId());
                    workOrderSub.setSrcId(deviceId.longValue());
                    workOrderSub.setType(CommonConstant.WorkOrderPlanSubType.DEVICE);
                    list.add(workOrderSub);
                }
            }
        }
        if (vo.getEventIds() != null) {
            if (!vo.getEventIds().isEmpty()) {
                List<Long> eventIds = vo.getEventIds();
                for (Long eventId : eventIds) {
                    WorkOrderSub workOrderSub = new WorkOrderSub();
                    workOrderSub.setPid(vo.getId());
                    workOrderSub.setSrcId(eventId);
                    workOrderSub.setType(CommonConstant.WorkOrderPlanSubType.EVENT);
                    list.add(workOrderSub);
                }
            }
        }
        //批量新增子表数据
        if (!list.isEmpty()) {
            return workOrderSubMapper.insertBatch(list);
        } else {
            return 0;
        }
    }
}

