<template>
  <div class="frame-body adaption-frame-body task-page">
    <div class="frame-card">
      <div class="frame-card-header border-radius" :style="{ minHeight: viewType === 1 ? '110px' : '56px' }">
        <div class="frame-search">
          <el-form :inline="true" :model="search" class="demo-form-inline">
            <div class="search-line">
              <div class="item2">
                <el-form-item>
                  <el-input
                    v-model="kws"
                    placeholder="请输入关键字"
                    clearable
                    @keyup.enter="keydownSearch"
                    @blur="keydownSearch"
                  />
                </el-form-item>
                <el-form-item>
                  <el-select v-model="search.searchType" placeholder="全部状态" clearable @change="onSearch">
                    <el-option v-for="item in searchTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
                  </el-select>
                </el-form-item>
                <el-form-item>
                  <el-select
                    v-model="search.status"
                    multiple
                    collapse-tags
                    collapse-tags-tooltip
                    placeholder="全部状态"
                    style="width: 160px"
                    @change="onSearch"
                  >
                    <el-option label="未开始" value="1" />
                    <el-option label="进行中" value="2" />
                    <el-option label="已完成" value="3" />
                    <el-option label="已逾期" value="5" />
                  </el-select>
                </el-form-item>
                <el-form-item v-if="viewType === 3">
                  <el-date-picker
                    v-model="dt2"
                    type="daterange"
                    value-format="YYYY-MM-DD"
                    start-placeholder="开始时间"
                    end-placeholder="结束时间"
                    :clearable="false"
                    @change="handleChangeTime"
                  />
                </el-form-item>
                <el-form-item v-if="viewType === 1">
                  <el-date-picker
                    v-if="toggleActive === 'day'"
                    v-model="dt"
                    type="date"
                    value-format="YYYY-MM-DD"
                    placeholder="选择日期"
                    :clearable="false"
                    @change="handleChangeTime"
                  />
                  <el-date-picker
                    v-else-if="toggleActive === 'week'"
                    v-model="dt"
                    type="week"
                    format="YYYY 第 WW 周"
                    value-format="YYYY-MM-DD"
                    placeholder="选择日期"
                    :clearable="false"
                    @change="handleChangeTime"
                  />
                  <el-date-picker
                    v-else
                    v-model="dt"
                    type="month"
                    value-format="YYYY-MM"
                    placeholder="选择日期"
                    :clearable="false"
                    @change="handleChangeTime"
                  />
                </el-form-item>
                <el-form-item>
                  <el-button type="primary" @click="reset">重置</el-button>
                </el-form-item>
              </div>
              <div class="item3">
                <el-form-item>
                  <span class="search-right">
                    <el-button
                      circle
                      :type="viewType === 3 ? 'primary' : undefined"
                      style="margin-right: 20px"
                      @click="setViewType(3)"
                    >
                      <el-icon><Tickets /></el-icon>
                    </el-button>
                    <el-button
                      circle
                      :type="viewType === 1 ? 'primary' : undefined"
                      style="margin-right: 20px"
                      @click="setViewType(1)"
                    >
                      <el-icon><OfficeBuilding /></el-icon>
                    </el-button>
                    <el-button type="primary" style="margin-right: 20px" @click="delTasks">批量删除</el-button>
                    <el-button type="primary" @click="openDialogForm">新建任务</el-button>
                  </span>
                </el-form-item>
              </div>
            </div>
            <div v-if="viewType === 1" class="search-line search-line-toggle">
              <div class="item1">
                <el-form-item>
                  <div class="toggle-group">
                    <button
                      v-for="item in toggleData"
                      :key="item.value"
                      type="button"
                      class="toggle-btn"
                      :class="{ 'is-active': toggleActive === item.value }"
                      @click="handleChangeType(item.value)"
                    >
                      {{ item.label }}
                    </button>
                  </div>
                </el-form-item>
              </div>
            </div>
          </el-form>
        </div>
      </div>

      <template v-if="viewType === 1">
        <div class="frame-card calendar-card">
          <div class="frame-card-content">
            <div v-if="toggleActive === 'day'" class="calendar-day-view">
              <div class="calendar-header">
                <div class="column-time">周次{{ dayInfo.week }}</div>
                <div class="column-content">{{ dayInfo.weekdayLabel }} {{ dayInfo.day }}</div>
              </div>
              <div class="calendar-content-list">
                <div class="calendar-item">
                  <div class="column-time">全天</div>
                  <div class="column-content"></div>
                </div>
                <div v-for="slot in daySlots" :key="slot.time" class="calendar-item">
                  <div class="column-time">{{ slot.time }}</div>
                  <div class="column-content">
                    <div v-if="!slot.data.length" class="calendar-empty">暂无任务</div>
                    <div v-for="row in slot.data" :key="row.taskDateId || row.id" class="calendar-task-chip" @click="goDetail(row)">
                      <span class="calendar-task-chip__title" v-html="row.title || row.name"></span>
                      <span class="calendar-task-chip__meta">{{ formatPercent(row.percent) }}</span>
                    </div>
                  </div>
                </div>
              </div>
            </div>

            <div v-else-if="toggleActive === 'week'" class="calendar-week-view">
              <div class="calendar-week-header">
                <div v-for="item in weekData" :key="item.dayKey" class="column-week">{{ item.day }}({{ item.weekdayLabel }})</div>
              </div>
              <div class="calendar-week-body">
                <div v-for="item in weekData" :key="item.dayKey" class="calendar-week-column">
                  <div v-if="!item.data.length" class="calendar-empty">暂无任务</div>
                  <div v-for="row in item.data" :key="row.taskDateId || row.id" class="summary-card" @click="goDetail(row)">
                    <span class="summary-card__line" :class="`priority-${formatPriority(row.priorityType)}`"></span>
                    <div class="summary-card__title" v-html="row.title || row.name"></div>
                    <div class="summary-card__meta">{{ row.dateName || row.deadline || '-' }}</div>
                  </div>
                </div>
              </div>
            </div>

            <div v-else class="calendar-month-view">
              <div class="calendar-month-header">
                <div v-for="label in monthWeekLabels" :key="label" class="column-week">{{ label }}</div>
              </div>
              <div class="calendar-month-grid">
                <div v-for="item in monthData" :key="item.dayKey" class="calendar-month-cell">
                  <div class="column-day">
                    <span class="day">{{ item.day }}</span>
                  </div>
                  <div class="column-week month-task-list">
                    <div v-if="!item.data.length" class="calendar-empty">暂无任务</div>
                    <div v-for="row in item.data.slice(0, 3)" :key="row.taskDateId || row.id" class="summary-card summary-card--month" @click="goDetail(row)">
                      <span class="summary-card__line" :class="`priority-${formatPriority(row.priorityType)}`"></span>
                      <div class="summary-card__title" v-html="row.title || row.name"></div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </template>

      <div v-else class="frame-card-content table-area">
        <div class="calendar-day h-100">
          <div class="target_list h-100">
                        <div class="list-header">
              <div class="name-col">
                <el-checkbox
                  v-model="checkouts"
                  :disabled="allDisabled"
                  style="padding: 0 10px"
                  :indeterminate="allIndeterminate"
                  @change="checkAllIn"
                />
                任务名称
              </div>

              <div class="person-col">执行人</div>
              <div class="progress-col">进度</div>
              <div class="person-col">状态</div>
              <div class="time-col">任务时间</div>
              <div class="person-col">来源</div>
              <div class="handle-col">操作</div>
            </div>

            <div ref="cardContentRef" class="card-content" v-loading="loading">
              <div v-for="item in pageData" :key="item.taskDateId || item.id" class="card-box">
                <div class="card-row-main">
                  <div class="icon-col">
                    <el-icon v-if="item.sonTasks && item.sonTasks.length" class="expand-icon" :class="{ 'is-close': !item.show }" @click="item.show = !item.show">
                      <ArrowDown />
                    </el-icon>
                  </div>
                  <div class="box-target-col text-overflow">
                    <el-checkbox
                      v-model="item.checks"
                      :disabled="!item.isEditable"
                      :indeterminate="item.indeterminate"
                      style="padding-right: 10px"
                      @change="checkChange(item)"
                    />
                    <p class="title" v-html="item.title || item.name" @click="goDetail(item)"></p>
                    <span v-if="formatTaskLabel(item.taskLabel)" class="task-label">{{ formatTaskLabel(item.taskLabel) }}</span>
                    <span v-for="(tag, idx) in normalizeTags(item.taskTagls)" :key="idx" class="task-tag">{{ tag }}</span>
                  </div>
                  <div class="person-col person-col-flex">
                    <el-avatar :size="28">{{ getAvatarText(item.executeName || item.ownerName) }}</el-avatar>
                    <span class="person-name">{{ item.executeName || item.ownerName || '-' }}</span>
                  </div>
                  <div class="progress-col">
                    <div class="progress-click" @click="openDialogTaskProgress(item.taskDateId || item.id)">
                      <el-progress :percentage="toNumber(item.percent)" :stroke-width="12" color="#2d8cf0" />
                    </div>
                  </div>
                  <div class="person-col">
                    <div>{{ formatStatus(item.status, item.statusLabel) }}</div>
                    <div v-if="Number(item.status) === 5 && item.overdueDays" class="overdue-text">{{ `(已逾期${item.overdueDays})` }}</div>
                  </div>
                  <div class="time-col">
                    <span v-if="item.dateType && Number(item.dateType) < 5">{{ item.dateStartDate }}</span>
                    <span v-if="item.dateType && Number(item.dateType) < 5">（</span>
                    {{ item.dateName || item.deadline || '-' }}
                    <span v-if="item.dateType && Number(item.dateType) < 5">）</span>
                  </div>
                  <div class="person-col">{{ item.createName || item.fromName || '-' }}</div>
                  <div class="handle-col handle-col-btn">
                    <button type="button" class="img-btn" title="添加子任务" @click="openDialogForm(item.id)">+</button>
                    <button type="button" class="img-btn look-btn" title="查看详情" @click="goDetail(item)">看</button>
                    <button type="button" class="img-btn del-btn" title="删除任务" @click="del(item.id)">删</button>
                  </div>
                </div>

                <div v-show="item.show" class="box-content">
                                    <div v-for="task in item.sonTasks || []" :key="task.taskDateId || task.id" class="card-row-sub">
                    <div class="icon-col icon-col-placeholder"></div>
                    <div class="content-target-col text-overflow">

                      <el-checkbox
                        v-model="task.checks"
                        :disabled="!task.isEditable"
                        style="padding-right: 10px"
                        @change="checkChangeSon(item, task)"
                      />
                      <p class="title" v-html="task.title || task.name" @click="goDetail(task)"></p>
                      <span v-if="formatTaskLabel(task.taskLabel)" class="task-label">{{ formatTaskLabel(task.taskLabel) }}</span>
                      <span v-for="(tag, idx) in normalizeTags(task.taskTagls)" :key="idx" class="task-tag">{{ tag }}</span>
                    </div>
                    <div class="person-col person-col-flex">
                      <el-avatar :size="28">{{ getAvatarText(task.executeName || task.ownerName) }}</el-avatar>
                      <span class="person-name">{{ task.executeName || task.ownerName || '-' }}</span>
                    </div>
                    <div class="progress-col">
                      <div class="progress-click" @click="openDialogTaskProgress(task.taskDateId || task.id)">
                        <el-progress :percentage="toNumber(task.percent)" :stroke-width="12" color="#2d8cf0" />
                      </div>
                    </div>
                    <div class="person-col">
                      <div>{{ formatStatus(task.status, task.statusLabel) }}</div>
                      <div v-if="Number(task.status) === 5 && task.overdueDays" class="overdue-text">{{ `(已逾期${task.overdueDays})` }}</div>
                    </div>
                    <div class="time-col">
                      <span v-if="task.dateType && Number(task.dateType) < 5">{{ task.dateStartDate }}</span>
                      <span v-if="task.dateType && Number(task.dateType) < 5">（</span>
                      {{ task.dateName || task.deadline || '-' }}
                      <span v-if="task.dateType && Number(task.dateType) < 5">）</span>
                    </div>
                    <div class="person-col">{{ task.createName || task.fromName || '-' }}</div>
                    <div class="handle-col handle-col-btn">
                      <button type="button" class="img-btn look-btn" title="查看详情" @click="goDetail(task)">看</button>
                      <button type="button" class="img-btn del-btn" title="删除任务" @click="del(task.id)">删</button>
                    </div>
                  </div>
                </div>
              </div>

              <el-empty v-if="!pageData.length && !loading" description="暂无任务" />
            </div>

            <div class="pager-wrap">
              <el-pagination
                v-model:current-page="pagination.pageNo"
                v-model:page-size="pagination.pageSize"
                background
                :page-sizes="pagination.psizes"
                :total="pagination.total"
                layout="total, sizes, prev, pager, next"
                @size-change="loadListData"
                @current-change="loadListData"
              />
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, nextTick, onActivated, onMounted, reactive, ref, watch } from 'vue'
import moment from 'moment'

