<template>
  <div class="task-flat-view">
    <div class="flat-view-header">
      <h2 class="flat-view-title">{{ title }}</h2>
      <span class="task-count">({{ flattenedTasks.length }})</span>
    </div>

    <div class="flat-view-toolbar">
      <a-dropdown>
        <template #overlay>
          <a-menu @click="onStatusFilterChange">
            <a-menu-item key="all" :class="{ 'ant-dropdown-menu-item-selected': statusFilter === 'all' }">全部事项</a-menu-item>
            <a-menu-item key="completed" :class="{ 'ant-dropdown-menu-item-selected': statusFilter === 'completed' }">已完成</a-menu-item>
            <a-menu-item key="uncompleted" :class="{ 'ant-dropdown-menu-item-selected': statusFilter === 'uncompleted' }">未完成</a-menu-item>
          </a-menu>
        </template>
        <a-button size="small">
          <Icon icon="ant-design:check-circle-outlined" class="mr-1" />
          {{ statusFilterLabel }}
          <Icon icon="ant-design:down-outlined" class="ml-1" />
        </a-button>
      </a-dropdown>

      <a-dropdown>
        <template #overlay>
          <a-menu @click="onSortChange">
            <a-menu-item v-for="opt in flatSortOptions" :key="opt.value" :class="{ 'ant-dropdown-menu-item-selected': sortField === opt.value }">
              <div class="sort-menu-item">
                <span>{{ opt.label }}</span>
                <span class="sort-arrows-row">
                  <span
                    class="sort-arrow-btn"
                    :class="{ active: sortField === opt.value && sortDirection === 'asc' }"
                    @click.stop="onSortDirectionChange(opt.value, 'asc')"
                  >
                    <Icon icon="ant-design:arrow-up-outlined" />
                  </span>
                  <span
                    class="sort-arrow-btn"
                    :class="{ active: sortField === opt.value && sortDirection === 'desc' }"
                    @click.stop="onSortDirectionChange(opt.value, 'desc')"
                  >
                    <Icon icon="ant-design:arrow-down-outlined" />
                  </span>
                </span>
              </div>
            </a-menu-item>
          </a-menu>
        </template>
        <a-button size="small">
          <Icon icon="ant-design:sort-ascending-outlined" class="mr-1" />
          排序: {{ currentSortLabel }}
          <Icon icon="ant-design:down-outlined" class="ml-1" />
        </a-button>
      </a-dropdown>

      <a-popover v-model:open="fieldConfigVisible" placement="bottomRight" trigger="click">
        <template #content>
          <div class="field-config-panel">
            <div class="field-config-title">字段配置</div>
            <div v-for="field in FIELD_CONFIG" :key="field.key" class="field-config-item" @click="toggleField(field.key)">
              <span>{{ field.label }}</span>
              <Icon
                :icon="visibleFields.includes(field.key) ? 'ant-design:eye-outlined' : 'ant-design:eye-invisible-outlined'"
                :class="visibleFields.includes(field.key) ? 'field-visible' : 'field-hidden'"
              />
            </div>
          </div>
        </template>
        <a-button size="small">
          <Icon icon="ant-design:setting-outlined" class="mr-1" />
          字段配置
        </a-button>
      </a-popover>
    </div>

    <div class="flat-view-body">
      <div class="flat-view-table-header" :style="{ minWidth: totalFieldsWidth + 'px' }">
        <div class="table-col table-col-drag-handle"></div>
        <div class="table-col table-col-title">
          <Icon icon="tasklist-title|svg" class="header-icon" />
          <span class="header-label">事项标题</span>
        </div>
        <template v-for="field in visibleFieldConfigs" :key="field.key">
          <div class="table-col header-col" :style="{ width: fieldWidthMap[field.key] || '100px' }">
            <Icon v-if="field.key === 'priority'" icon="tasklist-priority|svg" class="header-icon" />
            <Icon
              v-else-if="
                field.key === 'assigneeName' ||
                field.key === 'assignName' ||
                field.key === 'participantName' ||
                field.key === 'followersName' ||
                field.key === 'createBy'
              "
              icon="tasklist-user|svg"
              class="header-icon"
            />
            <Icon v-else-if="field.key === 'startTime' || field.key === 'endTime'" icon="tasklist-time|svg" class="header-icon" />
            <Icon v-else :icon="fieldIconMap[field.key]" class="header-icon" />
            <span class="header-label">{{ field.label }}</span>
          </div>
        </template>
      </div>

      <div v-for="ft in flattenedTasks" :key="ft.task.id" class="task-row" :style="{ minWidth: totalFieldsWidth + 'px' }">
        <div class="table-col table-col-drag-handle"></div>
        <div class="table-col table-col-title" @click.stop="emit('task-click', ft.task.id)">
          <div class="task-indent" :style="{ marginLeft: Math.min(ft.level, 4) * 20 + 'px' }">
            <span v-if="ft.task.childCount > 0" class="expand-arrow" @click.stop="toggleTaskExpand(ft.task.id)">
              <Icon :icon="expandedTaskIds.has(ft.task.id) ? 'ant-design:caret-down-outlined' : 'ant-design:caret-right-outlined'" />
            </span>
            <span v-else class="expand-arrow-placeholder"></span>
            <button
              class="task-checkbox"
              :class="{ checked: ft.task.completed }"
              :disabled="!canEditTask(ft.task)"
              @click.stop="canEditTask(ft.task) && emit('toggle-task', ft.task.id)"
            >
              <Icon v-if="ft.task.completed" icon="ant-design:check-outlined" />
            </button>
          </div>
          <span class="task-title" :class="{ completed: ft.task.completed }">{{ ft.task.taskName }}</span>
          <span v-if="ft.task.childCount > 0" class="task-child-count">
            <Icon icon="tasklist-subtask|svg" class="child-count-icon" />
            {{ ft.task.completedChildCount }}/{{ ft.task.childCount }}
          </span>
        </div>

        <template v-for="field in visibleFieldConfigs" :key="field.key">
          <div class="table-col task-field" :style="{ width: fieldWidthMap[field.key] || '100px' }">
            <template v-if="field.key === 'priority'">
              <a-dropdown
                v-if="canEditTask(ft.task)"
                :trigger="['click']"
                :get-popup-container="getPopupContainer"
                :overlay-style="{ minWidth: '100px' }"
              >
                <div class="cell-inner editable-cell dropdown-cell">
                  <span
                    v-if="ft.task.priority"
                    class="priority-tag"
                    :class="{ 'task-field-completed': ft.task.completed }"
                    :style="{ backgroundColor: getPriorityBg(ft.task.priority), color: '#1f2329' }"
                    >{{ getPriorityLabel(ft.task.priority) }}</span
                  >
                  <span v-else class="field-placeholder">-</span>
                </div>
                <template #overlay>
                  <a-menu @click="({ key }) => onPriorityChange(ft.task.id, key)">
                    <a-menu-item v-for="opt in PRIORITY_OPTIONS" :key="opt.value" class="priority-menu-item">
                      <span class="priority-tag" :style="{ backgroundColor: getPriorityBg(opt.value), color: '#1f2329' }">
                        {{ opt.label }}
                      </span>
                    </a-menu-item>
                  </a-menu>
                </template>
              </a-dropdown>
              <div v-else class="cell-inner">
                <span
                  v-if="ft.task.priority"
                  class="priority-tag"
                  :class="{ 'task-field-completed': ft.task.completed }"
                  :style="{ backgroundColor: getPriorityBg(ft.task.priority), color: '#1f2329' }"
                  >{{ getPriorityLabel(ft.task.priority) }}</span
                >
                <span v-else class="field-placeholder">-</span>
              </div>
            </template>

            <template v-else-if="field.key === 'assigneeName'">
              <div v-if="canEditTask(ft.task)" class="cell-inner editable-cell" @click.stop="openUserSelectModal('assignee', ft.task.id)">
                <template v-if="ft.task.assigneeName">
                  <AvatarDisplay :names="ft.task.assigneeName" :size="24" :completed="ft.task.completed" />
                </template>
                <template v-else>
                  <span class="field-icon-placeholder" :class="{ 'task-field-completed': ft.task.completed }">
                    <Icon icon="tasklist-add-user|svg" />
                  </span>
                </template>
              </div>
              <div v-else class="cell-inner">
                <template v-if="ft.task.assigneeName">
                  <AvatarDisplay :names="ft.task.assigneeName" :size="24" :completed="ft.task.completed" />
                </template>
                <span v-else class="field-placeholder">-</span>
              </div>
            </template>

            <template v-else-if="field.key === 'participantName'">
              <div v-if="canEditTask(ft.task)" class="cell-inner editable-cell" @click.stop="openUserSelectModal('participant', ft.task.id)">
                <template v-if="ft.task.participantName">
                  <AvatarDisplay :names="ft.task.participantName" :size="24" :completed="ft.task.completed" />
                </template>
                <template v-else>
                  <span class="field-icon-placeholder" :class="{ 'task-field-completed': ft.task.completed }">
                    <Icon icon="tasklist-add-user|svg" />
                  </span>
                </template>
              </div>
              <div v-else class="cell-inner">
                <template v-if="ft.task.participantName">
                  <AvatarDisplay :names="ft.task.participantName" :size="24" :completed="ft.task.completed" />
                </template>
                <span v-else class="field-placeholder">-</span>
              </div>
            </template>

            <template v-else-if="field.key === 'followersName'">
              <div v-if="canEditTask(ft.task)" class="cell-inner editable-cell" @click.stop="openUserSelectModal('followers', ft.task.id)">
                <template v-if="ft.task.followersName">
                  <AvatarDisplay :names="ft.task.followersName" :size="24" :completed="ft.task.completed" />
                </template>
                <template v-else>
                  <span class="field-icon-placeholder" :class="{ 'task-field-completed': ft.task.completed }">
                    <Icon icon="tasklist-add-user|svg" />
                  </span>
                </template>
              </div>
              <div v-else class="cell-inner">
                <template v-if="ft.task.followersName">
                  <AvatarDisplay :names="ft.task.followersName" :size="24" :completed="ft.task.completed" />
                </template>
                <span v-else class="field-placeholder">-</span>
              </div>
            </template>

            <template v-else-if="field.key === 'startTime' || field.key === 'endTime'">
              <div
                class="cell-inner date-cell-wrapper"
                :class="{ 'editable-cell': canEditTask(ft.task) }"
                @click.stop="canEditTask(ft.task) && !datePickerVisible && startEditCell(ft.task.id, field.key)"
              >
                <a-date-picker
                  v-if="editingCell?.taskId === ft.task.id && editingCell?.field === field.key"
                  :value="getEditingDate(field.key)"
                  :open="datePickerVisible"
                  placeholder="选择日期"
                  format="YYYY-MM-DD"
                  :allow-clear="true"
                  :disabled-date="field.key === 'endTime' ? getDisabledEndDate(ft.task.id) : undefined"
                  class="inline-date-picker"
                  @change="(date: any) => onDateCellChange(ft.task.id, date, field.key)"
                  @open-change="onCellPickerOpenChange"
                >
                  <template #renderExtraFooter>
                    <div style="text-align: right">
                      <a-button type="link" size="small" danger @click.stop="clearDateCell(ft.task.id, field.key)">清除</a-button>
                    </div>
                  </template>
                </a-date-picker>
                <template v-else>
                  <template v-if="(field.key === 'startTime' && ft.task.startTime) || (field.key === 'endTime' && ft.task.endTime)">
                    <span
                      class="field-value"
                      :class="{
                        'task-field-completed': ft.task.completed,
                        'overdue-date': field.key === 'endTime' && isOverdue(ft.task),
                      }"
                    >
                      {{ field.key === 'startTime' ? ft.task.startTime : ft.task.endTime }}
                    </span>
                  </template>
                  <template v-else>
                    <span class="field-icon-placeholder" :class="{ 'task-field-completed': ft.task.completed }">
                      <Icon icon="tasklist-calendar|svg" />
                    </span>
                  </template>
                </template>
              </div>
            </template>

            <template v-else-if="field.key === 'completeTime'">
              <div class="cell-inner readonly-cell">
                <span v-if="ft.task.completeTime" class="field-value" :class="{ 'task-field-completed': ft.task.completed }">
                  {{ ft.task.completeTime.substring(0, 10) }}
                </span>
                <span v-else class="field-placeholder">-</span>
              </div>
            </template>

            <template v-else-if="field.key === 'subTaskProgress'">
              <div class="cell-inner readonly-cell">
                <div v-if="ft.task.childCount > 0" class="progress-cell">
                  <div class="progress-bar">
                    <div
                      class="progress-bar-fill"
                      :style="{
                        width: (ft.task.completedChildCount / ft.task.childCount) * 100 + '%',
                        background: ft.task.completedChildCount > 0 ? '#52c41a' : '#1677ff',
                      }"
                    ></div>
                  </div>
                </div>
                <span v-else :class="{ 'task-field-completed': ft.task.completed }">-</span>
              </div>
            </template>

            <template v-else-if="field.key === 'remark'">
              <div class="cell-inner">
                <span v-if="ft.task.remark" class="field-value" :class="{ 'task-field-completed': ft.task.completed }" :title="ft.task.remark">
                  {{ ft.task.remark.length > 20 ? ft.task.remark.substring(0, 20) + '...' : ft.task.remark }}
                </span>
                <span v-else class="field-placeholder">-</span>
              </div>
            </template>

            <template v-else-if="field.key === 'assignName' || field.key === 'createBy'">
              <div class="cell-inner readonly-cell">
                <template v-if="getFieldValue(ft.task, field.key)">
                  <AvatarDisplay :names="getFieldValue(ft.task, field.key)" :size="24" :completed="ft.task.completed" />
                </template>
                <span v-else class="field-placeholder">-</span>
              </div>
            </template>

            <template v-else-if="field.key === 'taskDesc' || field.key === 'listName'">
              <div class="cell-inner readonly-cell">
                <span v-if="getFieldValue(ft.task, field.key)" class="field-value">{{ getFieldValue(ft.task, field.key) }}</span>
                <span v-else class="field-placeholder">-</span>
              </div>
            </template>

            <template v-else>
              <div class="cell-inner">
                <span :class="{ 'task-field-completed': ft.task.completed }">{{ getFieldValue(ft.task, field.key) }}</span>
              </div>
            </template>
          </div>
        </template>
      </div>

      <div v-if="flattenedTasks.length === 0" class="empty-state">
        <Icon icon="ant-design:inbox-outlined" class="empty-icon" />
        <p>暂无事项</p>
      </div>
    </div>

    <UserSelectModal
      ref="userSelectModalRef"
      :title="userSelectModalType === 'assignee' ? '选择负责人' : userSelectModalType === 'participant' ? '选择参与人' : '选择关注人'"
      :user-ids="userSelectModalCurrentIds"
      :user-names="userSelectModalCurrentNames"
      :multiple="true"
      @confirm="onUserSelectConfirm"
    />
  </div>
