package com.multictrl.modules.business.dto.flight;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 下发任务
 *
 * @author Sdy
 * @since 1.0.0 2026/4/29
 */

/*
  下发任务
  若用户的云服务无法访问外网，需实现 配置更新 功能，
  下发可被云服务访问的 NTP 服务的 URL，以实现时钟同步，否则航线任务将无法正常执行。
 */
@Data
public class FlightTaskPrepare {
    //计划 ID
    private String flight_id;
    //开始执行时间
    // 任务开始执行时间毫秒时间戳。
    // 可选字段。当 task_type 为 0 或 1 时必填，为 2 时非必填。
    private Long execute_time;
    //任务类型
    //{"0":"立即任务","1":"定时任务","2":"条件任务"}
    //立即任务和定时任务均由execute_time指定执行时间；
    // 条件任务支持ready_conditions字段指定任务就绪条件，设
    // 备可在指定时间段内满足就绪条件后即可执行；
    // 立即任务媒体上传优先级最高，定时任务和条件任务媒体上传优先级相同
    private Integer task_type;
    //航线文件对象
    private FileInfo file;
    //任务就绪条件
    //可选字段。
    // 条件任务（即 task_type 为2）时必填，其他类型任务会忽略该字段。
    // 下发条件任务后，设备会定频检查 ready_conditions 是否全部满足，
    // 若全部满足则会有 flighttask_ready 事件通知。
    // 且设备端接收 flighttask_execute 指令时，
    // 也会检查任务的 ready_conditions 是否已全部满足。
    private ReadyConditions ready_conditions;
    //任务执行条件
    //可选字段，用于在设备端增加任务执行的前置检查条件，存在任一条件不满足时会执行失败
    private ExecutableConditions executable_conditions;
    //航线断点信息
    // 可选字段，用于断点续飞，若指定该字段，航线任务会从字段指定的断点位置开始执行。
    private BreakPoint break_point;
    //返航高度
    //{"max":1500,"min":20,"step":"","unit_name":"米 / m"}
    private Integer rth_altitude;
    //返航高度模式
    //{"0":"智能高度","1":"设定高度"}
    /// 智能返航模式下，飞行器将自动规划最佳返航高度。
    /// 大疆机场当前不支持设置返航高度模式，只能选择'设定高度'模式。
    /// 当环境，光线不满足视觉系统要求时（譬如傍晚阳光直射、夜间弱光无光），
    /// 飞行器将使用您设定的返航高度进行直线返航
    private Integer rth_mode;
    //遥控器失控动作
    //{"0":"返航","1":"悬停","2":"降落"}
    //失控动作，当前固定传的值是 0，即返航。
    // 注意该枚举值定义跟飞控跟机场定义的不一致，机场端会进行转换。
    private Integer out_of_control_action;
    //航线失控动作
    //{"0":"继续执行航线任务","1":"退出航线任务，执行遥控器失控动作"}
    //保持跟 KMZ 文件一致
    private Integer exit_wayline_when_rc_lost;
    //航线精度类型
    //{"0":"GPS 任务","1":"高精度 RTK 任务"}
    //高精度 RTK 任务：飞行器起飞后会在空中等待 RTK 收敛后再执行任务，等待 RTK 收敛的过程中无法暂停任务。
    // 默认场景建议使用该模式。
    // GPS 任务：飞行器无需等待 RTK 收敛便可以直接开始执行。
    // 精度要求不高的任务或对起飞时效性要求较高的任务建议使用该模式。
    private Integer wayline_precision_type;
    //是否在模拟器中执行任务
    //可选字段，用于在室内进行模拟任务调试。
    //注意：进行模拟飞行前，请务必取下桨叶，以防舱盖关闭时夹断桨叶。
    private SimulateMission simulate_mission;
    //飞行安全预检查
    //{"0":"关闭","1":"开启"}
    //设置一键起飞和航线任务中的飞行安全是否预先检查。此字段为可选，默认为0，
    // 值为0表示关闭，1表示开启。
    // 飞行安全预先检查表示: 飞行器执行任务前，检查自身作业区文件是否与云端一致，
    // 如果不一致则拉取文件更新，如果一致则不处理
    private Integer flight_safety_advance_check;

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class BreakPoint {
        //断点序号
        @Schema(description = "断点序号")
        private Integer index;
        //断点状态
        //{"0":"在航段上","1":"在航点上"}
        @Schema(description = "断点状态 {0:在航段上,1:在航点上}")
        private Integer state;
        //当前航段进度
        //{"max":"1.0","min":"0"}
        @Schema(description = "当前航段进度 {max:1.0,min:0}")
        private Double progress;
        //航线 ID
        @Schema(description = "wayline_id 航线 ID")
        private Integer wayline_id;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class ExecutableConditions {
        //存储容量
        //可执行任务的机场或飞行器最低存储容量，机场或飞行器存储容量不满足 storage_capacity 时，任务执行失败。
        private Integer storage_capacity;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class FileInfo {
        //文件 URL
        private String url;
        //文件签名	文件内容 MD5 签名
        private String fingerprint;

    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class ReadyConditions {
        //电池容量
        //可执行任务的飞行器电池电量百分比阈值，任务开始执行时的飞行器电量必须大于 battery_capacity。
        private Integer battery_capacity;
        //任务可执行时段的开始时间
        //任务可执行时段起始时间毫秒时间戳，任务开始执行的时间必须大于 begin_time。
        private Long begin_time;
        //任务可执行时段的结束时间
        //任务可执行时段截止时间毫秒时间戳，任务开始执行的时间必须小于 end_time。
        private Long end_time;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class SimulateMission {
        //是否开启模拟器任务
        //{"0":"不开启","1":"开启"}
        //当次任务打开或关闭模拟器
        @Schema(description = "is_enable 是否开启模拟器任务 {0:不开启,1:开启}")
        private Integer is_enable;
        //纬度
        //{"max":"90.0","min":"-90.0"}
        @Schema(description = "机场纬度 {max:90.0,min:-90.0}")
        private Double latitude;
        //经度
        //{"max":"180.0","min":"-180.0"}
        @Schema(description = "机场经度 {max:180.0,min:-180.0}")
        private Double longitude;
        //高度
        //{"max":"9999.9","min":"-9999.9"unit_name":"米 / m"}
        @Schema(description = "机场海拔高度{max:9999.9,min:-9999.9unit_name:米/m}")
        private Double altitude;
    }
}
