<template>
  <div class="container">
    <a-row :gutter="20" align="stretch">
      <a-col :span="24">
        <a-scrollbar
          style="
            height: calc(100vh - 150px);
            overflow: auto;
            background: var(--color-bg-2);
          "
          class="item-container"
        >
          <a-card class="general-card">
            <template #title>
              <a-row style="padding: 12px 20px">
                <a-col v-if="draft" flex="32px">
                  <a-tooltip content="退出计划草稿">
                    <a-button
                      class="nav-btn"
                      type="outline"
                      :shape="'circle'"
                      @click="draftChangeHandler(false)"
                    >
                      <template #icon>
                        <icon-left />
                      </template>
                    </a-button>
                  </a-tooltip>
                </a-col>
                <a-col flex="auto">
                  <div
                    v-if="draft"
                    style="
                      text-align: center;
                      font-weight: bold;
                      font-size: 18px;
                    "
                  >
                    计划草稿
                  </div>
                </a-col>
              </a-row>
            </template>

            <template #extra>
              <div
                v-if="works.length > 0 || uiShow.ui_status?.alter"
                style="padding: 12px 20px"
              >
                <a-space :size="1" align="center" class="project-detail-nav">
                  <template #split>
                    <a-divider direction="vertical" />
                  </template>
                  <span v-if="uiShow.ui_status?.alter">
                    <a-button type="primary" @click="draftChangeHandler(true)"
                      >计划草稿</a-button
                    >
                  </span>
                  <span v-for="item in works" :key="item.id">
                    <a-button type="primary" @click="showWorkModal(item.id)">
                      {{ item.name }}
                    </a-button>
                  </span>
                </a-space>
              </div>
            </template>

            <a-divider style="margin-top: 0" />
            <a-table
              ref="editTableRef"
              v-model:expanded-keys="expandedKeys"
              :class="{
                'slide-out': draft,
                'slide-in': !draft && !isFirstLoad
              }"
              :scroll="{
                x: 1500,
                y: '100%'
              }"
              :pagination="false"
              :columns="columns"
              :data="tasks"
              :bordered="{
                cell: true,
                headerCell: true,
                wrapper: true
              }"
              :hoverable="false"
              table-layout-fixed
              :row-class="selectRowClass"
              row-key="task_id"
              hide-expand-button-on-empty
              @cell-mouse-enter="selectedTaskHandler"
              @cell-mouse-leave="selectTaskId = undefined"
              @change="handleChange"
            >
              <template #expand-icon="{ expanded }">
                <span v-if="expanded">
                  <icon-down style="margin-top: 3px" :size="16" />
                </span>
                <span v-else>
                  <icon-right style="margin-top: 2px" :size="16" />
                </span>
              </template>
              <template #name="{ record }">
                <div class="editable-cell">
                  <div
                    v-if="
                      !record.isLeaf && expandedKeys.includes(record.task_id)
                    "
                    class="editable-cell-isLeaf-icon"
                  >
                    <icon-font type="my-folder-open" :size="20" />
                  </div>
                  <div
                    v-if="
                      !record.isLeaf && !expandedKeys.includes(record.task_id)
                    "
                    class="editable-cell-isLeaf-icon"
                  >
                    <icon-font type="my-folder-close" :size="19" />
                  </div>
                  <div v-if="record.isLeaf" class="editable-cell-isLeaf-icon">
                    <icon-font type="my-file" :size="21" />
                  </div>

                  <div
                    v-if="editableNameData[record.task_id]"
                    class="editable-cell-input-wrapper"
                  >
                    <a-input
                      v-model="editableNameData[record.task_id].name"
                      v-focus="true"
                      placeholder="请输入任务名称"
                      @blur="nameChange(record.task_id)"
                      @press-enter="nameChange(record.task_id)"
                    />
                  </div>
                  <div v-else class="editable-cell-text-wrapper">
                    <span>{{ record.name || ' ' }}</span>
                    <div
                      v-show="
                        record.task_id === selectTaskId &&
                        editable(uiShow.ui_status?.name)
                      "
                      class="editable-cell-icon"
                    >
                      <icon-edit
                        :size="16"
                        @click="editName(record.task_id, record)"
                      />
                      <icon-plus :size="16" @click="add(record.task_id)" />
                    </div>
                  </div>
                </div>
              </template>
              <template #progress="{ record }">
                <a-trigger
                  update-at-scroll
                  trigger="click"
                  :disabled="
                    !(record.task_id === selectTaskId) ||
                    !record.isLeaf ||
                    !editable(uiShow.ui_status?.progress)
                  "
                  :unmount-on-close="true"
                  :blur-to-close="false"
                  show-arrow
                  position="tl"
                >
                  <div class="editable-cell">
                    <div class="editable-cell-text-wrapper">
                      <a-progress
                        :percent="record.progress / 100"
                        :style="{ width: '90%' }"
                        size="large"
                      />

                      <div
                        v-if="
                          record.task_id === selectTaskId &&
                          record.isLeaf &&
                          editable(uiShow.ui_status?.progress)
                        "
                        class="editable-cell-icon"
                      >
                        <icon-edit :size="16" />
                      </div>
                    </div>
                  </div>

                  <template #content>
                    <div class="demo-basic">
                      <a-space direction="vertical">
                        <a-typography-text>
                          调整{{ record.name }}进度</a-typography-text
                        >
                        <a-slider
                          v-model="record.progress"
                          :min="0"
                          :max="100"
                          :style="{ width: '200px' }"
                          @change="debounceChange($event as number, record)"
                        />
                      </a-space>
                    </div>
                  </template>
                </a-trigger>
              </template>
              <template #status="{ record }">
                <a-tag
                  v-for="item in selectedTaskStatus(record.status)"
                  :key="item.value"
                  :color="item['tag-props'].color"
                  >{{ item.label }}</a-tag
                >
                <!-- <a-select
                v-model="record.status"
                :disabled="
                  !(record.task_id === selectTaskId) ||
                  !allowModifyStatus.includes(record.status)
                "
                :style="{ width: '100%' }"
                :bordered="false"
                size="large"
              >
                <template #arrow-icon>
                  <icon-down
                    v-if="
                      record.task_id === selectTaskId &&
                      allowModifyStatus.includes(record.status)
                    "
                  />
                </template>
                <template #label="{ data: tag }">
                  <a-tag :color="tag.tagProps.color">{{ tag.label }}</a-tag>
                </template>
                <a-option
                  v-for="options in TaskStatusList"
                  :key="options.value"
                  :value="options.value"
                  :tag-props="options['tag-props']"
                >
                  <a-tag :color="options['tag-props'].color">{{
                    options.label
                  }}</a-tag>
                </a-option>
              </a-select> -->
              </template>
              <template #account="{ record }">
                <span v-if="!record.isLeaf"></span>
                <a-select
                  v-else
                  :model-value="record.handler_id"
                  :disabled="!editable(uiShow.ui_status?.handler_name)"
                  :style="{ width: '100%', padding: 0 }"
                  :bordered="false"
                  @change="handlerChange($event as string, record)"
                >
                  <template #arrow-icon>
                    <icon-down
                      v-if="
                        record.task_id === selectTaskId &&
                        record.isLeaf &&
                        editable(uiShow.ui_status?.name)
                      "
                    />
                  </template>
                  <template #label="{ data }">
                    <span style="color: rgb(var(--gray-10))">{{
                      data.label
                    }}</span>
                  </template>
                  <a-option
                    v-for="user in accountList"
                    :key="user.id"
                    :value="user.id"
                    :label="user.name"
                  >
                    <!-- {{ user.name }} -->
                  </a-option>
                </a-select>
              </template>
              <template #begin="{ record }">
                <a-date-picker
                  :disabled="
                    !record.isLeaf || !editable(uiShow.ui_status?.begin_at)
                  "
                  :model-value="record.begin_at"
                  :style="{ width: '100%' }"
                  @change="beginAtChange($event as string, record)"
                >
                  <!-- <a-space
                  align="center"
                  class="date-space"
                  style="width: 100%; justify-content: space-between"
                > -->
                  <div
                    style="
                      display: flex;
                      align-items: center;
                      justify-content: space-between;
                    "
                  >
                    {{ record.begin_at }}
                    <icon-calendar
                      v-show="
                        record.task_id === selectTaskId &&
                        record.isLeaf &&
                        editable(uiShow.ui_status?.begin_at)
                      "
                      style="cursor: pointer"
                    />
                  </div>
                  <!-- <a-button
                  v-show="record.task_id === selectTaskId"
                  type="text"
                  class="task-date-btn"
                >
                  <icon-calendar />
                </a-button> -->
                  <!-- </a-space> -->
                </a-date-picker>
              </template>
              <template #end="{ record }">
                <a-date-picker
                  :model-value="record.end_at"
                  :disabled="
                    !record.isLeaf || !editable(uiShow.ui_status?.end_at)
                  "
                  :style="{ width: '100%' }"
                  @change="endAtChange($event as string, record)"
                >
                  <div
                    style="
                      display: flex;
                      align-items: center;
                      justify-content: space-between;
                    "
                  >
                    {{ record.end_at }}
                    <icon-calendar
                      v-show="
                        record.task_id === selectTaskId &&
                        record.isLeaf &&
                        editable(uiShow.ui_status?.begin_at)
                      "
                      style="cursor: pointer"
                    />
                  </div>
                  <!-- <div>{{ record.end_at }}</div> -->
                  <!-- :disabled="!(record.task_id === selectTaskId)" -->
                  <!-- <a-space
                  align="center"
                  class="date-space"
                  style="width: 100%; justify-content: space-between"
                >
                  {{ record.end_at }}
                  <a-button
                    v-show="record.task_id === selectTaskId"
                    type="text"
                    class="task-date-btn"
                  >
                    <icon-calendar />
                  </a-button>
                </a-space> -->
                </a-date-picker>
              </template>
              <template #operater="{ record }">
                <div class="operate-text-button" style="height: 32px">
                  <div v-if="draft" class="ribbon-wrapper">
                    <div
                      :class="
                        'ribbon ' + getRibbonInfo(record.change_marker)?.class
                      "
                    >
                      {{ getRibbonInfo(record.change_marker)?.label }}
                    </div>
                  </div>
                  <div v-if="record.isLeaf">
                    <a-button
                      type="text"
                      @click="redirectTaskDetailPage(record.task_id)"
                      >详情</a-button
                    >
                    <!-- <a-divider direction="vertical" />
                  <a-button
                    type="text"
                    @click="showSetOutcomePage(record.task_id, record.name)"
                    >设置</a-button
                  > -->
                    <a-divider direction="vertical" />
                    <a-button
                      type="text"
                      status="danger"
                      @click="removePlanNode(record.task_id, record.layer)"
                      >删除</a-button
                    >
                    <a-divider direction="vertical" />
                    <a-dropdown v-if="record.works?.length > 0">
                      <a-button type="text">更多 <icon-down /></a-button>
                      <template #content>
                        <a-doption
                          v-for="item in record.works"
                          :key="item.id"
                          @click="showWorkModal(item.id)"
                          >{{ item.name }}</a-doption
                        >
                      </template>
                    </a-dropdown>
                  </div>
                </div>
              </template>
              <template #tr="{ record }">
                <tr
                  ref="refTitle"
                  :draggable="true"
                  @dragstart="handleDragstart(record, $event)"
                  @drop="onDrop(record, $event)"
                  @dragleave.prevent="handleDragleave($event)"
                  @dragover.prevent="handleDragover(record, $event)"
                ></tr>
              </template>
            </a-table>
          </a-card>
        </a-scrollbar>
      </a-col>
    </a-row>

    <SetOutcomeModal
      ref="outcomeModalRef"
      :account-list="accountList"
      :draft="draft"
    ></SetOutcomeModal>
  </div>