</template>

<script lang="ts" setup>
  import { ref, computed, nextTick } from 'vue';
  import dayjs from 'dayjs';
  import Icon from '/@/components/Icon/index';
  import AvatarDisplay from './AvatarDisplay.vue';
  import UserSelectModal from './UserSelectModal.vue';
  import { FIELD_CONFIG, SORT_OPTIONS, MAX_TASK_DEPTH } from '../types';
  import { PRIORITY_OPTIONS, getPriorityBg, getPriorityLabel, isOverdue } from '../utils/taskUtils';
  import type { TaskItem, StatusFilter, SortField, SortDirection, FieldKey, FlatTaskItem } from '../types';

  const props = defineProps<{
    title: string;
    tasks: TaskItem[];
    statusFilter: StatusFilter;
    sortField: SortField;
    sortDirection: SortDirection;
    visibleFields: FieldKey[];
    editable?: boolean;
    taskEditMap?: Map<string, boolean>;
  }>();

  const emit = defineEmits<{
    'toggle-task': [taskId: string];
    'task-click': [taskId: string];
    'update-task-field': [taskId: string, field: string, value: any];
    'update-task-fields': [taskId: string, fields: Record<string, any>];
    'update:statusFilter': [value: StatusFilter];
    'update:sortField': [value: SortField];
    'update:sortDirection': [value: SortDirection];
    'update:visibleFields': [value: FieldKey[]];
    'load-subtasks': [taskId: string, mainId: string];
  }>();

  const fieldConfigVisible = ref(false);
  const expandedTaskIds = ref<Set<string>>(new Set());
  const loadedChildrenIds = ref<Set<string>>(new Set());

  const visibleFieldConfigs = computed(() => {
    return FIELD_CONFIG.filter((f) => props.visibleFields.includes(f.key));
  });

  const flatSortOptions = computed(() => {
    return SORT_OPTIONS.filter((o) => o.value !== 'sortOrder');
  });

  const fieldWidthMap: Record<string, string> = {
    listName: '140px',
    taskDesc: '140px',
    priority: '120px',
    assigneeName: '120px',
    assignName: '120px',
    participantName: '120px',
    followersName: '120px',
    createBy: '120px',
    startTime: '180px',
    endTime: '180px',
    completeTime: '140px',
    createTime: '160px',
    updateTime: '160px',
    remark: '160px',
    subTaskProgress: '110px',
  };

  const fieldIconMap: Record<string, string> = {
    taskDesc: 'ant-design:align-left-outlined',
    priority: 'ant-design:flag-outlined',
    assigneeName: 'inline-user',
    assignName: 'inline-user',
    participantName: 'inline-user',
    followersName: 'inline-user',
    createBy: 'inline-user',
    startTime: 'ant-design:calendar-outlined',
    endTime: 'ant-design:clock-circle-outlined',
    completeTime: 'ant-design:check-circle-outlined',
    createTime: 'ant-design:plus-circle-outlined',
    updateTime: 'ant-design:sync-outlined',
    remark: 'ant-design:file-text-outlined',
    subTaskProgress: 'ant-design:pie-chart-outlined',
    listName: 'ant-design:file-text-outlined',
  };

  const totalFieldsWidth = computed(() => {
    let w = 400 + 40;
    for (const f of visibleFieldConfigs.value) {
      w += parseInt(fieldWidthMap[f.key] || '100', 10);
    }
    return w + 48;
  });

  const statusFilterLabel = computed(() => {
    const map: Record<StatusFilter, string> = { all: '全部事项', completed: '已完成', uncompleted: '未完成' };
    return map[props.statusFilter];
  });

  const currentSortLabel = computed(() => {
    const opt = flatSortOptions.value.find((o) => o.value === props.sortField);
    if (opt) return opt.label;
    const allOpt = SORT_OPTIONS.find((o) => o.value === props.sortField);
    return allOpt ? allOpt.label : '';
  });

  const allTaskMap = computed(() => {
    const map = new Map<string, TaskItem>();
    for (const t of props.tasks) {
      map.set(t.id, t);
    }
    return map;
  });

  const flatSortedTasks = computed(() => {
    let result = [...props.tasks];

    if (props.statusFilter === 'completed') {
      result = result.filter((t) => t.completed);
    } else if (props.statusFilter === 'uncompleted') {
      result = result.filter((t) => !t.completed);
    }

    const dir = props.sortDirection === 'asc' ? 1 : -1;
    result.sort((a, b) => {
      const va = (a as any)[props.sortField] || '';
      const vb = (b as any)[props.sortField] || '';
      if (va < vb) return -1 * dir;
      if (va > vb) return 1 * dir;
      return 0;
    });

    return result;
  });

  const flattenedTasks = computed(() => {
    const result: FlatTaskItem[] = [];
    const visited = new Set<string>();

    for (const task of flatSortedTasks.value) {
      if (visited.has(task.id)) continue;
      if (!task.pid || task.pid === task.groupId || !allTaskMap.value.has(task.pid)) {
        collectFlatTasks(task, 0, result, visited);
      }
    }

    return result;
  });

  function collectFlatTasks(task: TaskItem, level: number, result: FlatTaskItem[], visited: Set<string>) {
    if (visited.has(task.id)) return;
    if (level >= MAX_TASK_DEPTH) return;
    visited.add(task.id);
    result.push({ task, level });
    if (task.childCount > 0 && expandedTaskIds.value.has(task.id)) {
      const childTasks = props.tasks.filter((t) => t.pid === task.id);
      const sorted = [...childTasks].sort((a, b) => (a.sortOrder ?? 0) - (b.sortOrder ?? 0));
      for (const child of sorted) {
        collectFlatTasks(child, level + 1, result, visited);
      }
    }
  }

  function toggleTaskExpand(taskId: string) {
    const newSet = new Set(expandedTaskIds.value);
    if (newSet.has(taskId)) {
      newSet.delete(taskId);
      expandedTaskIds.value = newSet;
    } else {
      newSet.add(taskId);
      expandedTaskIds.value = newSet;
      const task = props.tasks.find((t) => t.id === taskId);
      if (task && task.childCount > 0 && !loadedChildrenIds.value.has(taskId) && task.mainId) {
        loadedChildrenIds.value = new Set([...loadedChildrenIds.value, taskId]);
        emit('load-subtasks', taskId, task.mainId);
      }
    }
  }

  function canEditTask(task: TaskItem): boolean {
    if (!props.editable && !props.taskEditMap) return false;
    if (props.editable) return true;
    if (props.taskEditMap) return props.taskEditMap.has(task.id);
    return false;
  }

  function getFieldValue(task: TaskItem, key: FieldKey): string {
    return (task as any)[key] || '';
  }

  function getPopupContainer() {
    return document.body;
  }

  function onStatusFilterChange({ key }: { key: string }) {
    emit('update:statusFilter', key as StatusFilter);
  }

  function onSortChange({ key }: { key: string }) {
    if (props.sortField === key) {
      emit('update:sortDirection', props.sortDirection === 'asc' ? 'desc' : 'asc');
    } else {
      emit('update:sortField', key as SortField);
      emit('update:sortDirection', 'desc');
    }
  }

  function onSortDirectionChange(field: string, dir: string) {
    emit('update:sortField', field as SortField);
    emit('update:sortDirection', dir as SortDirection);
  }

  function toggleField(fieldKey: FieldKey) {
    const fields = [...props.visibleFields];
    const idx = fields.indexOf(fieldKey);
    if (idx >= 0) {
      fields.splice(idx, 1);
    } else {
      fields.push(fieldKey);
    }
    emit('update:visibleFields', fields);
  }

  function onPriorityChange(taskId: string, value: any) {
    if (value !== undefined && value !== null) {
      emit('update-task-field', taskId, 'priority', value);
    }
  }

  const editingCell = ref<{ taskId: string; field: string } | null>(null);
  const datePickerVisible = ref(false);

  function startEditCell(taskId: string, field: string) {
    editingCell.value = { taskId, field };
    datePickerVisible.value = true;
  }

  function cancelEdit() {
    editingCell.value = null;
    datePickerVisible.value = false;
  }

  function getEditingDate(fieldKey: string) {
    const taskId = editingCell.value?.taskId;
    if (!taskId) return null;
    const task = props.tasks.find((t) => t.id === taskId);
    if (!task) return null;
    const val = fieldKey === 'startTime' ? task.startTime : task.endTime;
    return val ? dayjs(val.substring(0, 10)) : null;
  }

  function getTaskField(taskId: string, field: string): string {
    const task = props.tasks.find((t) => t.id === taskId);
    if (!task) return '';
    return (task as any)[field] || '';
  }

  function getDisabledEndDate(taskId: string) {
    return (current: any) => {
      if (!current) return false;
      const start = getTaskField(taskId, 'startTime');
      if (!start) return false;
      return dayjs(current).isBefore(dayjs(start), 'day');
    };
  }

  function onDateCellChange(taskId: string, date: any, fieldKey: string) {
    const task = props.tasks.find((t) => t.id === taskId);
    const value = date ? dayjs(date).format('YYYY-MM-DD') + ' 00:00:00' : '';
    const updates: Record<string, string> = {};
    if (fieldKey === 'startTime') {
      updates.startTime = value;
      updates.endTime = normalizeDate(task?.endTime);
    } else if (fieldKey === 'endTime') {
      updates.startTime = normalizeDate(task?.startTime);
      updates.endTime = value;
    }
    emit('update-task-fields', taskId, updates);
    cancelEdit();
  }

  function clearDateCell(taskId: string, fieldKey: string) {
    const task = props.tasks.find((t) => t.id === taskId);
    const updates: Record<string, string> = {};
    if (fieldKey === 'startTime') {
      updates.startTime = '';
      updates.endTime = normalizeDate(task?.endTime);
    } else if (fieldKey === 'endTime') {
      updates.startTime = normalizeDate(task?.startTime);
      updates.endTime = '';
    }
    emit('update-task-fields', taskId, updates);
    cancelEdit();
  }

  function onCellPickerOpenChange(open: boolean) {
    if (!open) {
      setTimeout(() => {
        if (editingCell.value) {
          cancelEdit();
        }
      }, 100);
    }
  }

  function normalizeDate(val: string | null | undefined): string {
    if (!val) return '';
    if (val.length >= 19) return val.substring(0, 19);
    return val.substring(0, 10) + ' 00:00:00';
  }

  const userSelectModalRef = ref();
  const userSelectModalType = ref<'assignee' | 'followers' | 'participant'>('assignee');
  const userSelectModalTaskId = ref('');
  const userSelectModalCurrentIds = ref('');
  const userSelectModalCurrentNames = ref('');

  function openUserSelectModal(type: 'assignee' | 'followers' | 'participant', taskId: string) {
    userSelectModalType.value = type;
    userSelectModalTaskId.value = taskId;

    const task = props.tasks.find((t) => t.id === taskId);
    if (type === 'assignee') {
      userSelectModalCurrentIds.value = task?.assigneeId || '';
      userSelectModalCurrentNames.value = task?.assigneeName || '';
    } else if (type === 'participant') {
      userSelectModalCurrentIds.value = task?.participantId || '';
      userSelectModalCurrentNames.value = task?.participantName || '';
    } else {
      userSelectModalCurrentIds.value = task?.followersId || '';
      userSelectModalCurrentNames.value = task?.followersName || '';
    }

    nextTick(() => {
      userSelectModalRef.value?.open();
    });
  }

  function onUserSelectConfirm(userIds: string, userNames: string) {
    const type = userSelectModalType.value;
    const taskId = userSelectModalTaskId.value;
    if (taskId) {
      if (type === 'assignee') {
        emit('update-task-fields', taskId, { assigneeId: userIds, assigneeName: userNames });
      } else if (type === 'participant') {
        emit('update-task-fields', taskId, { participantId: userIds, participantName: userNames });
      } else {
        emit('update-task-fields', taskId, { followersId: userIds, followersName: userNames });
      }
    }
  }
