<template>
  <div class="taskPanel">
    <div class="taskPanel-info">
      <div class="taskPanel-info-title">
        <span v-if="type === 'CREATE'">
          新建机场任务
        </span>
        <span v-else-if="type === 'DETAIL'">
          机场任务详情
        </span>
        <span v-else-if="type === 'COPY'">
          复制机场任务
        </span>
      </div>
      <a-spin :spinning="state.loading">
        <div class="taskPanel-info-content">
          <a-form ref="formRef" layout="vertical" :hideRequiredMark="true" :model="state.formModel">
            <!-- 任务名称 -->
            <a-form-item label='任务名称' name="name" :rules="[{ required: true, message: '任务名称不能为空', whitespace: true }]">
              <a-input placeholder="请输入任务名称" :maxlength="20" v-model:value="state.formModel.name" />
            </a-form-item>
            <!-- 执行航线 -->
            <a-form-item label="执行航线" name="file_id" :rules="[{ required: true, message: '执行航线不能为空' }]">
              <a-button type="primary" @click="handleClickSelectWayline" v-if="type !== 'DETAIL'">
                <PlusOutlined />
                选择航线
              </a-button>
              <div v-if="waylineInfo">
                <div class="wayline-panel" :style="{ marginTop: type === 'DETAIL' ? '0' : '10px' }">
                  <div class="wayline-panel-title">
                    <div class="wayline-panel-title-left">
                      {{ waylineInfo.name }}
                    </div>
                    <div class="wayline-panel-title-right">
                      <UserOutlined />
                      {{ waylineInfo.user_name }}
                    </div>
                  </div>
                  <div style="margin-bottom: 5px;">
                    <img :src="aircraftSrc">
                    {{ waylineInfo.drone_model }}
                  </div>
                  <div style="margin-bottom: 5px;">
                    <CameraFilled />
                    {{ waylineInfo.payload_model }}
                  </div>
                  <div>
                    更新时间 {{ waylineInfo.update_time }}
                  </div>
                </div>
              </div>
            </a-form-item>
            <!-- 执行设备 -->
            <a-form-item label="执行设备" name="dock_sn" :rules="[{ required: true, message: '执行设备不能为空' }]">
              <a-button type="primary" @click="handleClickSelectDevice" v-if="type !== 'DETAIL'">
                <PlusOutlined />
                选择设备
              </a-button>
              <div v-if="deviceInfo">
                <div class="device-panel" :style="{ marginTop: type === 'DETAIL' ? '0' : '10px' }">
                  <div class="device-panel-cell">
                    <img :src="dockSrc">
                    <div>
                      {{ deviceInfo.name }}
                    </div>
                  </div>
                  <div class="device-panel-cell">
                    <img :src="aircraftSrc">
                    <div>
                      {{ deviceInfo.children.name }}
                    </div>
                  </div>
                </div>
              </div>
            </a-form-item>
            <!-- 任务精度 -->
            <a-form-item label="任务精度" name="wayline_precision_type">
              <a-radio-group button-style="solid" v-model:value="state.formModel.wayline_precision_type">
                <a-radio-button :value="1">
                  高精度RTK
                </a-radio-button>
                <a-radio-button :value="0">
                  GNSS
                </a-radio-button>
              </a-radio-group>
            </a-form-item>
            <!-- 任务策略 -->
            <a-form-item label="任务策略" name="task_type">
              <div style="white-space: nowrap;">
                <a-radio-group button-style="solid" v-model:value="state.formModel.task_type">
                  <a-radio-button :value="0">
                    立即
                  </a-radio-button>
                  <a-radio-button :value="1">
                    定时
                  </a-radio-button>
                  <a-radio-button :value="2">
                    循环
                  </a-radio-button>
                </a-radio-group>
              </div>
            </a-form-item>
            <template v-if="state.formModel.task_type === 1">
              <!-- 执行时间 -->
              <a-form-item label="执行时间" name="task_time" :rules="[{ required: true, message: '执行时间不能为空' }]">
                <a-date-picker style="width: 100%;" :show-time="{ format: 'HH:mm' }" format="YYYY-MM-DD HH:mm"
                  valueFormat="YYYY-MM-DD HH:mm"
                  :disabledDate="(current: any) => current < moment().subtract(1, 'days')" placeholder="请选择执行时间"
                  v-model:value="state.formModel.task_time" />
              </a-form-item>
            </template>
            <template v-if="state.formModel.task_type === 2">
              <!-- 执行日期 -->
              <a-form-item label="执行日期" name="task_days" :rules="[{ required: true, message: '执行日期不能为空' }]">
                <a-range-picker style="width: 100%;" valueFormat="YYYY-MM-DD"
                  :disabledDate="(current: any) => current < moment().subtract(1, 'days')"
                  :placeholder="['开始日期', '结束日期']" v-model:value="state.formModel.task_days" />
              </a-form-item>
              <!-- 执行时间 -->
              <a-form-item label="执行时间" name="task_periods" :rules="[{ validator: checkTaskPeriods, required: true }]">
                <div style="display: flex;align-items: center;">
                  <a-time-picker placeholder="开始时间" format="HH:mm" valueFormat="YYYY-MM-DD HH:mm"
                    v-model:value="state.formModel.task_periods[0]" />
                  <div style="color: #FFFFFF;">-</div>
                  <a-time-picker placeholder="结束时间" format="HH:mm" valueFormat="YYYY-MM-DD HH:mm"
                    v-model:value="state.formModel.task_periods[1]" />
                </div>
              </a-form-item>
              <!-- 任务开始执行的电量 -->
              <a-form-item label="任务开始执行的电量" name="min_battery_capacity">
                <a-input-number :min="50" :max="100" :formatter="(value: number) => `${value}%`"
                  :parser="(value: string) => value.replace('%', '')"
                  v-model:value="state.formModel.min_battery_capacity">
                </a-input-number>
              </a-form-item>
            </template>
            <!-- 返航高度 -->
            <a-form-item label="返航高度（相对机场返航高度）" name="rth_altitude">
              <a-input-number style="width: 100%;" :min="20" :max="1500" v-model:value="state.formModel.rth_altitude" />
            </a-form-item>
            <!-- 航线飞行中失联 -->
            <a-form-item label="航线飞行中失联" name="exit_wayline_when_rc_lost">
              <div style="white-space: nowrap;">
                <a-radio-group button-style="solid" v-model:value="state.formModel.exit_wayline_when_rc_lost">
                  <a-radio-button :value="1">
                    退出任务并返航
                  </a-radio-button>
                  <a-radio-button :value="0">
                    继续执行
                  </a-radio-button>
                </a-radio-group>
              </div>
            </a-form-item>
            <!-- 完成动作 -->
            <a-form-item label="完成动作" name="out_of_control_action">
              <a-select style="width: 100%;" v-model:value="state.formModel.out_of_control_action" disabled>
                <a-select-option :value="0">
                  自动返航
                </a-select-option>
              </a-select>
            </a-form-item>
            <!-- 自动断点续飞 -->
            <a-form-item label="自动断点续飞" name="breakpoint_continuation">
              <a-switch checked-children="开" un-checked-children="关"
                v-model:checked="state.formModel.breakpoint_continuation" />
            </a-form-item>
          </a-form>
        </div>
      </a-spin>
      <div class="taskPanel-info-footer">
        <template v-if="type !== 'DETAIL'">
          <a-button style="background: #3c3c3c;margin-right: 10px;" @click="onClickCancel">
            取消
          </a-button>
          <a-button type="primary" @click="handleClickConfirm">
            确定
          </a-button>
        </template>
        <template v-else>
          <a-button style="background: #3c3c3c;" @click="onClickCancel">
            返回
          </a-button>
        </template>
      </div>
    </div>
    <div class="taskPanel-modal" v-if="waylineState.visible">
      <div class="taskPanel-modal-title">
        <div>
          航线列表
        </div>
        <a style="color: #FFFFFF;">
          <CloseOutlined @click="waylineState.visible = false" />
        </a>
      </div>
      <a-spin :spinning="waylineState.listLoading">
        <div class="taskPanel-modal-content" v-if="waylineState.list.length">
          <div class="wayline-panel" v-for="item in waylineState.list" :key="item.id"
            @click="state.formModel.file_id = item.id">
            <div class="wayline-panel-title">
              <div class="wayline-panel-title-left">
                {{ item.name }}
              </div>
              <div class="wayline-panel-title-right">
                <UserOutlined />
                {{ item.user_name }}
              </div>
            </div>
            <div style="margin-bottom: 5px;">
              <img :src="aircraftSrc">
              {{ item.drone_model }}
            </div>
            <div style="margin-bottom: 5px;">
              <CameraFilled />
              {{ item.payload_model }}
            </div>
            <div>
              更新时间 {{ item.update_time }}
            </div>
          </div>
        </div>
        <a-empty style="margin-top: 20%;" :image="noDataSrc" :image-style="{ height: '60px' }" v-else />
      </a-spin>
    </div>
    <div class="taskPanel-modal" v-if="deviceState.visible">
      <div class="taskPanel-modal-title">
        <div>
          设备列表
        </div>
        <a style="color: #FFFFFF;">
          <CloseOutlined @click="deviceState.visible = false" />
        </a>
      </div>
      <a-spin :spinning="deviceState.listLoading">
        <div class="taskPanel-modal-content" v-if="deviceState.list.length">
          <div class="device-panel" v-for="item in deviceState.list" :key="item.sn"
            @click="state.formModel.dock_sn = item.sn">
            <div class="device-panel-cell">
              <img :src="dockSrc">
              <div>
                {{ item.name }}
              </div>
            </div>
            <div class="device-panel-cell">
              <img :src="aircraftSrc">
              <div>
                {{ item.children.name }}
              </div>
            </div>
          </div>
        </div>
        <a-empty style="margin-top: 20%;" :image="noDataSrc" :image-style="{ height: '60px' }" v-else />
      </a-spin>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, reactive, watch, computed, onMounted } from 'vue';