</template>

<script lang="ts" setup>
import { IconDown, IconRight, IconPlus } from '@arco-design/web-vue/es/icon'
import { cloneDeep } from 'lodash'
import { ref, reactive, onMounted, h, nextTick, toRaw, computed } from 'vue'
import {
  Button,
  Icon,
  TableColumnData,
  TableData,
  Tooltip
} from '@arco-design/web-vue'
import { ChangeMarkerList, IconFontUrl, OperateTypeItem } from '@/enums/api'
import type { PropType, UnwrapRef } from 'vue'
import { selectedTaskStatus } from '@/utils'
import { useEmitt } from '@/logics/mitt/useEmitt'
import {
  getPlanTaskList,
  addPlanTask,
  removePlanTask,
  modifyPlanTask,
  setPlanProgress,
  sortPlanTask
} from '@/api/project/plan-task'
import { Task, TaskListReqParams, UiStatus } from '@/types/plan-task'

import { format } from 'date-fns'
import { useDebounceFn } from '@vueuse/core'
import { listenerRouteChange } from '@/logics/mitt/routeChange'
import { RouteLocationNormalized } from 'vue-router'
import SetOutcomeModal from './set-outcome.vue'

const draft = ref<boolean>(false)
const outcomeModalRef = ref<any>(null) // Modal 设置交付物Modal
const position = ref<any>(0)
const refTitle = ref<HTMLElement>()
const IconFont = Icon.addFromIconFontCn({
  src: IconFontUrl.URL
})