</script>

<style lang="less" scoped>
  .task-flat-view {
    flex: 1;
    height: 100%;
    background: #fff;
    display: flex;
    flex-direction: column;
    overflow: hidden;
  }

  .flat-view-header {
    padding: 16px 24px;
    border-bottom: 1px solid #f0f0f0;
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
  }

  .flat-view-title {
    margin: 0;
    font-size: 18px;
    font-weight: 600;
    color: #1f1f1f;
  }

  .task-count {
    font-size: 14px;
    color: #8f959e;
  }

  .flat-view-toolbar {
    padding: 8px 24px;
    border-bottom: 1px solid #f0f0f0;
    display: flex;
    gap: 8px;
    align-items: center;
    flex-wrap: wrap;
    flex-shrink: 0;
  }

  .flat-view-body {
    flex: 1;
    overflow: auto;
  }

  .flat-view-table-header {
    padding: 0 8px;
    height: 40px;
    background: #fafafa;
    border-bottom: 1px solid #e5e6eb;
    display: flex;
    align-items: stretch;
    font-size: 14px;
    color: #1f2329;
    font-weight: 500;
    flex-shrink: 0;
    position: sticky;
    top: 0;
    z-index: 10;

    .header-col {
      padding: 0 12px;
      gap: 4px;
      box-sizing: border-box;
    }

    .header-icon {
      color: #8f959e;
      font-size: 14px;
      flex-shrink: 0;
    }

    .header-label {
      white-space: nowrap;
      overflow: visible;
    }
  }

  .table-col {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    height: 100%;
  }

  .table-col-drag-handle {
    width: 24px;
    min-width: 24px;
    justify-content: center;
  }

  .table-col-title {
    width: 400px;
    min-width: 400px;
    height: 100%;
    display: flex;
    align-items: center;
    gap: 8px;
  }

  .task-indent {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
  }

  .expand-arrow {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    font-size: 11px;
    color: #999;
    cursor: pointer;
    border-radius: 2px;
    flex-shrink: 0;

    &:hover {
      color: #1677ff;
      background: #e6f4ff;
    }
  }

  .expand-arrow-placeholder {
    width: 16px;
    height: 16px;
  }

  .task-row {
    display: flex;
    align-items: stretch;
    height: 46px;
    padding: 0 8px;
    border-bottom: 1px solid #f0f0f0;
    font-size: 14px;
    box-sizing: border-box;
    cursor: pointer;

    &:hover {
      background: #f5f6f7;
    }
  }

  .task-checkbox {
    width: 18px;
    height: 18px;
    border-radius: 50%;
    border: 2px solid #d9d9d9;
    background: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.2s;
    padding: 0;
    flex-shrink: 0;

    &:hover {
      border-color: #52c41a;
    }

    &.checked {
      background: #52c41a;
      border-color: #52c41a;
      color: #fff;
      font-size: 11px;
    }

    &:disabled {
      cursor: not-allowed;
      opacity: 0.5;

      &:hover {
        border-color: #d9d9d9;
      }
    }
  }

  .task-title {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: #1f2329;
    flex-shrink: 1;
    min-width: 0;
    padding: 2px 6px;
    border-radius: 4px;
    transition: background 0.15s;

    &.completed {
      text-decoration: line-through;
      color: #c0c4cc;
    }
  }

  .task-row:hover .task-title {
    background: #fff;
  }

  .task-child-count {
    font-size: 11px;
    color: #8c8c8c;
    margin-left: 6px;
    white-space: nowrap;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: 2px;
  }

  .child-count-icon {
    font-size: 12px;
    color: #8f959e;
  }

  .task-field {
    color: #646a73;
    overflow: visible;
    padding: 0;
    box-sizing: border-box;
  }

  .task-field-completed {
    color: #c0c4cc;
  }

  .overdue-date {
    color: #f5222d !important;
    font-weight: 500;
  }

  .cell-inner {
    display: flex;
    align-items: center;
    width: 100%;
    height: 100%;
    padding: 0 12px;
    border: 1px solid transparent;
    border-radius: 4px;
    transition: border-color 0.15s;
    box-sizing: border-box;

    &:hover {
      border-color: #d0d3d6;
    }
  }

  .date-cell-wrapper {
    position: relative;
  }

  .inline-date-picker {
    width: 100% !important;

    :deep(.ant-picker) {
      width: 100%;
    }
  }

  .editable-cell {
    cursor: pointer;
  }

  .dropdown-cell {
    position: relative;

    &::after {
      content: '';
      position: absolute;
      right: 6px;
      top: 50%;
      transform: translateY(-50%);
      border: 4px solid transparent;
      border-top-color: #999;
      opacity: 0;
      transition: opacity 0.15s;
      pointer-events: none;
    }

    &:hover::after {
      opacity: 1;
    }
  }

  .readonly-cell {
    &:hover {
      border-color: transparent;
    }
  }

  .field-value {
    color: #646a73;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .field-placeholder {
    color: #c0c4cc;
    font-size: 14px;
  }

  .field-icon-placeholder {
    color: #8f959e;
    font-size: 16px;
    display: flex;
    align-items: center;
    transition: color 0.15s;

    &:hover {
      color: #3370ff;
    }
  }

  .priority-tag {
    display: inline-block;
    padding: 1px 8px;
    border-radius: 4px;
    font-size: 14px;
    line-height: 20px;
    white-space: nowrap;
    font-weight: 500;

    &.task-field-completed {
      opacity: 0.5;
    }
  }

  .priority-menu-item {
    display: flex;
    align-items: center;
    min-height: 32px;
  }

  .progress-cell {
    display: flex;
    align-items: center;
  }

  .progress-bar {
    width: 60px;
    height: 6px;
    background: #f0f0f0;
    border-radius: 3px;
    overflow: hidden;
  }

  .progress-bar-fill {
    height: 100%;
    border-radius: 3px;
    transition: width 0.3s ease;
  }

  .sort-menu-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 160px;
  }

  .sort-arrows-row {
    display: flex;
    align-items: center;
    gap: 4px;
  }

  .sort-arrow-btn {
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    border-radius: 4px;
    color: #bfbfbf;
    font-size: 14px;
    transition:
      color 0.15s,
      background 0.15s;

    &.active {
      color: #1677ff;
      background: #e6f4ff;
    }

    &:hover {
      color: #1677ff;
    }
  }

  .field-config-panel {
    .field-config-title {
      font-weight: 600;
      margin-bottom: 8px;
      padding-bottom: 8px;
      border-bottom: 1px solid #f0f0f0;
    }

    .field-config-item {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 6px 4px;
      cursor: pointer;
      border-radius: 4px;

      &:hover {
        background: #f5f5f5;
      }
    }

    .field-visible {
      color: #1677ff;
    }

    .field-hidden {
      color: #d9d9d9;
    }
  }

  .empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 60px 24px;
    color: #bbb;

    .empty-icon {
      font-size: 48px;
      margin-bottom: 12px;
    }

    p {
      margin: 0;
      font-size: 14px;
    }
  }

  .mr-1 {
    margin-right: 4px;
  }

  .ml-1 {
    margin-left: 4px;
  }
</style>