import { message } from 'ant-design-vue';
import { PlusOutlined, CloseOutlined, UserOutlined, CameraFilled } from '@ant-design/icons-vue';
import noDataSrc from '/@/assets/icons/no-data.png';
import aircraftSrc from '/@/components/airport/icons/aircraft.svg';
import dockSrc from '/@/components/airport/icons/dockInfo.svg';
import moment from 'moment';
import { apis } from '/@/api/custom';
import { wgs84togcj02 } from '/@/vendors/coordtransform';
import { DEVICE_NAME } from '/@/types/device'

interface Props {
  type: 'COPY' | 'DETAIL' | 'CREATE',
  drawTrajectory: (list: {
    paths: number[],
    isSPoint: boolean,
  }[]) => void,
  onClickConfirm: (data: any) => Promise<any>,
  onClickCancel: () => void,
};

const props = withDefaults(defineProps<Props>(), {

});

const formRef = ref();

interface State {
  loading: boolean,
  formModel: {
    name: string;
    file_id: string;
    wayline_type?: number,
    dock_sn: string;
    wayline_precision_type: number;
    task_type: number;
    task_time: string;
    task_days: any[],
    task_periods: any[],
    min_battery_capacity: number,
    rth_altitude: number,
    exit_wayline_when_rc_lost: number,
    out_of_control_action: number,
    breakpoint_continuation: boolean,
  }
}

