<template>
  <div class="page page--flush">
    <div class="main-content-flat unified-shell">
      <!-- 统计卡片 -->
      <div class="stats-row">
        <div class="stat-card stat-card--total">
          <div class="stat-icon">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8">
              <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/>
              <circle cx="9" cy="7" r="4"/>
              <path d="M23 21v-2a4 4 0 0 0-3-3.87"/>
              <path d="M16 3.13a4 4 0 0 1 0 7.75"/>
            </svg>
          </div>
          <div class="stat-body">
            <span class="stat-value">{{ total }}</span>
            <span class="stat-label">总用户</span>
          </div>
        </div>
        <div class="stat-card stat-card--active">
          <div class="stat-icon">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8">
              <path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/>
              <polyline points="22 4 12 14.01 9 11.01"/>
            </svg>
          </div>
          <div class="stat-body">
            <span class="stat-value">{{ activeCount }}</span>
            <span class="stat-label">{{ TEXT.enums.userStatus.ACTIVE }}</span>
          </div>
        </div>
        <div class="stat-card stat-card--disabled">
          <div class="stat-icon">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8">
              <circle cx="12" cy="12" r="10"/>
              <line x1="4.93" y1="4.93" x2="19.07" y2="19.07"/>
            </svg>
          </div>
          <div class="stat-body">
            <span class="stat-value">{{ disabledCount }}</span>
            <span class="stat-label">{{ TEXT.enums.userStatus.DISABLED }}</span>
          </div>
        </div>
      </div>

      <!-- 筛选栏 -->
      <div class="filter-container unified-action-bar">
        <div class="filter-form">
          <div class="filter-item-form">
            <el-input
              v-model="searchKeyword"
              :placeholder="TEXT.common.placeholders.keyword"
              clearable
              class="filter-input-comp"
              :prefix-icon="Search"
              @keyup.enter="applyFilters"
            />
          </div>
          <div class="filter-item-form">
            <el-select v-model="statusFilter" :placeholder="TEXT.common.fields.status" style="width: 140px" clearable class="filter-select-comp" @change="applyFilters">
              <el-option :label="TEXT.enums.userStatus.ACTIVE" value="ACTIVE" />
              <el-option :label="TEXT.enums.userStatus.DISABLED" value="DISABLED" />
            </el-select>
          </div>
          <div class="filter-spacer"></div>
          <el-button type="primary" :icon="Plus" @click="openCreate">{{ TEXT.common.actions.add }}{{ TEXT.modules.adminUsers.userLabel }}</el-button>
        </div>
      </div>

      <!-- 用户表格 -->
      <div class="unified-section user-table-section">
        <el-table :data="users" v-loading="loading" class="user-table" style="width: 100%" table-layout="fixed">
          <el-table-column :label="TEXT.common.fields.name" width="360">
            <template #default="scope">
              <div class="user-cell">
                <div class="user-info">
                  <span class="user-name">{{ scope.row.full_name }}</span>
                  <span class="user-email">{{ scope.row.email }}</span>
                </div>
              </div>
            </template>
          </el-table-column>
          <el-table-column prop="clinical_department" :label="TEXT.modules.adminUsers.clinicalDepartmentLabel" show-overflow-tooltip />
          <el-table-column :label="TEXT.common.fields.status">
            <template #default="scope">
              <span class="status-dot" :class="'dot--' + (scope.row.status || '').toLowerCase()"></span>
              {{ statusLabel(scope.row.status) }}
            </template>
          </el-table-column>
          <el-table-column prop="created_at" :label="TEXT.modules.adminUsers.createdAt" show-overflow-tooltip>
            <template #default="scope">
              <span class="text-muted">{{ displayDateTime(scope.row.created_at) }}</span>
            </template>
          </el-table-column>
          <el-table-column :label="TEXT.common.labels.actions" align="center">
            <template #default="scope">
              <div class="action-row">
                <el-tooltip :content="TEXT.common.actions.edit" placement="top">
                  <el-button link type="primary" :icon="Edit" class="action-btn" @click="openEdit(scope.row)" />
                </el-tooltip>
                <el-tooltip :content="scope.row.status === 'ACTIVE' ? TEXT.common.actions.disable : TEXT.common.actions.enable" placement="top">
                  <el-button
                    link
                    :type="scope.row.status === 'ACTIVE' ? 'warning' : 'success'"
                    :icon="scope.row.status === 'ACTIVE' ? Lock : Unlock"
                    class="action-btn"
                    :disabled="isLastAdmin(scope.row)"
                    @click="toggleStatus(scope.row)"
                  />
                </el-tooltip>
                <el-tooltip :content="TEXT.modules.adminUsers.resetPassword" placement="top">
                  <el-button link type="warning" :icon="Key" class="action-btn" @click="openReset(scope.row)" />
                </el-tooltip>
                <el-tooltip :content="TEXT.common.actions.delete" placement="top">
                  <el-button
                    link
                    type="danger"
                    :icon="Delete"
                    class="action-btn"
                    :disabled="scope.row.id === auth.user?.id"
                    @click="onDelete(scope.row)"
                  />
                </el-tooltip>
              </div>
            </template>
          </el-table-column>
        </el-table>
        <div class="pagination-wrap" v-if="total > 0">
          <el-pagination
            v-model:current-page="page"
            v-model:page-size="pageSize"
            :page-sizes="[5, 10, 20]"
            :total="total"
            layout="prev, pager, next, sizes, total"
            small
            @current-change="loadUsers"
            @size-change="onPageSizeChange"
          />
        </div>
      </div>
    </div>
    <UserForm v-if="formVisible" v-model:visible="formVisible" :user="editingUser" :admin-count="activeAdminCount" @saved="loadUsers" />
    <UserResetPassword v-if="resetVisible" v-model:visible="resetVisible" :user="resetUser" @reset="loadUsers" />
  </div>