import { ArrowDown, OfficeBuilding, Tickets } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useRouter } from 'vue-router'
import { taskListByTable, taskListMineGantt } from '@/api/otr/task/core'

type TaskRow = Record<string, any>


const router = useRouter()
const loading = ref(false)
const viewType = ref<number>(Number(localStorage.getItem('viewType') || 3))
const toggleActive = ref<string>(localStorage.getItem('calendarActive') || 'day')
const kws = ref('')
const dt = ref('')
const dt2 = ref<[string, string] | string[]>([
    moment().format('YYYY-MM-DD'),
  moment().endOf('month').format('YYYY-MM-DD'),

])
const pageData = ref<TaskRow[]>([])
const checkouts = ref(false)
const allIndeterminate = ref(false)
const allDisabled = ref(false)
const scrollFlag = ref(false)
const cardContentRef = ref<HTMLElement | null>(null)

const searchTypeOptions = [
  { label: '全部', value: '' },
  { label: '我负责的', value: '1' },
  { label: '我参与的', value: '2' },
  { label: '我分配的', value: '3' },
  { label: '分配给我的', value: '4' },
]

const toggleData = [
  { label: '日', value: 'day' },
  { label: '周', value: 'week' },
  { label: '月', value: 'month' },
]

const monthWeekLabels = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']

