<template>
  <div class="tasks">
    <header class="page-header">
      <h1>{{ $t('tasks.title') }}</h1>
      <div class="header-actions">
        <button class="btn btn-ghost" @click="refresh">{{ $t('tasks.refresh') }}</button>
        <button class="btn btn-primary" @click="openCreateModal">{{ $t('tasks.create') }}</button>
      </div>
    </header>

    <!-- 筛选栏 -->
    <div class="filter-bar">
      <div class="filter-group">
        <span class="filter-label">{{ $t('tasks.filter.project') }}</span>
        <button
          v-for="p in projectFilters"
          :key="p.key"
          class="filter-btn"
          :class="{ active: activeProject === p.key }"
          @click="activeProject = p.key"
        >
          {{ p.label }}
        </button>
      </div>
      <div class="filter-group">
        <span class="filter-label">{{ $t('tasks.filter.status') }}</span>
        <button
          v-for="s in statusFilters"
          :key="s.key"
          class="filter-btn"
          :class="{ active: activeStatus === s.key }"
          @click="activeStatus = s.key"
        >
          <span class="filter-btn-icon">{{ s.icon }}</span>
          <span class="filter-btn-label">{{ s.label }}</span>
        </button>
      </div>
    </div>

    <!-- 按项目分组 -->
    <div class="task-groups">
      <!-- Y-2: loading/error/empty 兜底(参考 Projects.vue 空态写法) -->
      <div v-if="loading" class="empty-state">{{ $t('common.loading') }}</div>
      <div v-else-if="store.error" class="empty-state">{{ store.error }}</div>
      <div v-else-if="filteredGroups.length === 0" class="empty-state">{{ $t('tasks.group.empty') }}</div>
      <template v-else>
        <section
          v-for="group in filteredGroups"
          :key="group.projectName"
          class="task-group"
        >
          <div class="group-header">
            <span class="group-icon">{{ group.icon }}</span>
            <h2 class="group-name">{{ group.projectName }}</h2>
            <span class="group-count">{{ $t('tasks.group.taskCount', { n: group.tasks.length }) }}</span>
          </div>
          <div class="task-list">
            <div class="task-item" v-for="task in group.tasks" :key="task.id" @click="router.push(`/tasks/${task.id}`)">
              <div class="task-main">
                <div class="task-title-row">
                  <span class="task-title">{{ task.title }}</span>
                  <span class="priority-badge" :class="priorityClass(task.priority)">{{ priorityLabel(task.priority) }}</span>
                </div>
                <div class="task-meta">
                  <span class="branch-tag" v-if="task.branch_name">
                    <span class="branch-icon">⑂</span>
                    {{ task.branch_name }}
                  </span>
                  <span class="task-date">{{ formatRelative(task.created_at) }}</span>
                  <span class="task-time">{{ formatRelative(task.updated_at) }}</span>
                </div>
              </div>
              <span class="status-tag" :class="taskStatusClass(task.status)">{{ $t(statusLabel(task.status)) }}</span>
            </div>
          </div>
        </section>
      </template>
    </div>

    <!-- 分页器(F-260621-02 P3):pageSize=0 不分页(全量,等价旧行为);用户选 N 条触发客户端切片 -->
    <Paginator
      v-model:page="page"
      v-model:pageSize="pageSize"
      :total="store.tasks.length"
    />

    <!-- 新建任务模态框 -->
    <div class="modal-overlay" v-if="showCreateModal" @click.self="showCreateModal = false">
      <div class="modal-box">
        <h3>{{ $t('tasks.modal.title') }}</h3>
        <label style="font-size:12px;color:var(--df-text-secondary);margin-bottom:4px;display:block">{{ $t('tasks.modal.project') }}</label>
        <select v-model="newTaskProjectId" style="width:100%;padding:8px 12px;border: 0.5px solid var(--df-border);border-radius: var(--df-radius-sm);background:var(--df-bg);color:var(--df-text);font-size:13px;margin-bottom:12px">
          <option v-for="p in store.projects" :key="p.id" :value="p.id">{{ p.name }}</option>
        </select>
        <label style="font-size:12px;color:var(--df-text-secondary);margin-bottom:4px;display:block">{{ $t('tasks.modal.titleField') }}</label>
        <input v-model="newTaskTitle" :placeholder="$t('tasks.modal.titlePlaceholder')" @keyup.enter="confirmCreate" />
        <label style="font-size:12px;color:var(--df-text-secondary);margin-bottom:4px;display:block">{{ $t('tasks.modal.desc') }}</label>
        <input v-model="newTaskDesc" :placeholder="$t('tasks.modal.descPlaceholder')" style="width:100%;padding:8px 12px;border: 0.5px solid var(--df-border);border-radius: var(--df-radius-sm);background:var(--df-bg);color:var(--df-text);font-size:13px;margin-bottom:12px;box-sizing:border-box" />
        <label style="font-size:12px;color:var(--df-text-secondary);margin-bottom:4px;display:block">{{ $t('tasks.modal.branch') }}</label>
        <input v-model="newTaskBranch" :placeholder="$t('tasks.modal.branchPlaceholder')" style="width:100%;padding:8px 12px;border: 0.5px solid var(--df-border);border-radius: var(--df-radius-sm);background:var(--df-bg);color:var(--df-text);font-size:13px;margin-bottom:12px;box-sizing:border-box" />
        <label style="font-size:12px;color:var(--df-text-secondary);margin-bottom:4px;display:block">{{ $t('tasks.modal.priority') }}</label>
        <select v-model="newTaskPriority" style="width:100%;padding:8px 12px;border: 0.5px solid var(--df-border);border-radius: var(--df-radius-sm);background:var(--df-bg);color:var(--df-text);font-size:13px;margin-bottom:12px">
          <option :value="0">{{ $t('tasks.modal.priorityCritical') }}</option>
          <option :value="1">{{ $t('tasks.modal.priorityHigh') }}</option>
          <option :value="2">{{ $t('tasks.modal.priorityMedium') }}</option>
          <option :value="3">{{ $t('tasks.modal.priorityLow') }}</option>
        </select>
        <div class="modal-actions">
          <button class="btn-cancel" @click="showCreateModal = false">{{ $t('common.cancel') }}</button>
          <button class="btn-confirm" @click="confirmCreate" :disabled="submitting || !newTaskTitle.trim()">{{ $t('common.confirm') }}</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue'
import { useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n'
import { useProjectStore } from '@/stores/project'
import { formatRelative } from '@/utils/time'
import { taskStatusLabel as statusLabel, taskStatusClass, priorityLabel, priorityClass } from '../constants/project'
import type { TaskRecord, TaskQuery } from '@/api/types'
import Paginator from '../components/Paginator.vue'

const router = useRouter()
const store = useProjectStore()
const { t } = useI18n()

const activeProject = ref('all')
const activeStatus = ref('all')
// Y-2: 本视图加载态(loadTasks 不翻转全局 state.loading,故用局部 ref 精确反映任务加载)
const loading = ref(false)

// 分页(F-260621-02 P3):pageSize=0 → 全量(向后兼容,等价改造前);用户选 N → 客户端切片
const page = ref(1)
const pageSize = ref(0)

// ── 新建任务模态框 ──
const showCreateModal = ref(false)
const newTaskProjectId = ref('')
const newTaskTitle = ref('')
const newTaskDesc = ref('')
const newTaskBranch = ref('')
const newTaskPriority = ref(2) // 默认 medium

// 异步操作禁用态(IPC 期间防双击重复提交):confirmCreate 创建任务期间禁用确认按钮
const submitting = ref(false)

interface TaskGroup {
  projectName: string
  icon: string
  tasks: TaskRecord[]
}

const projectFilters = computed(() => [
  { key: 'all', label: t('tasks.filter.all') },
  ...store.projects.map(p => ({ key: p.id, label: p.name })),
])

// D-260616-01:筛选器对齐后端 7 态(删 review_ready/merged/abandoned,加 in_review/testing/done/blocked/cancelled)
const statusFilters = computed<{ key: string; label: string; icon: string }[]>(() => [
  { key: 'all', label: t('tasks.statusFilter.all'), icon: '📋' },
  { key: 'todo', label: t('tasks.statusFilter.todo'), icon: '📝' },
  { key: 'in_progress', label: t('tasks.statusFilter.in_progress'), icon: '🔨' },
  { key: 'in_review', label: t('tasks.statusFilter.in_review'), icon: '👀' },
  { key: 'testing', label: t('tasks.statusFilter.testing'), icon: '🧪' },
  { key: 'done', label: t('tasks.statusFilter.done'), icon: '✅' },
  { key: 'blocked', label: t('tasks.statusFilter.blocked'), icon: '🚫' },
  { key: 'cancelled', label: t('tasks.statusFilter.cancelled'), icon: '🗑️' },
])

function getProjectName(projectId: string): string {
  return store.projects.find(p => p.id === projectId)?.name ?? t('tasks.group.unknownProject')
}

const projectIcons: Record<string, string> = {
  'u-ask': '🤖',
  'u-img': '🖼️',
  'flux': '⚡',
}

// F-260621-02(P1 status 下沉):status 过滤从前端内存 filter 改为构造 query 调后端,
// store.tasks 已是筛选后的结果(后端 WHERE)。filteredGroups 仅做按项目分组(project
// 维度也有后端 query 下沉,这里 groupMap 仅做展示分组,不再二次 filter)。
//
// 注:project 维度同样下沉后端(activeProject watch 构造 query),store.tasks 已按
// project_id 过滤。groupMap 保留分组逻辑(展示按项目聚合),无需再 filter。
const filteredGroups = computed(() => {
  // 分页(F-260621-02):pageSize=0 → 全量切片(等价改造前);否则取当前页窗口。
  // 先对扁平 store.tasks 切片,再分组(保持按项目聚合语义,分组在页窗口内)。
  const all = store.tasks
  const filtered = pageSize.value > 0
    ? all.slice((page.value - 1) * pageSize.value, page.value * pageSize.value)
    : all

  const groupMap = new Map<string, TaskRecord[]>()
  for (const task of filtered) {
    if (!groupMap.has(task.project_id)) {
      groupMap.set(task.project_id, [])
    }
    groupMap.get(task.project_id)!.push(task)
  }

  const result: TaskGroup[] = []
  for (const [projectId, groupTasks] of groupMap) {
    const name = getProjectName(projectId)
    result.push({
      projectName: name,
      icon: projectIcons[name] || '📂',
      tasks: groupTasks,
    })
  }
  return result
})

// statusLabel / priorityLabel / priorityClass 由 ../constants/project 提供(与 ProjectDetail 文案统一)

// F-260621-02(P1 status 下沉):按当前 activeProject + activeStatus 构造后端 query。
// - 全 all → undefined(全量,等价旧行为)
// - 任一具体值 → query 下沉后端 WHERE(project_id / status)
function buildTaskQuery(): TaskQuery | undefined {
  const projAll = activeProject.value === 'all'
  const statusAll = activeStatus.value === 'all'
  if (projAll && statusAll) return undefined
  const query: TaskQuery = {}
  if (!projAll) query.project_id = activeProject.value
  if (!statusAll) query.status = activeStatus.value
  return query
}

async function refresh() {
  loading.value = true
  try {
    await store.loadTasks(buildTaskQuery())
  } finally {
    loading.value = false
  }
}

function openCreateModal() {
  newTaskProjectId.value = store.projects.length > 0 ? store.projects[0].id : ''
  newTaskTitle.value = ''
  newTaskDesc.value = ''
  newTaskBranch.value = ''
  newTaskPriority.value = 2
  showCreateModal.value = true
}

async function confirmCreate() {
  if (!newTaskTitle.value.trim() || !newTaskProjectId.value) return
  submitting.value = true
  try {
    const r = await store.createTask({
      project_id: newTaskProjectId.value,
      title: newTaskTitle.value.trim(),
      description: newTaskDesc.value.trim(),
      branch_name: newTaskBranch.value.trim() || undefined,
      priority: newTaskPriority.value,
    })
    if (!r) return // 失败已 toast,保持弹窗不关
    showCreateModal.value = false
  } finally {
    submitting.value = false
  }
}

// B-260615-29: 切换项目筛选时按筛选重载(避免仅前端 filter,跨项目视图不同步)
// CR-260615-26(R-1): 同步登记当前筛选到 store,供 AR-11 listener 按筛选拉取
// F-260621-02(P1 status 下沉):重载 query 同时含 project_id + status,前端不再 filter status
watch(activeProject, () => {
  store.setActiveTaskProject(activeProject.value)
  page.value = 1
  loading.value = true
  store.loadTasks(buildTaskQuery()).finally(() => { loading.value = false })
})

// F-260621-02(P1 status 下沉):切换 status 筛选时构造 query 重载(后端 WHERE,非前端 filter),
// 并登记到 store 供 AR-11 listener 复用同一筛选(保 B-29 契约)
watch(activeStatus, (key) => {
  store.setActiveTaskStatus(key)
  page.value = 1
  loading.value = true
  store.loadTasks(buildTaskQuery()).finally(() => { loading.value = false })
})

onMounted(async () => {
  // R-1: 登记初始筛选(all=全量),让数据变更 listener 知道视图已挂载、按全量拉取
  store.setActiveTaskProject(activeProject.value)
  store.setActiveTaskStatus(activeStatus.value)
  loading.value = true
  try {
    await Promise.all([store.loadProjects(), store.loadTasks()])
  } finally {
    loading.value = false
  }
})
</script>

<style scoped>
.tasks { padding: 16px 20px 20px; }

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--df-gap-page);
}
.page-header h1 { font-size: 24px; font-weight: 500; color: var(--df-text); }
.header-actions { display: flex; gap: 10px; }

