package com.dji.sample.control.controller;

import com.dji.sample.control.model.enums.DroneAuthorityEnum;
import com.dji.sample.control.model.enums.RemoteDebugMethodEnum;
import com.dji.sample.control.model.param.*;
import com.dji.sample.control.service.IControlService;
import com.dji.sample.manage.model.enums.OperateRecordTypeEnum;
import com.dji.sample.manage.service.IOperateRecordService;
import com.dji.sdk.common.HttpResultResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

/**
 * @author sean
 * @version 1.2
 * @date 2022/7/29
 */
@RestController
@Slf4j
@RequestMapping("${url.control.prefix}${url.control.version}/devices")
public class DockController {

    @Autowired
    private IControlService controlService;

    @Autowired
    private IOperateRecordService operateRecordService;

    @PostMapping("/{sn}/jobs/{service_identifier}")
    public HttpResultResponse createControlJob(
            HttpServletRequest request,
            @PathVariable String sn,
                                               @PathVariable("service_identifier") String serviceIdentifier,
                                               @Valid @RequestBody(required = false) RemoteDebugParam param) {

        HttpResultResponse result = controlService.controlDockDebug(sn, RemoteDebugMethodEnum.find(serviceIdentifier), param);

        OperateRecordTypeEnum type = resolveDebugType(serviceIdentifier);
        operateRecordService.record(request, type, sn, param,
                type.getDescription() + " [" + serviceIdentifier + "]");

        return result;

    }

    @PostMapping("/{sn}/jobs/fly-to-point")
    public HttpResultResponse flyToPoint(HttpServletRequest request,@PathVariable String sn, @Valid @RequestBody FlyToPointParam param) {
        HttpResultResponse result = controlService.flyToPoint(sn, param);
        operateRecordService.record(request, OperateRecordTypeEnum.FLY_TO_POINT, sn, param);
        return result;
    }

    @DeleteMapping("/{sn}/jobs/fly-to-point")
    public HttpResultResponse flyToPointStop(HttpServletRequest request, @PathVariable String sn) {
        HttpResultResponse result = controlService.flyToPointStop(sn);
        operateRecordService.record(request, OperateRecordTypeEnum.FLY_TO_POINT_STOP, sn, null);
        return result;
    }

    @PostMapping("/{sn}/jobs/takeoff-to-point")
    public HttpResultResponse takeoffToPoint(HttpServletRequest request,@PathVariable String sn, @Valid @RequestBody TakeoffToPointParam param) {
        HttpResultResponse result = controlService.takeoffToPoint(sn, param);
        operateRecordService.record(request, OperateRecordTypeEnum.TAKEOFF_TO_POINT, sn, param);
        return result;
    }

    @PostMapping("/{sn}/authority/flight")
    public HttpResultResponse seizeFlightAuthority(HttpServletRequest request, @PathVariable String sn) {
        HttpResultResponse result = controlService.seizeAuthority(sn, DroneAuthorityEnum.FLIGHT, null);
        operateRecordService.record(request, OperateRecordTypeEnum.SEIZE_FLIGHT_AUTHORITY, sn, null);
        return result;
    }

    /** Pilot：申请云端控制授权（遥控器弹窗） */
    @PostMapping("/{sn}/authority/cloud-control")
    public HttpResultResponse requestCloudControlAuth(HttpServletRequest request, @PathVariable String sn) {
        HttpResultResponse result = controlService.requestCloudControlAuth(sn);
        operateRecordService.record(request, OperateRecordTypeEnum.SEIZE_FLIGHT_AUTHORITY, sn, null);
        return result;
    }

    /** Pilot：释放云端控制授权 */
    @DeleteMapping("/{sn}/authority/cloud-control")
    public HttpResultResponse releaseCloudControlAuth(HttpServletRequest request, @PathVariable String sn) {
        HttpResultResponse result = controlService.releaseCloudControlAuth(sn);
        operateRecordService.record(request, OperateRecordTypeEnum.SEIZE_FLIGHT_AUTHORITY, sn, null);
        return result;
    }

    @PostMapping("/{sn}/authority/payload")
    public HttpResultResponse seizePayloadAuthority(HttpServletRequest request,@PathVariable String sn, @Valid @RequestBody DronePayloadParam param) {
        HttpResultResponse result = controlService.seizeAuthority(sn, DroneAuthorityEnum.PAYLOAD, param);
        operateRecordService.record(request, OperateRecordTypeEnum.SEIZE_PAYLOAD_AUTHORITY, sn, param);
        return result;
    }

    @PostMapping("/{sn}/payload/commands")
    public HttpResultResponse payloadCommands(HttpServletRequest request,@PathVariable String sn, @Valid @RequestBody PayloadCommandsParam param) throws Exception {
        param.setSn(sn);
        HttpResultResponse result = controlService.payloadCommands(param);
        operateRecordService.record(request, OperateRecordTypeEnum.PAYLOAD_COMMANDS, sn, param);
        return result;
    }

    @PostMapping("/{sn}/jobs/rtkCalibration")
    public HttpResultResponse createControlJob(HttpServletRequest request,@PathVariable String sn,
                                               @Valid @RequestBody RtkCalibrationParam param) {
        HttpResultResponse result = controlService.rtkCalibration(sn, param);
        operateRecordService.record(request, OperateRecordTypeEnum.RTK_CALIBRATION, sn, param);
        return result;
    }

    private OperateRecordTypeEnum resolveDebugType(String serviceIdentifier) {
        if ("return_home".equalsIgnoreCase(serviceIdentifier)) {
            return OperateRecordTypeEnum.RETURN_HOME;
        }
        if ("return_home_cancel".equalsIgnoreCase(serviceIdentifier)) {
            return OperateRecordTypeEnum.RETURN_HOME_CANCEL;
        }
        return OperateRecordTypeEnum.DOCK_DEBUG;
    }

}