</template>

<script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, ref, watch } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { Edit, Delete, Key, Lock, Unlock, Search, Plus } from "@element-plus/icons-vue";
import { fetchUsers, updateUser, deleteUser } from "../../api/users";
import { fetchStudies } from "../../api/studies";
import { listMembers } from "../../api/members";
import type { UserInfo } from "../../types/api";
import UserForm from "./UserForm.vue";
import UserResetPassword from "./UserResetPassword.vue";
import { useAuthStore } from "../../store/auth";
import { displayDateTime } from "../../utils/display";
import { TEXT } from "../../locales";

const users = ref<UserInfo[]>([]);
const allUsers = ref<UserInfo[]>([]);
const total = ref(0);
const page = ref(1);
const pageSize = ref(10);
const loading = ref(false);
const activeAdminCount = ref(0);
const formVisible = ref(false);
const resetVisible = ref(false);
const searchKeyword = ref("");
const statusFilter = ref("");
const editingUser = ref<UserInfo | null>(null);
const resetUser = ref<UserInfo | null>(null);
const auth = useAuthStore();
let keywordSearchTimer: ReturnType<typeof setTimeout> | null = null;

const activeCount = computed(() => allUsers.value.filter(u => u.status === 'ACTIVE').length);
const disabledCount = computed(() => allUsers.value.filter(u => u.status === 'DISABLED').length);

const statusLabel = (status: string) => {
  switch (status) {
    case "ACTIVE": return TEXT.enums.userStatus.ACTIVE;
    case "DISABLED": return TEXT.enums.userStatus.DISABLED;
    default: return status || TEXT.common.fallback;
  }
};

const isLastAdmin = (row: UserInfo) =>
  row.is_admin && row.status === "ACTIVE" && activeAdminCount.value <= 1;

const loadUsers = async () => {
  loading.value = true;
  try {
    const [{ data }, { data: adminData }] = await Promise.all([
      fetchUsers({
        skip: (page.value - 1) * pageSize.value,
        limit: pageSize.value,
        keyword: searchKeyword.value || undefined,
        status: statusFilter.value || undefined,
      }),
      fetchUsers({ skip: 0, limit: 10000 }),
    ]);
    const items = (data as any).items || [];
    const allItems = (adminData as any).items || [];
    users.value = items;
    allUsers.value = allItems;
    total.value = (data as any).total || items.length;
    activeAdminCount.value = allItems.filter((u: UserInfo) => u.is_admin && u.status === "ACTIVE").length;
  } catch (e: any) {
    ElMessage.error(e?.response?.data?.message || TEXT.modules.adminUsers.loadFailed);
  } finally {
    loading.value = false;
  }
};

const applyFilters = () => {
  clearKeywordSearchTimer();
  page.value = 1;
  loadUsers();
};

const clearKeywordSearchTimer = () => {
  if (!keywordSearchTimer) return;
  clearTimeout(keywordSearchTimer);
  keywordSearchTimer = null;
};