const pagination = reactive({
  total: 0,
  psizes: [10, 20, 50, 100],
  pageNo: 1,
  pageSize: 10,
})

const search = reactive({
  orderBy: '',
  sort: '',
  deptId: '',
  subCompanyId: '',
  searchType: '',
  keyWord: '',
    endDate: moment().endOf('month').format('YYYY-MM-DD'),
  startDate: moment().format('YYYY-MM-DD'),

  sta: [] as string[],
  status: [] as string[],
  userId: '',
  pageNo: 1,
  pageSize: 10,
})

const params = reactive({
  kws: '',
  start: '',
  end: '',
  deptId: '',
  subCompanyId: '',
  status: '',
  userId: '',
  searchType: '',
  scope: 'mine',
})

const dayInfo = computed(() => {
    const base = moment(params.start || moment().format('YYYY-MM-DD'))

  const weekLabels = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
  return {
    day: `${base.year()}年${base.format('MM')}月${base.format('DD')}日`,
    week: String(base.week()),
    weekdayLabel: weekLabels[base.day()] || '周一',
  }
})

const daySlots = computed(() => {
  const rows = pageData.value
  return [
    { time: '上午', data: rows.filter((item) => isMorning(item)) },
    { time: '下午', data: rows.filter((item) => !isMorning(item)) },
  ]
})