const uiShow = reactive<{ ui_status?: UiStatus }>({
  ui_status: {
    alter: true
  }
}) // 客户详情

const props = defineProps({
  prjId: {
    type: String,
    required: true
  },
  accountList: {
    type: Array as PropType<{ id: string; name: string }[]>,
    required: true
  }
})

const expandedKeys = ref<string[]>([])
const isFirstLoad = ref(true)
interface Tasks {
  task_id: string
  name?: string
  pid?: string
  progress?: number
  status?: number
  handler_id?: string
  handler_name?: string
  begin_at?: string
  end_at?: string
  children?: Tasks[]
  sub_tasks?: Tasks[]
  isLeaf?: boolean
  layer?: number
}

/**
 * 是否是编辑
 * @param type
 */
const editable = (type?: string) => {
  return type === OperateTypeItem.RW || type === OperateTypeItem.W
}

const columns = computed<TableColumnData[]>(() => {
  return [
    {
      title: '名称',
      dataIndex: 'name',
      slotName: 'name',
      filterable: editable(uiShow.ui_status?.name)
        ? {
            filter: () => {
              return false
            },
            icon: () =>
              h(
                Tooltip,
                {
                  content: '添加任务'
                },
                {
                  default: () =>
                    h(
                      Button,
                      {
                        type: 'text',
                        onClick: (event: MouseEvent) => {
                          addMilestone()
                          event.stopPropagation()
                          event.preventDefault()
                        }
                      },
                      {
                        icon: () => h(IconPlus)
                      }
                    )
                }
              )
          }
        : undefined,
      width: 300,
      bodyCellClass: (record: TableData) => {
        return getRibbonInfo(record.change_marker)?.subClass || ''
      }
    },
    {
      title: '进度',
      dataIndex: 'progress',
      slotName: 'progress',
      bodyCellClass: (record: TableData) => {
        return getRibbonInfo(record.change_marker)?.subClass || ''
      }
    },
    {
      title: '状态',
      dataIndex: 'status',
      slotName: 'status',
      width: 150,
      bodyCellClass: (record: TableData) => {
        return getRibbonInfo(record.change_marker)?.subClass || ''
      }
    },
    {
      title: '主责人',
      dataIndex: 'handler_name',
      slotName: 'account',
      width: 150,
      bodyCellClass: (record: TableData) => {
        return getRibbonInfo(record.change_marker)?.subClass || ''
      }
    },
    {
      title: '计划开始时间',
      dataIndex: 'begin_at',
      slotName: 'begin',
      bodyCellClass: (record: TableData) => {
        return getRibbonInfo(record.change_marker)?.subClass || ''
      }
      // width: 200
    },
    {
      title: '计划结束时间',
      dataIndex: 'end_at',
      slotName: 'end',
      bodyCellClass: (record: TableData) => {
        return getRibbonInfo(record.change_marker)?.subClass || ''
      }
      // width: 200
    },
    {
      title: '实际完成时间',
      dataIndex: 'completed_at',
      bodyCellClass: (record: TableData) => {
        return getRibbonInfo(record.change_marker)?.subClass || ''
      }
      // width: 200
    },
    {
      title: '操作',
      dataIndex: 'operater',
      slotName: 'operater',
      width: 220,
      fixed: 'right',
      bodyCellClass: (record: TableData) => {
        return getRibbonInfo(record.change_marker)?.subClass || ''
      }
    }
  ]
})

