package com.multictrl.modules.business.controller;

import com.multictrl.common.annotation.ApiOrder;
import com.multictrl.common.annotation.LogOperation;
import com.multictrl.common.utils.Result;
import com.multictrl.common.validator.ValidatorUtils;
import com.multictrl.modules.business.dto.command.DrcStick;
import com.multictrl.modules.business.dto.command.FlyToPoint;
import com.multictrl.modules.business.dto.command.TakeoffToPoint;
import com.multictrl.modules.business.service.CommandService;
import com.multictrl.modules.business.service.DJIBaseService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.*;

/**
 * 指令飞行
 *
 * @author Sdy
 * @since 1.0.0 2026/4/27
 */
@RestController
@RequestMapping("business/command")
@Tag(name = "指令飞行", description = "指令飞行功能的开放目的是解决无人机与机场在远程控制过程中，无法即时性操作的限制。" +
        "在实际应用场景中，飞行器可以从空闲状态响应或暂停正在执行的航线任务。开发者通过手动方式继续控制设备或负载。" +
        "通过指令飞行功能，开发者可以获得安全可靠的飞行器控制、高实时性的指令下发与直播画面传输、osd 信息上报以及对负载的控制能力。")
@ApiOrder(6)
@RequiredArgsConstructor
public class CommandController {
    private final CommandService commandService;
    private final DJIBaseService djiBaseService;

    @LogOperation("一键起飞")
    @PostMapping("/takeoffToPoint/{dockSn}")
    @Operation(summary = "一键起飞")
    @RequiresPermissions("bus:command:takeoff")
    public Result<Object> takeoffToPoint(@PathVariable String dockSn, @RequestBody TakeoffToPoint takeoffToPoint) {
        ValidatorUtils.validateEntity(takeoffToPoint);

        return new Result<>().ok(commandService.takeoffToPoint(dockSn, takeoffToPoint));
    }

    @LogOperation("起飞到备降点100米处悬停")
    @PostMapping("/takeOffToAlternateLandPoint/{dockSn}")
    @Operation(summary = "起飞到备降点100米处悬停")
    @RequiresPermissions("bus:command:takeoff")
    public Result<Object> takeOffToAlternateLandPoint(@PathVariable String dockSn) {

        return new Result<>().ok(commandService.takeOffToAlternateLandPoint(dockSn));
    }

    @PostMapping("/flyToPoint/{dockSn}")
    @LogOperation("飞向目标点")
    @Operation(summary = "飞向目标点")
    @Schema(description = "特别说明：飞行器有最低飞行高度(20m)安全保障机制，如果飞行器相对起飞点高度低于20m，会先上升到20m")
    @RequiresPermissions("bus:command:flyToPoint")
    public Result<Object> flyToPoint(@PathVariable String dockSn, @RequestBody FlyToPoint flyToPoint) {
        ValidatorUtils.validateEntity(flyToPoint);

        return new Result<>().ok(commandService.flyToPoint(dockSn, flyToPoint));
    }

    @PostMapping("/flyToPointStop/{dockSn}")
    @LogOperation("结束飞向目标点")
    @Operation(summary = "结束飞向目标点")
    @RequiresPermissions("bus:command:flyToPointStop")
    public Result<Object> flyToPointStop(@PathVariable String dockSn) {

        return new Result<>().ok(djiBaseService.executeAndReturnResult(dockSn, "fly_to_point_stop"));
    }

    @PostMapping("/flyToPointUpdate/{dockSn}")
    @LogOperation("飞向目标点更新")
    @Operation(summary = "飞向目标点更新")
    @Schema(description = "「一键起飞」或「flyto 飞向目标点」的过程中，可以通过该命令快速更新目标点")
    @RequiresPermissions("bus:command:flyToPointUpdate")
    public Result<Object> flyToPointUpdate(@PathVariable String dockSn, @RequestBody FlyToPoint flyToPoint) {
        ValidatorUtils.validateEntity(flyToPoint);

        return new Result<>().ok(commandService.flyToPointUpdate(dockSn, flyToPoint));
    }

    @PostMapping("/drcModeEnter/{dockSn}")
    @LogOperation("进入指令飞行控制模式")
    @Operation(summary = "进入指令飞行控制模式")
    @Schema(description = "如果想使用虚拟摇杆控制飞机，必须进入该模式。在进入指令飞行控制模式后，必须发送心跳包，否则飞机会自动退出指令飞行控制模式,1分钟内没心跳退出")
    @RequiresPermissions("bus:command:drcModeEnter")
    public Result<Object> drcModeEnter(@PathVariable String dockSn) {

        return new Result<>().ok(commandService.drcModeEnter(dockSn));
    }

    @PostMapping("/drcModeExit/{dockSn}")
    @LogOperation("退出指令飞行控制模式")
    @Operation(summary = "退出指令飞行控制模式")
    @RequiresPermissions("bus:command:drcModeExit")
    public Result<Object> drcModeExit(@PathVariable String dockSn) {

        return new Result<>().ok(commandService.drcModeExit(dockSn));
    }

    @PostMapping("/drcStickControl/{dockSn}")
//    @LogOperation("DRC-杆量控制")
    @Operation(summary = "DRC-杆量控制")
    @Schema(description = "建立DRC链路之后，可通过“DRC-杆量控制”指令控制飞行器和云台姿态。发送频率需要保持5-10hz（一秒5~10次），才能比较精准地控制飞行器的运动。本协议无回包机制。")
    @RequiresPermissions("bus:command:drcStickControl")
    public void drcStickControl(@PathVariable String dockSn, @RequestBody DrcStick drcStick) {
        ValidatorUtils.validateEntity(drcStick);

        commandService.drcStickControl(dockSn, drcStick);
//        return new Result<>();
    }

    @PostMapping("/drcEmergencyStop/{dockSn}")
    @LogOperation("DRC-飞行器急停")
    @Operation(summary = "DRC-飞行器急停")
    @RequiresPermissions("bus:command:drcEmergencyStop")
    public Result<Object> drcEmergencyStop(@PathVariable String dockSn) {

        return new Result<>().ok(djiBaseService.executeDrcAndReturnResult(dockSn, "drone_emergency_stop"));
    }
}