const weekData = computed(() => buildWeekData(pageData.value, params.start || moment().format('YYYY-MM-DD')))
const monthData = computed(() => buildMonthData(pageData.value, params.start || moment().format('YYYY-MM-DD')))


watch(viewType, (value) => {
  localStorage.setItem('viewType', String(value))
})

watch(
  () => pageData.value,
  async () => {
    await nextTick()
    if (cardContentRef.value) {
      scrollFlag.value = cardContentRef.value.scrollWidth > cardContentRef.value.clientWidth
    }
  },
  { deep: true },
)

function setViewType(value: number) {
  viewType.value = value
  if (viewType.value === 1) {
    initData(toggleActive.value, dt.value || getDateDefault(toggleActive.value))
  }
  loadData()
}

function getDateDefault(type: string) {
    const now = moment()

  if (type === 'day') return now.format('YYYY-MM-DD')
  if (type === 'week') return now.startOf('isoWeek').format('YYYY-MM-DD')
  return now.format('YYYY-MM')
}

function initData(type: string, value: string) {
  params.deptId = search.deptId
  params.subCompanyId = search.subCompanyId
  params.status = (search.status || []).join(',')
  params.userId = search.userId
  params.searchType = search.searchType
  params.kws = search.keyWord

  if (type === 'day') {
    dt.value = value
    params.start = value
    params.end = value
    return
  }
  if (type === 'week') {
    dt.value = value
    params.start = value
        params.end = moment(value).add(6, 'day').format('YYYY-MM-DD')

    return
  }
  dt.value = value
  params.start = `${value}-01`
    params.end = moment(`${value}-01`).endOf('month').format('YYYY-MM-DD')

}

function handleChangeType(value: string) {
  toggleActive.value = value
  localStorage.setItem('calendarActive', value)
  const defaultDate = getDateDefault(value)
  initData(value, defaultDate)
  loadData()
}

function handleChangeTime(value: any) {
  if (viewType.value === 3) {
    const range = Array.isArray(value) ? value : []
        search.startDate = range[0] || moment().format('YYYY-MM-DD')
    search.endDate = range[1] || moment().endOf('month').format('YYYY-MM-DD')

    loadListData()
    return
  }

  if (typeof value === 'string') {
    initData(toggleActive.value, value)
  }
  loadCalendarData()
}

function keydownSearch() {
  search.keyWord = kws.value
  params.kws = kws.value
  if (viewType.value === 1) {
    initData(toggleActive.value, dt.value || getDateDefault(toggleActive.value))
    loadCalendarData()
  } else {
    loadListData()
  }
}

