package cn.iocoder.yudao.module.remote.service.robot;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.remote.api.path.dto.RemoteRobotDistanceInformationDTO;
import cn.iocoder.yudao.module.remote.api.path.dto.RemoteRobotWirelessSignalDTO;
import cn.iocoder.yudao.module.remote.api.robot.RemoteControllerProcessor;
import cn.iocoder.yudao.module.remote.api.webSocket.RequestProcessor;
import cn.iocoder.yudao.module.remote.config.ip.IpProperties;
import cn.iocoder.yudao.module.remote.constant.robot.RobotTaskChcheConstant;
import cn.iocoder.yudao.module.remote.controller.admin.robot.dto.Cockpit;
import cn.iocoder.yudao.module.remote.controller.admin.robot.dto.PositionMapRespDTO;
import cn.iocoder.yudao.module.remote.controller.admin.robot.dto.RemoteRobotChangeModeDTO;
import cn.iocoder.yudao.module.remote.controller.admin.robot.dto.RemoteRobotTaskDoneDTO;
import cn.iocoder.yudao.module.remote.controller.admin.robot.dto.RobotDistanceInformationDTO;
import cn.iocoder.yudao.module.remote.enums.robot.DirectionEnum;
import cn.iocoder.yudao.module.remote.util.IpUtils;
import cn.iocoder.yudao.module.remote.util.redis.RedisUtil;
import cn.iocoder.yudao.module.system.api.remote.RemoteRobotApi;
import cn.iocoder.yudao.module.system.api.remote.dto.RemoteRobotDTO;
import cn.iocoder.yudao.module.system.api.remote.dto.RemoteRobotStatusDTO;
import cn.iocoder.yudao.module.system.api.remote.dto.RemoteRobotTransferDTO;
import cn.iocoder.yudao.module.system.api.robot.dto.FloorZoneDTO;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.TASK_COMMONG_FAIL;

@Slf4j
@Service
public class RemoteRobotServiceImpl implements RemoteRobotService {

    @Resource
    private RemoteRobotApi remoteRobotApi;

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private RemoteControllerProcessor remoteControllerProcessor;

    @Autowired
    private IpProperties ipProperties;

    /**
     * 获取地图区域对应的机器人信息
     *
     * @param positionMapRespDTO
     * @return
     */
    @Override
    public List<RemoteRobotDTO> remoteGetAreaRobot(PositionMapRespDTO positionMapRespDTO) {
        return remoteRobotApi.remoteGetAreaRobot(positionMapRespDTO.getId());
    }

    /**
     * 一键急停or一键恢复地图上所有AGV
     *
     * @param id
     * @param type
     */
    @Override
    public void remoteEmergencyStopOrRecovery(Long id, Integer type) {
        CommonResult<Boolean> result = remoteRobotApi.remoteEmergencyStopOrRecovery(id, type);
        if (!result.isSuccess()) {
            throw exception0(TASK_COMMONG_FAIL.getCode(), result.getMsg());
        }
    }

    /**
     * 获取机器人远遥模式/急停/协控状态
     *
     * @param request
     * @return
     */
    @Override
    public RemoteRobotStatusDTO getRemoteRobotStatus(HttpServletRequest request) {
        String ip = IpUtils.getIp(request);
        return remoteRobotApi.getRemoteRobotStatus(ip);
    }

    /**
     * 暂停机器人
     *
     * @param robotNo
     * @return
     */
    @Override
    public void robotStop(String robotNo) {
        CommonResult<Boolean> result = remoteRobotApi.robotStop(robotNo);
        if (!result.isSuccess()) {
            throw exception0(TASK_COMMONG_FAIL.getCode(), result.getMsg());
        }
    }

    /**
     * 恢复车辆
     *
     * @param robotNo
     */
    @Override
    public void recovery(String robotNo) {
        CommonResult<Boolean> result = remoteRobotApi.recovery(robotNo);
        if (!result.isSuccess()) {
            throw exception0(TASK_COMMONG_FAIL.getCode(), result.getMsg());
        }
    }

    /**
     * 切换远遥模式
     *
     * @param data
     * @return
     */
    @Override
    public void robotChangeMode(RemoteRobotChangeModeDTO data, HttpServletRequest request) {
        String ip = IpUtils.getIp(request);
        Cockpit cockpit = ipProperties.getCockpitByIp(ip);
        CommonResult<RemoteRobotTransferDTO> result = remoteRobotApi.robotChangeMode(data.getRemoteMode(), ip, data.getRobotNo(),cockpit.getControllerPort(),cockpit.getControllerIp());
        if (!result.isSuccess()) {
            throw exception0(TASK_COMMONG_FAIL.getCode(), result.getMsg());
        }
        //非自动模式
        if (0!= data.getRemoteMode()) {
            remoteControllerProcessor.addCache(result.getData(),ip);
        }else {
            remoteControllerProcessor.remoteCache(result.getData(),ip);
        }
    }