const state: State = reactive({
  loading: false,
  formModel: {
    name: '',// 任务名称
    file_id: '',// 执行航线
    wayline_type: undefined,// 航线类型
    dock_sn: '',// 执行设备
    wayline_precision_type: 1,// 任务精度
    task_type: 0,// 任务策略
    task_time: '',// 定时-执行时间
    task_days: [],// 循环-执行日期
    task_periods: [],// 循环-执行时间
    min_battery_capacity: 90,// 循环-任务开始执行的电量
    rth_altitude: 20,// 返航高度
    exit_wayline_when_rc_lost: 1,// 航线飞行中失联
    out_of_control_action: 0,// 完成动作-返航
    breakpoint_continuation: true,// 自动断点续飞
  }
})

const waylineState = reactive({
  visible: false,
  listLoading: false,
  list: [] as {
    id: string,
    name: string,
    update_time: string,
    user_name: string,
    drone_model: string,
    payload_model: string,
    wayline_type: number,
  }[],
})

const waylineInfo = computed(() => {
  const fileId = state.formModel.file_id;
  return waylineState.list.find(item => item.id === fileId);
});

const deviceState = reactive({
  visible: false,
  listLoading: false,
  list: [] as {
    sn: string,
    name: string,
    children: {
      sn: string,
      name: string,
      drone_model: string,
    },
  }[],
})

const deviceInfo = computed(() => {
  const dockSn = state.formModel.dock_sn;
  return deviceState.list.find(item => item.sn === dockSn);
});