function onSearch() {
  search.sta = [...(search.status || [])]
  if (viewType.value === 1) {
    initData(toggleActive.value, dt.value || getDateDefault(toggleActive.value))
    loadCalendarData()
  } else {
    loadListData()
  }
}

function reset() {
  search.keyWord = ''
  search.searchType = ''
  search.status = []
  search.sta = []
    search.startDate = moment().format('YYYY-MM-DD')
  search.endDate = moment().endOf('month').format('YYYY-MM-DD')
  dt2.value = [moment().format('YYYY-MM-DD'), moment().endOf('month').format('YYYY-MM-DD')]

  dt.value = getDateDefault(toggleActive.value)
  kws.value = ''
  if (viewType.value === 1) {
    initData(toggleActive.value, dt.value)
  }
  loadData()
}

function openDialogForm(parentTaskId?: string | number) {
  if (parentTaskId) {
    router.push({ path: '/otr/task/form', query: { ptaskId: String(parentTaskId) } })
    return
  }
  router.push('/otr/task/form')
}

function goDetail(row: TaskRow) {
  router.push({ path: '/otr/task/detail', query: { id: String(row.taskDateId || row.id || '') } })
}

function openDialogTaskProgress(taskId?: string | number) {
  if (!taskId) return
  router.push({ path: '/otr/task/detail', query: { id: String(taskId) } })
}

function normalizeTaskRows(records: TaskRow[]): TaskRow[] {
  return (records || []).map((item) => ({
    ...item,
    title: item.title || item.name || '-',
    executeName: item.executeName || item.ownerName || item.memberName || '-',
    createName: item.createName || item.fromName || '-',
    percent: toNumber(item.percent || item.progress || 0),
    status: item.status ?? inferStatus(item.statusLabel),
    dateName: item.dateName || item.deadline || item.createdAt || '-',
    dateStartDate: item.dateStartDate || item.startDate || item.deadline || item.createdAt || '',
    show: item.show ?? true,
    isEditable: item.isEditable ?? true,
    sonTasks: normalizeTaskRows(item.sonTasks || []),
    checks: false,
    indeterminate: false,
  }))
}

async function loadListData() {
  loading.value = true
  try {
    const res: any = await taskListByTable({
      ...search,
      pageNo: pagination.pageNo,
      pageSize: pagination.pageSize,
      sta: search.status,
      keyWord: search.keyWord,
      startDate: search.startDate,
      endDate: search.endDate,
    })
    const result = res?.result || {}
    const records = result.records || result.list || []
    pageData.value = normalizeTaskRows(records)
    pagination.total = Number(result.total || pageData.value.length)
    syncCheckState()
  } finally {
    loading.value = false
  }
}

async function loadCalendarData() {
  loading.value = true
  try {
    const res: any = await taskListMineGantt({
      page: 1,
      psize: 1000,
      start: params.start,
      end: params.end,
      kws: params.kws,
      deptId: params.deptId,
      subCompanyId: params.subCompanyId,
      status: params.status,
      userId: params.userId,
      searchType: params.searchType,
      scope: params.scope,
    })
    const result = res?.result || {}
    const records = result.records || result.list || []
    pageData.value = normalizeTaskRows(records)
  } finally {
    loading.value = false
  }
}

function loadData() {
  if (viewType.value === 1) {
    loadCalendarData()
  } else {
    loadListData()
  }
}

function checkAllIn() {
  allIndeterminate.value = false
  pageData.value.forEach((item) => {
    if (item.isEditable) {
      item.checks = checkouts.value
      item.indeterminate = false
    }
    ;(item.sonTasks || []).forEach((child: TaskRow) => {
      if (child.isEditable) child.checks = checkouts.value
    })
  })
  syncCheckState()
}

function checkChange(row: TaskRow) {
  row.indeterminate = false
  ;(row.sonTasks || []).forEach((child: TaskRow) => {
    if (child.isEditable) child.checks = !!row.checks
  })
  syncCheckState()
}

function checkChangeSon(parent: TaskRow, task: TaskRow) {
  const editableChildren = (parent.sonTasks || []).filter((child: TaskRow) => child.isEditable)
  const checkedCount = editableChildren.filter((child: TaskRow) => child.checks).length
  parent.checks = checkedCount > 0 && checkedCount === editableChildren.length
  parent.indeterminate = checkedCount > 0 && checkedCount < editableChildren.length
  task.checks = !!task.checks
  syncCheckState()
}