    @Override
    public Object getPositionMapList() {
        return remoteRobotApi.getRemotePositionMapList();
    }

    /**
     * 断开连接
     *
     * @param request
     */
    @Override
    public void remoteDisconnect(HttpServletRequest request) {
        String ip = IpUtils.getIp(request);
        CommonResult<RemoteRobotTransferDTO> result = remoteRobotApi.remoteDisconnect(ip);
        if (!result.isSuccess()) {
            throw exception0(TASK_COMMONG_FAIL.getCode(), result.getMsg());
        }

        if (ObjectUtil.isEmpty(result.getData())) {
            log.info("断开连接, 未查到远遥绑定的信息 :{}",ip);
            return;
        }

        remoteControllerProcessor.remoteCache(result.getData(),ip);
    }

    /**
     * 任务完成/取货完成
     *
     * @param remoteRobotTaskDoneDTO
     * @param request
     */
    @Override
    public void remoteTaskDone(RemoteRobotTaskDoneDTO remoteRobotTaskDoneDTO, HttpServletRequest request) {
        String ip = IpUtils.getIp(request);
        CommonResult<Boolean> result = remoteRobotApi.remoteTaskDone(ip, remoteRobotTaskDoneDTO.getMode());
        if (!result.isSuccess()) {
            throw exception0(TASK_COMMONG_FAIL.getCode(), result.getMsg());
        }
    }

    /**
     * 推送导航信息给前端
     *
     * @param data
     */
    @Override
    public void remoteDistanceInformation(RemoteRobotDistanceInformationDTO data) {
        TenantContextHolder.setTenantId(1L);
        String mac = (String) redisUtil.get(RobotTaskChcheConstant.ROBOT_GET_MAC_BY_NO + data.getRobotNo());
        if (ObjectUtil.isEmpty(mac)) {
            mac = remoteRobotApi.getMacByRobotNo(data.getRobotNo());
        }
        String floorAreaKey = RobotTaskChcheConstant.ROBOT_FLOOR_AREA + mac;
        Object o = redisUtil.get(floorAreaKey);
        if (ObjectUtil.isEmpty(o)) {
            log.info("找不到对应的车辆位置信息 :{}, 车辆编号:{}", floorAreaKey, data.getRobotNo());
            return;
        }
        FloorZoneDTO floorZone = JSON.parseObject((String) o, FloorZoneDTO.class);
        String msg = getDistanceInformationMsg(data);
        RobotDistanceInformationDTO build =
                RobotDistanceInformationDTO.builder().linearSpeed(floorZone.getLinearSpeed()).robotNo(data.getRobotNo())
                        .endDistance(data.getEndDistance()).nextRadian(data.getNextRadian()).message(msg).build();
        /*processor.handleRequest(floorZone.getFloor() + "_" + floorZone.getArea(),
                mac, JSONUtil.toJsonStr(build));*/
    }

    /**
     * 上报车辆信息信息
     * @param data
     */
    @Override
    public void sendRobotWirelessSignalStatus(RemoteRobotWirelessSignalDTO data) {
        TenantContextHolder.setTenantId(1L);
        String robotNo = (String) redisUtil.get(RobotTaskChcheConstant.ROBOT_GET_ROBOTNO_BY_MAC + data.getMac());
        if (ObjectUtil.isEmpty(robotNo)) {
            robotNo = remoteRobotApi.getRobotNoByMac(data.getMac());
        }
        log.info("车辆编号 :{}",robotNo);

    }

    /**
     * 组装
     *
     * @param data
     * @return
     */
    public String getDistanceInformationMsg(RemoteRobotDistanceInformationDTO data) {
        if (DirectionEnum.LEFT_FRONT.getType().equals(data.getCurrentDirection())) {
            return DirectionEnum.LEFT_FRONT.getMsg();
        } else if (DirectionEnum.RIGHT_FRONT.getType().equals(data.getCurrentDirection())) {
            return DirectionEnum.RIGHT_FRONT.getMsg();
        } else if (DirectionEnum.RIGHT_IN_FRONT.getType().equals(data.getCurrentDirection()) && DirectionEnum.END_POINT.getType().equals(data.getNextDirection())) {
            //直走到终点
            return DirectionEnum.RIGHT_IN_FRONT.getMsg() + data.getEndDistance() + "米到达终点";
        } else if (DirectionEnum.RIGHT_IN_FRONT.getType().equals(data.getCurrentDirection())) {
            //直走后拐弯
            return DirectionEnum.RIGHT_IN_FRONT.getMsg() + data.getNextDistance() + "米后 " + DirectionEnum.getMsgByType(data.getNextDirection());
        } else {
            return DirectionEnum.getMsgByType(data.getNextDirection());
        }
    }


}