const tasks = ref<Tasks[]>([])

const editTableRef = ref<any>(null)
const selectedKey = ref<string>()
const selectTaskId = ref<string>()
const { emitter } = useEmitt()
const editableNameData: UnwrapRef<Record<string, any>> = reactive({})

const works = ref<{ id: string; name: string }[]>([])

const getRibbonInfo = (mark: number) => {
  return ChangeMarkerList.find(item => item.value === mark)
}

const draftChangeHandler = async (isDraft: boolean) => {
  tasks.value = []
  draft.value = isDraft
  isFirstLoad.value = false
  await getTaskTree()
}

/**
 *
 * @param _data
 * @param _extraData
 * @param _currentData
 */
const handleChange = (_data: any, _extraData: any, _currentData: any) => {
  tasks.value = _data
}

/**
 * 鼠标放上
 * @param group
 */
const selectedTaskHandler = (task: TableData) => {
  selectTaskId.value = task.task_id
}

/**
 *
 * @param record
 * @param _rowIndex
 */
const selectRowClass = (record: TableData, _rowIndex: number) => {
  if (selectTaskId.value === record.task_id) {
    return 'row-select-bg'
  }
  return 'edit-row-class'
}

/**
 * 修改节点信息
 * @param task
 * @param taskId
 * @returns
 */