function getChooseIds() {
  const ids: Array<string | number> = []
  pageData.value.forEach((item) => {
    if (item.checks) ids.push(item.id)
    ;(item.sonTasks || []).forEach((child: TaskRow) => {
      if (child.checks) ids.push(child.id)
    })
  })
  return ids.filter(Boolean)
}

function syncCheckState() {
  const editableRows = pageData.value.flatMap((item) => {
    const rows = item.isEditable ? [item] : []
    const children = (item.sonTasks || []).filter((child: TaskRow) => child.isEditable)
    return rows.concat(children)
  })
  const checkedRows = editableRows.filter((row) => row.checks)
  allDisabled.value = editableRows.length === 0
  checkouts.value = editableRows.length > 0 && checkedRows.length === editableRows.length
  allIndeterminate.value = checkedRows.length > 0 && checkedRows.length < editableRows.length
}

function delTasks() {
  const ids = getChooseIds()
  if (!ids.length) {
    ElMessage.warning('请先选择任务')
    return
  }
  ElMessageBox.confirm('确认批量删除已选择任务吗？', '系统提示', {
    confirmButtonText: '提交',
    cancelButtonText: '取消',
    type: 'warning',
  }).then(() => {
    pageData.value = pageData.value.filter((item) => !ids.includes(item.id))
    pageData.value.forEach((item) => {
      item.sonTasks = (item.sonTasks || []).filter((child: TaskRow) => !ids.includes(child.id))
    })
    pagination.total = Math.max(0, pagination.total - ids.length)
    syncCheckState()
    ElMessage.success('删除成功')
  }).catch(() => undefined)
}

function del(id?: string | number) {
  if (!id) return
  ElMessageBox.confirm('确认删除该任务吗？', '系统提示', {
    confirmButtonText: '提交',
    cancelButtonText: '取消',
    type: 'warning',
  }).then(() => {
    pageData.value = pageData.value.filter((item) => item.id !== id)
    pageData.value.forEach((item) => {
      item.sonTasks = (item.sonTasks || []).filter((child: TaskRow) => child.id !== id)
    })
    pagination.total = Math.max(0, pagination.total - 1)
    syncCheckState()
    ElMessage.success('删除成功')
  }).catch(() => undefined)
}

function toNumber(value: any) {
  const raw = String(value ?? '0').replace('%', '')
  const num = Number(raw)
  return Number.isNaN(num) ? 0 : Math.max(0, Math.min(100, num))
}

function formatPercent(value: any) {
  return `${toNumber(value)}%`
}

function inferStatus(label?: string) {
  if (!label) return 1
  if (label.includes('未开始') || label.includes('未读')) return 1
  if (label.includes('进行中') || label.includes('待处理') || label.includes('待确认')) return 2
  if (label.includes('已完成') || label.includes('已发布')) return 3
  if (label.includes('已逾期')) return 5
  return 1
}

function formatStatus(status: any, statusLabel?: string) {
  if (statusLabel) return statusLabel
  switch (Number(status)) {
    case 1:
      return '未开始'
    case 2:
      return '进行中'
    case 3:
    case 4:
      return '已完成'
    case 5:
      return '已逾期'
    default:
      return '-'
  }
}

function formatTaskLabel(label: any) {
  const value = Number(label)
  if (!value || value === 1) return ''
  if (value === 2) return '主任务'
  if (value === 3) return '子任务'
  return '任务'
}

function normalizeTags(tags: any) {
  if (!Array.isArray(tags)) return []
  return tags.map((item) => item?.name || item?.label || item?.title || String(item)).filter(Boolean)
}

function getAvatarText(name?: string) {
  return name ? name.slice(-1) : '人'
}

function isMorning(item: TaskRow) {
  const dateText = item.dateStartDate || item.startDate || item.deadline || item.createdAt || item.dateName || ''
  if (!dateText) return true
    const hour = moment(dateText).hour()

  if (Number.isNaN(hour)) return true
  return hour < 12
}

function formatPriority(priorityType: any) {
  const num = Number(priorityType)
  if (num === 1) return 'purple'
  if (num === 2) return 'blue'
  if (num === 3) return 'yellow'
  return 'green'
}

function buildWeekData(records: TaskRow[], startDate: string) {
    const start = moment(startDate).startOf('isoWeek')

  return new Array(7).fill(null).map((_, index) => {
    const current = start.add(index, 'day')
    const dayKey = current.format('YYYY-MM-DD')
    return {
      dayKey,
      day: current.format('MM.DD'),
      weekdayLabel: monthWeekLabels[index].replace('周', ''),
      data: records.filter((item) => matchDay(item, dayKey)),
    }
  })
}

