<template>
  <div class="page">
    <el-card class="mb-12">
      <div class="filters">
        <el-select v-model="filters.status" placeholder="状态" clearable @change="loadTasks">
          <el-option v-for="opt in statusOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
        </el-select>
        <el-select v-model="filters.milestone_id" placeholder="里程碑" clearable @change="loadTasks">
          <el-option v-for="m in milestones" :key="m.id" :label="m.name" :value="m.id" />
        </el-select>
        <el-input v-model="filters.assignee_id" placeholder="负责人" style="width: 180px" @change="loadTasks" />
        <div class="spacer" />
        <PermissionAction action="task.create">
          <el-button type="primary" @click="openCreate">新建任务</el-button>
        </PermissionAction>
      </div>
    </el-card>

    <el-card>
      <el-table :data="tasks" v-loading="loading" style="width: 100%">
        <el-table-column prop="title" label="标题" />
        <el-table-column prop="milestone_id" label="节点/里程碑">
          <template #default="scope">
            {{ milestoneName(scope.row.milestone_id) }}
          </template>
        </el-table-column>
        <el-table-column prop="assignee_id" label="负责人" width="160" />
        <el-table-column prop="priority" label="优先级" width="100">
          <template #default="scope">
            <el-tag :type="priorityColor(scope.row.priority)">{{ priorityLabel(scope.row.priority) }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="status" label="状态" width="120">
          <template #default="scope">
            <el-tag :type="statusColor(scope.row.status)">{{ statusLabel(scope.row.status) }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="due_date" label="截止日期" width="140" />
        <el-table-column label="操作" width="120">
          <template #default="scope">
            <PermissionAction action="task.edit">
              <el-button type="primary" link size="small" @click="openEdit(scope.row)">编辑</el-button>
            </PermissionAction>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
        class="pagination"
        layout="prev, pager, next"
        :page-size="pageSize"
        :current-page="page"
        :total="total"
        @current-change="onPageChange"
      />
    </el-card>

    <TaskForm v-model="showForm" :task="editingTask" :milestones="milestones" @success="loadTasks" />
  </div>
</template>

<script setup lang="ts">
import { onMounted, ref, computed } from "vue";
import { ElMessage } from "element-plus";
import { fetchTasks } from "../api/tasks";
import { fetchMilestones } from "../api/milestones";
import { useStudyStore } from "../store/study";
import { useAuthStore } from "../store/auth";
import PermissionAction from "../components/PermissionAction.vue";
import { usePermission } from "../utils/permission";
import TaskForm from "../components/TaskForm.vue";
import { getDictColor, getDictLabel, getDictOptions, statusDict, priorityDict } from "../dictionaries";

const study = useStudyStore();
const auth = useAuthStore();

const tasks = ref<any[]>([]);
const milestones = ref<any[]>([]);
const loading = ref(false);
const total = ref(0);
const page = ref(1);
const pageSize = 10;

const statusOptions = getDictOptions(statusDict).filter((opt) => ["TODO", "DOING", "DONE", "BLOCKED"].includes(opt.value));

const filters = ref({
  status: "",
  milestone_id: "",
  assignee_id: "",
});

const showForm = ref(false);
const editingTask = ref<any | null>(null);

const { can } = usePermission();
const milestoneMap = computed(() =>
  milestones.value.reduce<Record<string, string>>((acc, cur) => {
    acc[cur.id] = cur.name || cur.id;
    return acc;
  }, {})
);

const loadMilestones = async () => {
  if (!study.currentStudy) return;
  try {
    const { data } = await fetchMilestones(study.currentStudy.id);
    milestones.value = data.items || data; // 兼容
  } catch (e: any) {
    ElMessage.error(e?.response?.data?.message || "里程碑加载失败");
  }
};

const loadTasks = async () => {
  if (!study.currentStudy) return;
  loading.value = true;
  try {
    const params: Record<string, any> = {
      skip: (page.value - 1) * pageSize,
      limit: pageSize,
    };
    if (filters.value.status) params.status = filters.value.status;
    if (filters.value.milestone_id) params.milestone_id = filters.value.milestone_id;
    if (filters.value.assignee_id) params.assignee_id = filters.value.assignee_id;

    const { data } = await fetchTasks(study.currentStudy.id, params);
    if (Array.isArray(data)) {
      tasks.value = data;
      total.value = data.length;
    } else {
      tasks.value = data.items || [];
      total.value = data.total || tasks.value.length;
    }
  } catch (e: any) {
    ElMessage.error(e?.response?.data?.message || "任务加载失败");
  } finally {
    loading.value = false;
  }
};

const onPageChange = (p: number) => {
  page.value = p;
  loadTasks();
};

const openCreate = () => {
  editingTask.value = null;
  showForm.value = true;
};

const openEdit = (row: any) => {
  editingTask.value = row;
  showForm.value = true;
};

const ensureUser = async () => {
  if (!auth.user && auth.token) {
    try {
      await auth.fetchMe();
    } catch {
      // ignore, canEdit 将保持 false
    }
  }
};

const filterKey = computed(() => (study.currentStudy ? `tasks_filter_${study.currentStudy.id}` : null));
const saveFilters = () => {
  if (!filterKey.value) return;
  localStorage.setItem(filterKey.value, JSON.stringify({ ...filters.value, page: page.value }));
};
const loadSavedFilters = () => {
  if (!filterKey.value) return;
  const raw = localStorage.getItem(filterKey.value);
  if (raw) {
    try {
      const parsed = JSON.parse(raw);
      filters.value.status = parsed.status || "";
      filters.value.milestone_id = parsed.milestone_id || "";
      filters.value.assignee_id = parsed.assignee_id || "";
      page.value = parsed.page || 1;
    } catch {
      /* ignore */
    }
  }
};

const statusLabel = (v: string) => getDictLabel(statusDict, v);
const statusColor = (v: string) => getDictColor(statusDict, v) || "info";
const priorityLabel = (v: string) => getDictLabel(priorityDict, v);
const priorityColor = (v: string) => getDictColor(priorityDict, v) || "info";

const milestoneName = (id: string) => milestoneMap.value[id] || id || "-";

onMounted(async () => {
  await ensureUser();
  loadSavedFilters();
  loadMilestones();
  loadTasks();
});
</script>

<style scoped>
.page {
  padding: 16px;
}
.filters {
  display: flex;
  gap: 8px;
  align-items: center;
}
.spacer {
  flex: 1;
}
.pagination {
  margin-top: 12px;
  text-align: right;
}
.mb-12 {
  margin-bottom: 12px;
}
</style>