const modifyNode = <T extends Tasks[]>(task: T, taskId: string): T => {
  task.map((item: Tasks): T => {
    if (item.task_id === taskId) {
      Object.assign(item, editableNameData[taskId])
      return task
    }
    if (item.children) {
      modifyNode(item.children, taskId)
    }
    return task
  })
  return task
}

/**
 * 递归获取tree需要的结构体
 * @param task 接口返回的树状数组
 * @param layer 层级
 */
const getNodesTree = (task: Tasks, layer?: number): Tasks => {
  task.layer = (layer || 0) + 1 // 添加layer参数
  task.children = task.sub_tasks // 添加children参数
  if (task.children && task.children.length > 0) {
    task.children.map(res => getNodesTree(res, task.layer))
  } else {
    task.children = []
    task.isLeaf = true
  }
  return task
}

/**
 * 添加节点信息
 * @param task
 * @param taskId
 * @returns
 */
const addNode = <T extends Tasks[]>(
  task: T,
  taskId: string,
  node: Tasks
): T => {
  task.map((item: Tasks) => {
    if (item.task_id === taskId) {
      editableNameData[node.task_id] = cloneDeep(node)
      if (!Reflect.has(item, 'children')) {
        Reflect.set(item, 'children', [])
      }
      item.children?.push(node)
      item.isLeaf = false
      Object.assign(item, editableNameData[taskId])
      return item
    }
    if (item.children) {
      addNode(item.children, taskId, node)
    }
    return item
  })
  return task
}

// /**
//  * 删除节点
//  * @param tree
//  * @param taskId
//  * @returns
//  */
// const removeNode = <T extends Tasks[]>(task: T, taskId: string): T => {
//   task.map((item: Tasks, index: number): T => {
//     if (item.task_id === taskId) {
//       task.splice(index, 1)
//     }
//     if (item.children) {
//       removeNode(item.children, taskId)
//     }
//     return task
//   })
//   return task
// }

// 修改节点
const editName = (taskId: string, record: Tasks) => {
  selectedKey.value = taskId
  editableNameData[taskId] = cloneDeep(record)
}

// 添加节点
const add = async (taskId: string) => {
  selectedKey.value = taskId
  const node: Tasks = {
    task_id: new Date().getTime().toString(),
    name: '默认任务',
    progress: 0,
    layer: 2,
    isLeaf: true,
    handler_id: props.accountList[0].id,
    begin_at: format(new Date(), 'yyyy-MM-dd'),
    end_at: format(new Date(), 'yyyy-MM-dd'),
    status: 0,
    children: []
  }

  const params = {
    draft: draft.value,
    prj_id: props.prjId,
    task_pid: taskId,
    name: node.name!,
    handler_id: node.handler_id!,
    begin_at: node.begin_at!,
    end_at: node.end_at!
  }
  const { id } = await addPlanTask(params)
  node.task_id = id
  tasks.value = addNode(tasks.value, taskId, node)
  expandedKeys.value.push(id)
}

/**
 * 保存添加,修改节点后的操作
 */