/* ===== 按钮 ===== */
.btn {
  padding: 8px 16px;
  border: none;
  border-radius: var(--df-radius-sm);
  font-size: 13px;
  cursor: pointer;
  transition: all 0.15s;
}
.btn-primary { background: var(--df-accent); color: #fff; }
.btn-primary:hover { background: var(--df-accent-hover); }
.btn-ghost { background: transparent; color: var(--df-text-secondary); border: 0.5px solid var(--df-border); }
.btn-ghost:hover { background: var(--df-bg-card); color: var(--df-text); }

/* ===== 筛选栏 ===== */
.filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-bottom: var(--df-gap-page);
  padding: var(--df-pad-panel);
  background: var(--df-bg-card);
  border: 0.5px solid var(--df-border);
  border-radius: var(--df-radius-lg);
}
.filter-group {
  display: flex;
  align-items: center;
  flex-wrap: wrap; /* 窄屏按钮可换行,避免 nowrap 溢出 */
  gap: 6px;
}
.filter-label {
  font-size: 12px;
  color: var(--df-text-dim);
  white-space: nowrap;
}
.filter-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 12px;
  border: 0.5px solid var(--df-border);
  border-radius: var(--df-radius-sm);
  background: transparent;
  color: var(--df-text-secondary);
  font-size: 12px;
  cursor: pointer;
  transition: all 0.15s;
}
.filter-btn-icon { line-height: 1; } /* 图标基线对齐,避免行高跳动 */
.filter-btn-label { white-space: nowrap; } /* 文字不内断行,换行只发生在按钮间 */
.filter-btn:hover { background: rgba(108, 99, 255, 0.06); color: var(--df-text); }
.filter-btn.active {
  background: var(--df-accent);
  color: #fff;
  border-color: var(--df-accent);
}
/* 窄屏(手机宽):按钮内图标与文字改纵向排布,避免横向挤压致图标/文字在空格处错位断行 */
@media (max-width: 480px) {
  .filter-btn {
    flex-direction: column;
    gap: 2px;
    padding: 4px 8px;
  }
}