// 获取航线列表
const fetchWaylineList = async () => {
  waylineState.listLoading = true;
  try {
    const res = await apis.fetchAllWaylineList();
    const list = res.data.map((item: any) => {
      return {
        id: item.id,
        name: item.name,
        update_time: moment(item.update_time).format('YYYY-MM-DD HH:mm:ss'),
        user_name: item.user_name,
        drone_model: DEVICE_NAME[item.drone_model_key],
        payload_model: item.payload_model_keys.map((key: any) => DEVICE_NAME[key]).join('、'),
        wayline_type: item.template_types ? item.template_types[0] : '',
      }
    })
    waylineState.list = list;
  } catch (error) {
    console.error(error);
  } finally {
    waylineState.listLoading = false;
  }
}

// 获取设备列表
const fetchDeviceList = async () => {
  deviceState.listLoading = true;
  try {
    const res = await apis.fetchAllDockDeviceList();
    // 在线设备列表
    const olineList = res.data.filter((item: any) => item.status);
    const list = olineList.map((item: any) => {
      const drone_model_key = item.children ? item.children.domain + '-' + item.children.type + '-' + item.children.sub_type : '';
      return {
        sn: item.device_sn,
        name: item.nickname,
        children: {
          sn: item.children?.device_sn || '',
          name: item.children?.device_name || '',
          drone_model: DEVICE_NAME[drone_model_key],
        }
      }
    })
    deviceState.list = list;
  } catch (error) {
    console.error(error);
  } finally {
    deviceState.listLoading = false;
  }
}

const fetchDetail = async (id: string) => {
  state.loading = true;
  try {
    const res = await apis.fetchJobDetail(id);
    const info = res.data;
    const data = {
      ...state.formModel,
      name: props.type === 'COPY' ? info.job_name + '_复制' : info.job_name,
      file_id: info.file_id,
      wayline_type: info.wayline_type,
      dock_sn: info.dock_sn,
      wayline_precision_type: info.wayline_precision_type,
      task_type: info.task_type,
      task_time: info.task_type === 1 ? info.begin_time : state.formModel.task_time,
      rth_altitude: info.rth_altitude,
      breakpoint_continuation: info.breakpoint_continuation,
    }
    state.formModel = data;
  } catch (error) {
    console.error(error);
  } finally {
    state.loading = false;
  }
}

const init = async (id?: string) => {
  await Promise.all([
    fetchWaylineList(),
    fetchDeviceList(),
  ])
  if (id) {
    await fetchDetail(id);
  }
}

onMounted(() => {
  init();
})

watch(() => waylineState.visible, async (visible) => {
  if (visible) {// 更新航线列表
    await fetchWaylineList();
  }
});

watch(() => deviceState.visible, async (visible) => {
  if (visible) {// 更新设备列表
    await fetchDeviceList();
  }
});

watch(() => state.formModel.file_id, async (wayline_id) => {
  if (!wayline_id) {
    return;
  }
  try {
    const res = await apis.fetchWaylinePoint(wayline_id);
    const list = res.data.map((item: any) => {
      return {
        paths: wgs84togcj02(item.longitude, item.latitude),
        isSPoint: item.point_index == 0 && item.folder_id == 0,
      }
    })
    props.drawTrajectory(list);
  } catch (error) {
    console.error(error);
  }
});

// 检查执行时间
const checkTaskPeriods = (rule: any, values: string) => {
  if (values?.length) {
    const startTime = values[0];
    const endTime = values[1];
    if (!startTime) {
      return Promise.reject('开始时间不能为空');
    } else if (!endTime) {
      return Promise.reject('结束时间不能为空');
    } else if (startTime > endTime) {
      return Promise.reject('结束时间不能早于开始时间');
    } else {
      return Promise.resolve();
    }
  } else {
    return Promise.reject('执行时间不能为空');
  }
};

// 点击选择航线
const handleClickSelectWayline = () => {
  waylineState.visible = true;
  deviceState.visible = false;
}

// 点击选择设备
const handleClickSelectDevice = () => {
  deviceState.visible = true;
  waylineState.visible = false;
}