const nameChange = async (taskId: string) => {
  try {
    if (!editableNameData[taskId]) {
      return
    }
    await modifyPlanTask({
      draft: draft.value,
      task_id: taskId,
      name: editableNameData[taskId].name
    })
    // tasks.value = modifyNode(tasks.value, taskId)
    getTaskTree()
  } catch (_e) {
    getTaskTree()
  }
  delete editableNameData[taskId]
  selectedKey.value = undefined
}

const setProgress = async (progress: number, task: Tasks) => {
  try {
    await setPlanProgress({ progress, task_id: task.task_id })
  } catch (_e) {
    /* empty */
  }
  setTimeout(() => {
    getTaskTree()
  }, 1500)
}

const debounceChange = useDebounceFn(setProgress, 1000)

/**
 *  handler负责人发生改变时
 * @param handlerId
 * @param task
 */
const handlerChange = async (handlerId: string, task: Tasks) => {
  try {
    await modifyPlanTask({
      draft: draft.value,
      task_id: task.task_id,
      handler_id: handlerId
    })
    getTaskTree()
    return false
  } catch (_e) {
    return true
  }
}

/**
 * 修改开始时间回调
 * @param begin
 * @param task
 */
const beginAtChange = async (begin: string, task: Tasks) => {
  try {
    await modifyPlanTask({
      draft: draft.value,
      task_id: task.task_id,
      begin_at: begin
    })
    getTaskTree()
    return false
  } catch (_e) {
    return true
  }
}

/**
 *  修改结束时间回调
 * @param begin
 * @param task
 */
const endAtChange = async (end: string, task: Tasks) => {
  await modifyPlanTask({
    draft: draft.value,
    task_id: task.task_id,
    end_at: end
  })
  // task.end_at = end
  getTaskTree()
  return false
}

// 跳转到任务计划详情页面
const redirectTaskDetailPage = (taskId: string) => {
  emitter.emit('redirectTaskDetailPage', { id: taskId, draft: draft.value })
}

const showSetOutcomePage = (taskId: string, name: string) => {
  // emitter.emit('redirectTaskDetailPage', taskId)
  outcomeModalRef.value?.showSetOutcomePage(taskId, name)
}

/**
 * 添加里程碑
 */
const addMilestone = async () => {
  const node: Tasks = {
    task_id: new Date().getTime().toString(),
    name: '默认任务',
    progress: 0,
    layer: 1,
    isLeaf: true,
    status: 0,
    handler_id: props.accountList[0].id,
    begin_at: format(new Date(), 'yyyy-MM-dd'),
    end_at: format(new Date(), 'yyyy-MM-dd'),
    children: [],
    sub_tasks: []
  }
  const params = {
    draft: draft.value,
    prj_id: props.prjId,
    name: node.name!,
    handler_id: node.handler_id!,
    begin_at: node.begin_at!,
    end_at: node.end_at!
  }
  const { id } = await addPlanTask(params)
  node.task_id = id
  selectTaskId.value = node.task_id
  expandedKeys.value.push(id)
  tasks.value.push(node)
  editableNameData[id] = cloneDeep(node)
}

/**
 * 删除节点,判断节点层级,层级为1时,为里程碑,2即为计划任务
 */
const removePlanNode = async (taskId: string, layer: number) => {
  await removePlanTask({ draft: draft.value, task_id: taskId })
  getTaskTree()
}

// const redirectTaskPage = async (work: { id: string }) => {
//   showWorkModal(work.id)
// }

const getTaskTree = async () => {
  const params: TaskListReqParams = {
    prj_id: props.prjId,
    draft: draft.value
  }
  const {
    tasks: list,
    ui_status: uiStatus,
    works: tWorks
  } = await getPlanTaskList(params)
  tasks.value = list.map(task => {
    return getNodesTree(task)
  })
  uiShow.ui_status = uiStatus
  works.value = tWorks || []
}

const dragDataKey = 'drag-plan-task-key'
const handleDragstart = (record: Task, ev: DragEvent) => {
  dragNode.value = record
  if (ev.dataTransfer) {
    ev.dataTransfer.dropEffect = 'move'
    const nodeEle = (ev.target as Element).parentElement
    if (nodeEle) {
      // console.log(nodeEle)
      // ev.dataTransfer.setDragImage(nodeEle, 0, 0)
      ev.dataTransfer.setData(dragDataKey, record.task_id)
      nextTick(() => {
        nodeEle.classList.add('dragging')
      })
    }
  }
}