/* ===== 任务分组 ===== */
.task-groups {
  display: flex;
  flex-direction: column;
  gap: var(--df-gap-grid);
}

.task-group {
  background: var(--df-bg-card);
  border: 0.5px solid var(--df-border);
  border-radius: var(--df-radius-lg);
  padding: var(--df-pad-panel);
}

.group-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: var(--df-gap-head);
  padding-bottom: 10px;
  border-bottom: 0.5px solid var(--df-border);
}
.group-icon { font-size: 18px; }
.group-name { font-size: 15px; font-weight: 500; color: var(--df-text); }
.group-count { font-size: 12px; color: var(--df-text-dim); margin-left: 8px; }

/* ===== 任务条目 ===== */
.task-list {
  display: flex;
  flex-direction: column;
}
.task-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 14px;
  border-radius: var(--df-radius);
  transition: background 0.1s;
  cursor: pointer;
}
.task-item:hover { background: rgba(108, 99, 255, 0.04); }

.task-main { flex: 1; min-width: 0; }

.task-title-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 4px;
}
.task-title { font-size: 14px; font-weight: 500; color: var(--df-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.priority-badge {
  font-size: 10px; font-weight: 500;
  padding: 1px 6px;
  border-radius: var(--df-radius-xs);
}
.priority-critical { background: rgba(255,107,107,0.2); color: var(--df-danger); }
.priority-high { background: rgba(255,152,0,0.2); color: #ff9800; }
.priority-medium { background: rgba(100,181,246,0.2); color: var(--df-info); }
.priority-low { background: rgba(90,99,128,0.2); color: var(--df-text-dim); }

.task-meta {
  display: flex;
  align-items: center;
  gap: 14px;
}
.branch-tag {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 12px;
  color: var(--df-text-secondary);
  background: rgba(108, 99, 255, 0.06);
  padding: 2px 8px;
  border-radius: var(--df-radius-xs);
  font-family: monospace;
}
.branch-icon { font-size: 12px; color: var(--df-accent); }
.task-date { font-size: 11px; color: var(--df-text-dim); }
.task-time {
  font-size: 11px;
  color: var(--df-text-dim);
  opacity: 0.7;
}

/* ===== 状态标签 ===== */
.status-tag {
  font-size: 11px; font-weight: 500;
  padding: 4px 10px;
  border-radius: var(--df-radius-sm);
  white-space: nowrap;
}
.status-todo { background: rgba(90,99,128,0.2); color: var(--df-text-dim); }
.status-progress { background: rgba(100,181,246,0.2); color: var(--df-info); }
.status-review { background: rgba(255,217,61,0.2); color: var(--df-warning); }
.status-done { background: rgba(100,255,218,0.15); color: var(--df-success); }
.status-abandoned { background: rgba(255,107,107,0.2); color: var(--df-danger); }
/* D-260616-01:7 态新增 — testing(橙警告,近 review 区分)/blocked(红 danger,与 cancelled 区分用实心边框) */
.status-testing { background: rgba(255,152,0,0.2); color: #ff9800; }
.status-blocked { background: rgba(255,107,107,0.12); color: var(--df-danger); border: 0.5px solid var(--df-danger); }

/* ===== 空状态(Y-2: loading/error/empty 兜底,样式参考 Projects.vue) ===== */
.empty-state {
  text-align: center; padding: 60px 20px;
  font-size: 14px; color: var(--df-text-dim);
}

/* ===== 模态框 ===== */
.modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; z-index: 100; }
.modal-box { background: var(--df-bg-card); border: 0.5px solid var(--df-border); border-radius: var(--df-radius-lg); padding: 24px; min-width: 360px; max-width: 90vw; }
.modal-box h3 { color: var(--df-text); margin-bottom: 16px; }
.modal-box input, .modal-box select { width: 100%; padding: 8px 12px; border: 0.5px solid var(--df-border); border-radius: var(--df-radius-sm); background: var(--df-bg); color: var(--df-text); font-size: 13px; margin-bottom: 12px; box-sizing: border-box; }
.modal-box .modal-actions { display: flex; gap: 8px; justify-content: flex-end; }
.modal-box .btn-cancel { padding: 6px 16px; border: 0.5px solid var(--df-border); border-radius: var(--df-radius-sm); background: transparent; color: var(--df-text-secondary); cursor: pointer; }
.modal-box .btn-confirm { padding: 6px 16px; border: none; border-radius: var(--df-radius-sm); background: var(--df-accent); color: #fff; cursor: pointer; }
</style>