// 点击确定
const handleClickConfirm = async () => {
  formRef.value?.validateFields().then(async (values: any) => {
    const wayline = waylineInfo.value;
    const waylineDroneModel = wayline?.drone_model;
    const droneModel = deviceInfo.value?.children.drone_model;
    state.formModel.wayline_type = wayline?.wayline_type;
    if (waylineDroneModel !== droneModel) {
      // return message.warning('请选择相同型号的设备');
    }
    const data = {
      ...values,
      wayline_type: state.formModel.wayline_type,
    };
    if (values.task_time) {
      data.task_time = moment(values.task_time).valueOf();
    }
    if (values.task_days?.length === 2) {
      const startDate = moment(values.task_days[0]);
      const endDate = moment(values.task_days[1]);
      // 计算天数差
      const daysDiff = endDate.diff(startDate, 'days') + 1;
      // 生成包含每一天的秒级的时间戳的数组
      const taskDays = [];
      for (let i = 0; i < daysDiff; i++) {
        const day = startDate.add(i, 'days');
        taskDays.push(day.unix().valueOf());
      }
      data.task_days = taskDays;
    }
    if (values.task_periods?.length === 2) {
      const startDate = moment(values.task_periods[0]).unix().valueOf();
      const endDate = moment(values.task_periods[1]).unix().valueOf();
      data.task_periods = [startDate, endDate];
    }
    await props.onClickConfirm(data);
  }).catch((error: any) => {
    console.error(error);
  });
}

defineExpose({ init });
</script>

<style lang="scss" scoped>
.taskPanel {
  height: 100%;
  color: #FFFFFF;
  position: relative;

  &-info {
    width: 300px;
    height: 100%;
    padding: 0 10px 10px;
    border-right: 1px solid #4f4f4f;
    background-color: #232323;

    &-title {
      width: 100%;
      height: 40px;
      padding-left: 10px;
      border-bottom: 1px solid #4f4f4f;
      display: flex;
      justify-content: space-between;
      align-items: center;
    }

    &-content {
      width: 100%;
      height: calc(100vh - 100px);
      overflow: auto;
    }

    &-footer {
      width: 100%;
      height: 60px;
      display: flex;
      justify-content: space-between;
      align-items: center;

      button {
        width: 100%;
        color: #FFFFFF;
        border: none;
      }
    }
  }

  &-modal {
    width: 280px;
    height: 100%;
    padding: 0 10px 10px;
    background-color: #232323;
    position: absolute;
    left: 100%;
    top: 0;
    z-index: 2;

    &-title {
      width: 100%;
      height: 40px;
      border-bottom: 1px solid #4f4f4f;
      display: flex;
      justify-content: space-between;
      align-items: center;
    }

    &-content {
      width: 100%;
      height: calc(100vh - 50px);
      overflow: auto;
    }
  }
}

.wayline-panel {
  width: 100%;
  padding: 10px;
  background-color: #3c3c3c;
  border-radius: 4px;
  color: #FFFFFF;
  cursor: pointer;
  margin-top: 10px;

  &-title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 5px;

    &-left {
      width: 120px;
      white-space: nowrap;
      text-overflow: ellipsis;
      overflow: hidden;
    }

    &-right {
      width: 80px;
      white-space: nowrap;
      text-overflow: ellipsis;
      overflow: hidden;
    }
  }

  img {
    width: 14px;
    height: 14px;
  }
}

.device-panel {
  width: 100%;
  padding: 10px;
  background-color: #3c3c3c;
  border-radius: 4px;
  color: #FFFFFF;
  cursor: pointer;
  margin-top: 10px;

  &-cell {
    display: flex;
    align-items: center;
    margin-bottom: 5px;

    img {
      width: 16px;
      height: 16px;
      margin-right: 5px;
    }
  }

  &-cell:last-child {
    margin: 0;
  }
}
</style>

<style lang="scss">
.taskPanel {
  form {
    margin: 12px;
  }

  .ant-form-item {
    margin-bottom: 12px;
  }

  form,
  label,
  input,
  .ant-input,
  .ant-input:hover,
  .ant-calendar-range-picker-separator,
  .ant-time-picker .anticon,
  .ant-calendar-picker .anticon {
    background-color: #232323;
    color: #FFFFFF;
  }

  .ant-select-selector {
    background: #3c3c3c !important;
    color: rgba(255, 255, 255, .25) !important;
    border-color: #3c3c3c !important;
  }
}

::-webkit-scrollbar {
  display: none;
}
</style>