// 检查目标节点是否是拖拽节点的子节点
const isDescendant = (parentNode: Tasks, childKey: string): boolean => {
  if (parentNode?.children) {
    return parentNode?.children.some((child: Tasks) => {
      if (child.task_id === childKey) {
        return true
      }
      return isDescendant(child, childKey)
    })
  }
  return false
}

const dragNode = ref<any>()
const handleDragover = (record: Task[], e: DragEvent) => {
  const rect = (e.target as Element).getBoundingClientRect()
  const offset = e.clientY - rect!.top
  if (offset < rect!.height / 3) {
    // 鼠标在目标元素的上方
    position.value = -1
  } else if (offset > (rect!.height * 2) / 3) {
    // 鼠标在目标元素的下方
    position.value = 1
  } else {
    // 鼠标在目标元素的中间区域
    position.value = 0
  }

  if (e.dataTransfer) {
    e.dataTransfer.dropEffect = 'move'
    const dom = e.currentTarget as HTMLElement
    const tdDomList = dom.querySelectorAll('td')
    // eslint-disable-next-line default-case
    switch (position.value) {
      case -1:
        // tdDomList.map()
        tdDomList.forEach(item => {
          item.setAttribute('drag-over-style', 'border-top')
        })
        break
      case 1:
        tdDomList.forEach(item => {
          item.setAttribute('drag-over-style', 'border-bottom')
        })
        break
      case 0:
        tdDomList.forEach(item => {
          item.setAttribute('drag-over-style', 'background')
        })
        break
    }
  }
}

const onDrop = async (dropNode: Tasks, e: DragEvent) => {
  // console.log(dropNode.pid)
  let taskPid
  let taskIds: string[] = []
  const taskId = e.dataTransfer?.getData(dragDataKey)
  handleDragleave(e)
  if (isDescendant(dragNode.value, dropNode.task_id) && position.value === 0) {
    return
  }
  if (taskId === dropNode.task_id) {
    return
  }
  const rawObject = toRaw(tasks.value)
  const loop = (list: any[], key: string, callback: any) => {
    list.some((item: { task_id: any; children: any }, index: any, arr: any) => {
      if (item.task_id === key) {
        callback(item, index, arr)
        return true
      }
      if (item.children) {
        return loop(item.children, key, callback)
      }
      return false
    })
  }

  loop(
    rawObject,
    dragNode.value.task_id,
    (_: any, index: number, arr: Tasks[]) => {
      arr.splice(index, 1)
    }
  )

  if (position.value === 0) {
    loop(rawObject, dropNode.task_id, (item: Tasks) => {
      item.children = item.children || []
      item.children.push(dragNode.value)
      // item.isLeaf = false
      taskPid = item.task_id
      taskIds = item.children.map(task => {
        return task.task_id
      })
    })
  } else {
    loop(
      rawObject,
      dropNode.task_id,
      (item: any, index: number, arr: Tasks[]) => {
        arr.splice(position.value < 0 ? index : index + 1, 0, dragNode.value)
        taskPid = item.pid
        taskIds = arr.map(task => {
          return task.task_id
        })
      }
    )
  }
  await sortPlanTask({
    prj_id: props.prjId,
    draft: draft.value,
    task_pid: taskPid,
    task_ids: taskIds
  })
  getTaskTree()
}

const handleDragleave = (e: DragEvent) => {
  const dom = e.currentTarget as HTMLElement
  const tdDomList = dom.querySelectorAll('td')
  tdDomList.forEach(item => {
    item.removeAttribute('drag-over-style')
  })
}

/**
 * 显示工作任务对话框
 */
const showWorkModal = (id: string) => {
  emitter.emit('show_work_modal', id)
}

// 监听子组件增加，修改，删除事件，更新列表
useEmitt({
  name: 'get_task_list',
  callback: () => {
    // draft.value = false
    getTaskTree()
  }
})

// 监听子组件增加，修改，删除事件，更新列表
useEmitt({
  name: 'switch-draft-page',
  callback: (isDraft: boolean) => {
    draft.value = isDraft
  }
})