const scheduleKeywordSearch = () => {
  clearKeywordSearchTimer();
  keywordSearchTimer = setTimeout(() => {
    keywordSearchTimer = null;
    page.value = 1;
    loadUsers();
  }, 300);
};

watch(searchKeyword, () => {
  scheduleKeywordSearch();
});

const onPageSizeChange = (size: number) => {
  pageSize.value = size;
  page.value = 1;
  loadUsers();
};

const openCreate = () => {
  editingUser.value = null;
  formVisible.value = true;
};

const openEdit = (row: UserInfo) => {
  editingUser.value = row;
  formVisible.value = true;
};

const toggleStatus = async (row: UserInfo) => {
  if (isLastAdmin(row)) {
    ElMessage.warning(TEXT.modules.adminUsers.keepAdminWarning);
    return;
  }
  const disable = row.status === "ACTIVE";
  const ok = await ElMessageBox.confirm(
    disable ? TEXT.modules.adminUsers.disableConfirm : TEXT.modules.adminUsers.enableConfirm,
    disable ? TEXT.modules.adminUsers.disableTitle : TEXT.modules.adminUsers.enableTitle,
    {
      type: disable ? "warning" : "info",
      confirmButtonText: TEXT.common.actions.confirm,
      cancelButtonText: TEXT.common.actions.cancel,
    }
  ).catch(() => null);
  if (!ok) return;
  try {
    await updateUser(row.id, { status: disable ? "DISABLED" : "ACTIVE", is_active: !disable });
    ElMessage.success(disable ? TEXT.modules.adminUsers.disableSuccess : TEXT.modules.adminUsers.enableSuccess);
    loadUsers();
  } catch (e: any) {
    ElMessage.error(e?.response?.data?.message || TEXT.common.messages.actionFailed);
  }
};

const openReset = (row: UserInfo) => {
  resetUser.value = row;
  resetVisible.value = true;
};

const onDelete = async (row: UserInfo) => {
  const { action } = await ElMessageBox.prompt(
    TEXT.modules.adminUsers.deleteConfirm,
    TEXT.modules.adminUsers.deleteTitle,
    {
      inputPlaceholder: TEXT.modules.adminUsers.deleteConfirmPlaceholder,
      confirmButtonText: TEXT.common.actions.confirm,
      confirmButtonClass: "el-button--danger",
      cancelButtonText: TEXT.common.actions.cancel,
      inputPattern: /^确认删除$/,
      inputErrorMessage: TEXT.modules.adminUsers.deleteConfirmInputError,
    }
  ).catch(() => ({ action: "cancel" }));
  if (action !== "confirm") return;
  try {
    await deleteUser(row.id);
    ElMessage.success(TEXT.modules.adminUsers.deleteSuccess);
    loadUsers();
  } catch (e: any) {
    const detail = e?.response?.data?.detail || e?.response?.data?.message;
    if (detail && detail.includes(TEXT.modules.adminProjectMembers.memberLabel)) {
      ElMessage.closeAll();
      const blockingProjects = await findUserProjects(row.id);
      if (blockingProjects.length > 0) {
        ElMessage.error(`${detail}，该用户仍在以下项目中：${blockingProjects.join("、")}`);
      } else {
        ElMessage.error(detail);
      }
    } else {
      ElMessage.error(detail || TEXT.modules.adminUsers.deleteFailed);
    }
  }
};

const findUserProjects = async (userId: string) => {
  try {
    const { data } = await fetchStudies();
    const studies = Array.isArray(data) ? data : (data as any).items || [];
    const blocking: string[] = [];
    await Promise.all(studies.map(async (study: any) => {
      try {
        const { data: membersData } = await listMembers(study.id, { limit: 1000, include_inactive: true });
        const members = Array.isArray(membersData) ? membersData : (membersData as any).items || [];
        if (members.some((m: any) => m.user_id === userId)) {
          blocking.push(study.name);
        }
      } catch {
        // skip
      }
    }));
    return blocking;
  } catch {
    return [];
  }
};

onMounted(() => {
  loadUsers();
});

onBeforeUnmount(() => {
  clearKeywordSearchTimer();
});
</script>

<style scoped>
.page,
.main-content-flat,
.user-table-section {
  min-width: 0;
  box-sizing: border-box;
}

.main-content-flat {
  width: 100%;
  max-width: 100%;
}

.stats-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--unified-shell-divider);
}

.stat-card {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border-radius: 10px;
  background: var(--ctms-neutral-100);
  transition: var(--ctms-transition);
}