function buildMonthData(records: TaskRow[], startDate: string) {
    const base = moment(startDate).startOf('month')

  const start = base.startOf('isoWeek')
  return new Array(42).fill(null).map((_, index) => {
    const current = start.add(index, 'day')
    const dayKey = current.format('YYYY-MM-DD')
    return {
      dayKey,
      day: current.format('DD'),
      data: records.filter((item) => matchDay(item, dayKey)),
    }
  })
}

function matchDay(item: TaskRow, dayKey: string) {
  const candidates = [item.dateStartDate, item.startDate, item.deadline, item.createdAt, item.dateName]
  return candidates.some((value) => {
    if (!value) return false
        return moment(value).format('YYYY-MM-DD') === dayKey

  })
}

onMounted(() => {
  const defaultDate = getDateDefault(toggleActive.value)
  dt.value = defaultDate
  initData(toggleActive.value, defaultDate)
  loadData()
})

onActivated(() => {
  loadData()
})
</script>

<style scoped lang="scss">
.task-page {
  .frame-card {
    background: #fff;
    border-radius: 8px;
  }

  .frame-card-header {
    padding: 16px 20px 10px;
    border-bottom: 1px solid #f0f2f5;
  }

  .frame-card-content {
    padding: 0;
  }

  .frame-search {
    width: 100%;
  }

  .search-line {
    display: flex;
    align-items: center;
    justify-content: space-between;

    :deep(.el-form-item) {
      margin-bottom: 0;
      margin-right: 12px;
    }

    :deep(.el-select) {
      width: 140px;
    }

    :deep(.el-date-editor) {
      width: 240px;
    }
  }

  .search-line-toggle {
    margin-top: 16px;
  }

  .toggle-group {
    display: inline-flex;
    border: 1px solid #dcdfe6;
    border-radius: 4px;
    overflow: hidden;
  }

  .toggle-btn {
    min-width: 44px;
    height: 32px;
    border: 0;
    background: #fff;
    color: #606266;
    cursor: pointer;
    padding: 0 14px;
  }

  .toggle-btn + .toggle-btn {
    border-left: 1px solid #dcdfe6;
  }

  .toggle-btn.is-active {
    background: #409eff;
    color: #fff;
  }

  .calendar-card {
    margin-top: 0;
    overflow: auto;
    margin-bottom: 0;
  }

  .calendar-day-view,
  .calendar-week-view,
  .calendar-month-view {
    padding: 16px 20px 20px;
  }

  .calendar-header,
  .calendar-week-header,
  .calendar-month-header {
    display: grid;
    border: 1px solid #ebeef5;
    background: #f8fafc;
    font-weight: 600;
    color: #606266;
  }

  .calendar-header {
    grid-template-columns: 120px 1fr;
  }

  .calendar-item {
    display: grid;
    grid-template-columns: 120px 1fr;
    border-left: 1px solid #ebeef5;
    border-right: 1px solid #ebeef5;
    border-bottom: 1px solid #ebeef5;
    min-height: 88px;
  }

  .column-time,
  .column-content,
  .column-week,
  .column-day {
    padding: 12px;
  }

  .calendar-content-list {
    background: #fff;
  }

  .calendar-empty {
    color: #b1b7c3;
    font-size: 12px;
  }

  .calendar-task-chip {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    padding: 8px 10px;
    margin-bottom: 8px;
    border-radius: 6px;
    background: #f5f8fd;
    cursor: pointer;
  }

  .calendar-task-chip__title {
    color: #303133;
  }

  .calendar-task-chip__meta {
    color: #409eff;
    white-space: nowrap;
  }

  .calendar-week-header,
  .calendar-week-body {
    grid-template-columns: repeat(7, minmax(0, 1fr));
  }

  .calendar-week-header {
    display: grid;
  }

  .calendar-week-body {
    display: grid;
    border-left: 1px solid #ebeef5;
    border-right: 1px solid #ebeef5;
    border-bottom: 1px solid #ebeef5;
  }

  .calendar-week-column {
    min-height: 220px;
    border-right: 1px solid #ebeef5;
    padding: 12px;
  }

  .calendar-week-column:last-child {
    border-right: 0;
  }

  .summary-card {
    position: relative;
    padding: 10px 12px 10px 16px;
    margin-bottom: 8px;
    background: #fff;
    border: 1px solid #ebeef5;
    border-radius: 6px;
    cursor: pointer;
  }

  .summary-card__line {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 4px;
    border-radius: 6px 0 0 6px;
  }

  .priority-purple {
    background: #8b5cf6;
  }

  .priority-blue {
    background: #409eff;
  }

  .priority-yellow {
    background: #e6a23c;
  }

  .priority-green {
    background: #67c23a;
  }

  .summary-card__title {
    color: #303133;
    font-size: 13px;
    line-height: 20px;
  }

  .summary-card__meta {
    color: #909399;
    font-size: 12px;
    margin-top: 4px;
  }

  .calendar-month-grid {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    border-left: 1px solid #ebeef5;
    border-right: 1px solid #ebeef5;
    border-bottom: 1px solid #ebeef5;
  }

  .calendar-month-cell {
    min-height: 160px;
    border-right: 1px solid #ebeef5;
    border-bottom: 1px solid #ebeef5;
    background: #fff;
  }

  .calendar-month-cell:nth-child(7n) {
    border-right: 0;
  }

  .column-day {
    display: flex;
    justify-content: space-between;
    padding-bottom: 0;
  }

  .day {
    font-weight: 600;
    color: #303133;
  }

  .month-task-list {
    padding-top: 8px;
  }

  .summary-card--month {
    padding-top: 8px;
    padding-bottom: 8px;
  }

  .table-area {
    background: #f8fafc;
    margin: 0;
    overflow: hidden;
  }

  .target_list {
    padding: 0 20px 20px;
  }

    .list-header,
  .card-row-main,
  .card-row-sub {
    display: grid;
    grid-template-columns: 32px minmax(320px, 2.4fr) 140px 180px 100px 180px 80px 120px;
    align-items: center;
    column-gap: 20px;
  }


  .list-header {
    height: 56px;
    color: #606266;
    font-weight: 600;
  }

    .name-col,
  .normal-name-col,
  .small-name-col,
  .box-target-col,
  .content-target-col {
    display: flex;
    align-items: center;
    min-width: 0;
  }

  .name-col {
    grid-column: 1 / 3;
  }

  .icon-col {
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .icon-col-placeholder {
    visibility: hidden;
  }


  .card-content {
    min-height: 320px;
  }

  .card-box {
    margin-bottom: 12px;
    background: #fff;
    border: 1px solid #ebeef5;
    border-radius: 8px;
    overflow: hidden;
  }

    .card-row-main,
  .card-row-sub {
    min-height: 68px;
    padding: 0 16px;
  }

  .card-row-main {
    background: #fff;
  }


  .card-row-sub {
    border-top: 1px solid #f3f4f6;
    background: #fbfcfe;
  }

    .title {
    margin: 0;
    color: #303133;
    cursor: pointer;
    line-height: 20px;
    font-size: 14px;
  }


    .text-overflow .title {
    flex: 1;
    min-width: 0;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }


  .task-label {
    display: inline-flex;
    align-items: center;
    height: 22px;
    margin-left: 8px;
    padding: 0 8px;
    font-size: 12px;
    color: #409eff;
    background: #ecf5ff;
    border-radius: 11px;
  }

  .task-tag {
    display: inline-flex;
    align-items: center;
    height: 22px;
    margin-left: 8px;
    padding: 0 8px;
    font-size: 12px;
    color: #606266;
    background: #f4f4f5;
    border-radius: 11px;
  }

  .person-col-flex {
    display: flex;
    align-items: center;
  }

    .person-name {
    margin-left: 8px;
    color: #606266;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }


    .progress-click {
    cursor: pointer;
    display: flex;
    align-items: center;
  }

  :deep(.progress-col .el-progress) {
    width: 100%;
  }


  .overdue-text {
    color: #e71e19;
    font-size: 12px;
    margin-top: 2px;
  }

  .expand-icon {
    cursor: pointer;
    color: #909399;
    transition: transform 0.2s;
  }

  .expand-icon.is-close {
    transform: rotate(-90deg);
  }

    .handle-col-btn {
    display: flex;
    align-items: center;
    gap: 8px;
    justify-content: flex-start;
  }


  .img-btn {
    width: 28px;
    height: 28px;
    border: 0;
    border-radius: 50%;
    color: #fff;
    background: #409eff;
    cursor: pointer;
    font-size: 12px;
  }

  .look-btn {
    background: #67c23a;
  }

  .del-btn {
    background: #f56c6c;
  }

    .time-col,
  .progress-col,
  .handle-col,
  .person-col {
    min-width: 0;
    color: #606266;
    font-size: 13px;
  }

  .time-col {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .pager-wrap {
    display: flex;
    justify-content: flex-end;
    margin-top: 16px;
  }


    @media (max-width: 1280px) {
    .list-header,
    .card-row-main,
    .card-row-sub {
      grid-template-columns: 28px minmax(240px, 2fr) 120px 150px 88px 160px 72px 108px;
      column-gap: 12px;
    }
  }

}
</style>