listenerRouteChange(async (r: RouteLocationNormalized) => {
  const isDraft = r.query?.draft // id
  if (isDraft) {
    draft.value = JSON.parse(isDraft as string)
  }
})

onMounted(async () => {
  // await getAccounts()
  await getTaskTree()
  editTableRef.value.expandAll()
})
</script>

<script lang="ts">
export default {
  name: 'TaskList'
}
</script>

<style scoped lang="less">
.container {
  padding: 20px 20px 20px 20px;
  .general-card {
    :deep(.arco-card-header) {
      padding: 0;
      .nav-btn {
        border-color: transparent;
        color: var(--text-2);
        background-color: var(--color-fill-2);
        font-size: 14px;
      }
      // .nav-btn:hover {
      //   // background-color: var(--color-fill-2);
      // }
    }
    // min-height: calc(100vh - 150px);
  }
}
:deep(.arco-scrollbar-thumb-direction-vertical) {
  display: none;
}
// .container:hover {
//   transition: width 1s linear;
// }
.editable-cell {
  display: inline-flex;
  width: 100%;
  .editable-cell-isLeaf-icon {
    display: flex;
    align-items: center;
  }
  .editable-cell-input-wrapper,
  .editable-cell-text-wrapper {
    // height: 32px;
    display: flex;
  }

  .editable-cell-input-wrapper {
    width: 100%;
  }
  .editable-cell-text-wrapper {
    width: 100%;
    align-items: center;
    padding: 5px;
  }

  .editable-cell-icon,
  .editable-cell-icon-check {
    cursor: pointer;
  }

  .editable-cell-icon {
    font-size: 16px;
    margin-left: auto;
    align-items: center;
    display: flex;
    .arco-icon {
      margin-left: 4px;
    }
  }

  .editable-cell-icon-check {
    line-height: 28px;
    top: 10px;
  }

  .editable-cell-icon {
    .arco-icon:hover {
      color: #108ee9;
    }
  }

  .editable-add-btn {
    margin-bottom: 8px;
  }
}
:deep(.arco-table .arco-table-expand-btn) {
  background: none;
}
:deep(.edit-row-class) {
  // .arco-table-td:first-child {
  // border: none;
  // }
  .arco-select-view-single.arco-select-view-disabled {
    cursor: pointer;
  }
  .arco-table-td[drag-over-style='border-top'] {
    border-top: 2px solid rgb(var(--primary-4));
  }
  .arco-table-td[drag-over-style='border-bottom'] {
    border-bottom: 2px solid rgb(var(--primary-4));
  }
  .arco-table-td[drag-over-style='background'] {
    background: rgb(var(--primary-2));
  }
}

.demo-basic {
  padding: 10px 20px 20px 20px;
  width: 100%;
  background-color: var(--color-bg-popup);
  border-radius: 4px;
  box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.15);
}
:deep(.task-date-btn) {
  color: var(--color-text-2);
}
:deep(.task-date-btn):hover {
  color: var(--color-text-2);
  background-color: transparent;
}
:deep(.row-select-bg) {
  // .arco-table-td {
  .arco-table-drag-handle {
    border-left: 2px solid rgb(var(--primary-4));
    border-right: none;

    cursor: pointer;
  }

  .arco-table-td {
    .date-space {
      .arco-space-item {
        white-space: nowrap;
      }
    }
  }
  // }
}
:deep(.row-initial) {
  .arco-table-td {
    cursor: pointer;
  }
}
:deep(.arco-table-filters) {
  right: 15px;
  :hover {
    background: transparent;
  }
}
:deep(.arco-table-cell-expand-icon .arco-table-cell-inline-icon) {
  margin-right: 4px;
  margin-left: 2px;
}
:deep(.arco-card-header-no-title) {
  padding: 0;
}
:deep(.arco-card-header-extra) {
  padding: 0;
}
@keyframes in {
  0% {
    transform: translateX(-120%);
  }
  100% {
    transform: translateX(0%);
  }
}

@keyframes out {
  0% {
    transform: translateX(120%);
  }

  100% {
    transform: translateX(0%);
  }
}
.slide-in {
  animation: in 0.5s;
}
.slide-out {
  animation: out 0.5s;
}
</style>