.stat-card:hover {
  transform: translateY(-1px);
  box-shadow: var(--ctms-shadow-sm);
}

.stat-icon {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.stat-icon svg {
  width: 18px;
  height: 18px;
}

.stat-card--total .stat-icon {
  background: #e8edf3;
  color: var(--ctms-primary);
}

.stat-card--active .stat-icon {
  background: #e6f4ed;
  color: var(--ctms-success);
}

.stat-card--disabled .stat-icon {
  background: #fde8e8;
  color: var(--ctms-danger);
}

.stat-body {
  display: flex;
  flex-direction: column;
}

.stat-value {
  font-size: 20px;
  font-weight: 700;
  line-height: 1.2;
  color: var(--ctms-text-main);
}

.stat-label {
  font-size: 11px;
  color: var(--ctms-text-secondary);
  margin-top: 2px;
}

/* 筛选栏 */
.filter-form {
  display: flex;
  width: 100%;
  gap: 10px;
  align-items: center;
  min-width: 0;
  flex-wrap: wrap;
}

.filter-item-form {
  margin-bottom: 0 !important;
  margin-right: 0 !important;
  min-width: 0;
}

.filter-input-comp {
  width: 220px;
  max-width: 100%;
}

.filter-spacer {
  flex: 1;
  min-width: 0;
}

/* 用户单元格 */
.user-cell {
  display: flex;
  align-items: center;
}

.user-info {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.user-name {
  font-weight: 600;
  font-size: 13px;
  color: var(--ctms-text-main);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.user-email {
  font-size: 12px;
  color: var(--ctms-text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 状态点 */
.status-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  margin-right: 6px;
  vertical-align: middle;
}

.status-dot.dot--active {
  background: var(--ctms-success);
  box-shadow: 0 0 0 3px rgba(63, 143, 107, 0.15);
}

.status-dot.dot--disabled {
  background: var(--ctms-text-disabled);
  box-shadow: 0 0 0 3px rgba(148, 163, 184, 0.15);
}

.text-muted {
  color: var(--ctms-text-secondary);
  font-size: 12px;
}

/* 操作按钮 */
.action-row {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 2px;
  border-radius: 8px;
  background: rgba(248, 250, 252, 0.72);
  box-shadow: inset 0 0 0 1px rgba(148, 163, 184, 0.14);
  white-space: nowrap;
}

.action-btn {
  width: 28px;
  height: 28px;
  min-height: 28px;
  padding: 0;
  margin: 0;
  border-radius: 7px;
  font-size: 15px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.94), rgba(248, 250, 252, 0.82));
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.06), inset 0 0 0 1px rgba(148, 163, 184, 0.16);
  transition: transform 120ms ease, box-shadow 120ms ease, background-color 120ms ease;
}

.action-row :deep(.el-button + .el-button) {
  margin-left: 0;
}

.action-row :deep(.el-button .el-icon) {
  width: 15px;
  height: 15px;
}

.action-btn:hover {
  transform: translateY(-1px);
  background: #fff;
  box-shadow: 0 4px 10px rgba(15, 23, 42, 0.1), inset 0 0 0 1px rgba(148, 163, 184, 0.22);
}

.action-btn.is-disabled {
  transform: none;
  opacity: 0.45;
  box-shadow: inset 0 0 0 1px rgba(148, 163, 184, 0.12);
}

/* 表格区域 */
.user-table-section {
  padding: 0;
  max-width: 100%;
  overflow-x: hidden;
}

.user-table :deep(.el-table__inner-wrapper::before) {
  display: none;
}

.user-table :deep(.el-scrollbar__bar.is-horizontal) {
  display: none;
}

.user-table :deep(th.el-table__cell) {
  padding-top: 10px;
  padding-bottom: 10px;
}

.user-table :deep(td.el-table__cell) {
  padding-top: 10px;
  padding-bottom: 10px;
}

.pagination-wrap {
  margin-top: 10px;
  display: flex;
  justify-content: flex-end;
  padding: 8px 16px;
  max-width: 100%;
  overflow: hidden;
}

.pagination-wrap :deep(.el-pagination) {
  min-width: 0;
  flex-wrap: wrap;
  justify-content: flex-end;
  row-gap: 6px;
}

@media (max-width: 768px) {
  .stats-row {
    grid-template-columns: repeat(2, 1fr);
  }

  .filter-spacer {
    display: none;
  }
}
</style>
