<template>
  <div class="page">
    <el-card shadow="never" class="main-content-card unified-shell">
      <div class="unified-action-bar actions-only-bar">
        <div class="filter-spacer"></div>
        <el-button type="primary" @click="openCreate">
          {{ TEXT.common.actions.add }}{{ TEXT.modules.adminSites.siteLabel }}
        </el-button>
      </div>
      <div class="unified-section site-table-section">
        <el-table :data="displaySites" v-loading="loading" stripe :row-class-name="siteRowClass">
          <el-table-column prop="name" :label="TEXT.common.fields.siteName" width="220">
            <template #default="scope">
              <div class="site-name-cell">
                <span>{{ scope.row.name }}</span>
                <el-tag v-if="isLeadUnitSite(scope.row)" type="warning" effect="light" size="small">
                  {{ TEXT.modules.adminSites.leadUnitTag }}
                </el-tag>
              </div>
            </template>
          </el-table-column>
          <el-table-column prop="city" :label="TEXT.common.fields.city" width="100" />
          <el-table-column prop="pi_name" :label="TEXT.modules.adminSites.piLabel" width="120" />
          <el-table-column :label="TEXT.common.fields.phone" width="140">
            <template #default="scope">
              {{ phoneText(scope.row) }}
            </template>
          </el-table-column>
          <el-table-column prop="contact" :label="TEXT.common.fields.contact" width="160">
            <template #default="scope">
              {{ contactLabel(scope.row) }}
            </template>
          </el-table-column>
          <el-table-column :label="TEXT.common.fields.status" width="100">
            <template #default="scope">
              <el-tag type="success" v-if="scope.row.is_active">已解锁</el-tag>
              <el-tag type="danger" v-else>已锁定</el-tag>
            </template>
          </el-table-column>
          <el-table-column :label="TEXT.common.labels.actions" width="200" align="center" class-name="action-column">
            <template #default="scope">
              <el-button link type="primary" size="small" @click="openEdit(scope.row)">{{ TEXT.common.actions.edit }}</el-button>
              <el-button
                link
                :type="scope.row.is_active ? 'danger' : 'primary'"
                size="small"
                @click="toggleSite(scope.row)"
              >
                {{ scope.row.is_active ? "锁定" : "解锁" }}
              </el-button>
              <el-button
                v-if="isAdmin"
                link
                type="danger"
                size="small"
                @click="confirmDelete(scope.row)"
              >
                {{ TEXT.common.actions.delete }}
              </el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </el-card>
    <SiteForm
      v-if="projectId"
      v-model:visible="formVisible"
      :study-id="projectId"
      :site="editingSite"
      :members="members"
      :users="users"
      @saved="loadSites"
    />
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, ref } from "vue";
import { useRoute } from "vue-router";
import { ElMessage, ElMessageBox } from "element-plus";
import { fetchStudyDetail } from "../../api/studies";
import { deleteSite, fetchSites, updateSite } from "../../api/sites";
import { fetchUsers } from "../../api/users";
import { listMembers } from "../../api/members";
import SiteForm from "./SiteForm.vue";
import type { Site, Study, UserInfo } from "../../types/api";
import { useAuthStore } from "../../store/auth";
import { evaluateAction } from "../../guards/actionGuard";
import { logAudit } from "../../audit";
import { TEXT } from "../../locales";

const route = useRoute();
const projectId = computed(() => route.params.projectId as string);
const auth = useAuthStore();

const project = ref<Study | null>(null);
const sites = ref<Site[]>([]);
const users = ref<UserInfo[]>([]);
const members = ref<any[]>([]);
const loading = ref(false);
const formVisible = ref(false);
const editingSite = ref<Site | null>(null);
const isAdmin = computed(() => auth.user?.role === "ADMIN");

const loadProject = async () => {
  if (!projectId.value) return;
  try {
    const { data } = await fetchStudyDetail(projectId.value);
    project.value = data;
  } catch {
    /* ignore */
  }
};

const loadSites = async () => {
  if (!projectId.value) return;
  loading.value = true;
  try {
    const { data } = await fetchSites(projectId.value, { include_inactive: true });
    sites.value = Array.isArray(data) ? data : (data as any).items || [];
  } catch (e: any) {
    ElMessage.error(e?.response?.data?.message || TEXT.modules.adminSites.loadFailed);
  } finally {
    loading.value = false;
  }
};

const loadUsers = async () => {
  try {
    const { data } = await fetchUsers({ limit: 500 });
    users.value = (data as any).items || [];
  } catch {
    users.value = [];
  }
};

const loadMembers = async () => {
  if (!projectId.value) return;
  try {
    const { data } = await listMembers(projectId.value, { limit: 500 });
    members.value = Array.isArray(data) ? data : data.items || [];
  } catch {
    members.value = [];
  }
};

const memberNameMap = computed(() => {
  const map: Record<string, string> = {};
  users.value.forEach((u) => {
    map[u.id] = u.full_name || u.username || u.id;
  });
  members.value.forEach((m) => {
    if (m.user_id && !map[m.user_id]) map[m.user_id] = m.full_name || m.username || m.user_id;
  });
  return map;
});

const contactLabel = (row: any) => {
  if (!row?.contact) return TEXT.common.fallback;
  return String(row.contact)
    .split(",")
    .map((c) => c.trim())
    .filter(Boolean)
    .map((c) => memberNameMap.value[c] || c)
    .join("、") || TEXT.common.fallback;
};

const phoneText = (row: any) => row?.phone || row?.contact_phone || TEXT.common.fallback;

const normalizeSiteName = (value?: string | null) => String(value || "").trim().replace(/\s+/g, "").toLowerCase();
const isLeadUnitSite = (row: Site): boolean => {
  const leadUnitName = normalizeSiteName(project.value?.lead_unit);
  const siteName = normalizeSiteName(row.name);
  if (!leadUnitName || !siteName) return false;
  return siteName === leadUnitName;
};

const displaySites = computed(() => {
  return sites.value
    .map((item, index) => ({ item, index }))
    .sort((a, b) => {
      const aLead = isLeadUnitSite(a.item) ? 1 : 0;
      const bLead = isLeadUnitSite(b.item) ? 1 : 0;
      if (aLead !== bLead) return bLead - aLead;
      return a.index - b.index;
    })
    .map((entry) => entry.item);
});

const siteRowClass = ({ row }: { row: Site }) => {
  const classes: string[] = [];
  if (!row.is_active) classes.push("row-inactive");
  if (isLeadUnitSite(row)) classes.push("row-lead-unit");
  return classes.join(" ");
};

const openCreate = () => {
  loadUsers();
  loadMembers();
  editingSite.value = null;
  formVisible.value = true;
};

const openEdit = (row: Site) => {
  loadUsers();
  loadMembers();
  editingSite.value = row;
  formVisible.value = true;
};

const toggleSite = async (row: Site) => {
  if (!projectId.value) return;
  const decision = evaluateAction({
    actorRole: auth.user?.role || null,
    requiredPermission: "site.manage",
    target: { siteId: row.id, studyId: projectId.value },
  });
  if (!decision.allowed) {
    ElMessage.warning(decision.reason || TEXT.common.messages.noPermission);
    logAudit(decision.auditType, {
      targetId: row.id,
      targetName: row.name,
      reason: decision.reason,
      severity: decision.severity,
    });
    return;
  }
  if (row.is_active) {
    const ok = await ElMessageBox.confirm("锁定后该中心将不可编辑，但数据会保留，确认锁定？", "锁定中心", {
      type: "warning",
      confirmButtonText: TEXT.common.actions.confirm,
      cancelButtonText: TEXT.common.actions.cancel,
    }).catch(() => null);
    if (!ok) return;
  }
  try {
    await updateSite(projectId.value, row.id, { is_active: !row.is_active });
    ElMessage.success(row.is_active ? "已锁定" : "已解锁");
    loadSites();
    logAudit("SITE_STATUS_CHANGED", {
      targetId: row.id,
      targetName: row.name,
      before: { is_active: row.is_active },
      after: { is_active: !row.is_active },
      severity: "normal",
    });
  } catch (e: any) {
    ElMessage.error(e?.response?.data?.message || TEXT.common.messages.actionFailed);
    logAudit("SITE_STATUS_CHANGED", {
      targetId: row.id,
      targetName: row.name,
      before: { is_active: row.is_active },
      after: { is_active: !row.is_active },
      severity: "warning",
      reason: e?.response?.data?.message,
    });
  }
};

const confirmDelete = async (row: Site) => {
  if (!projectId.value) return;
  if (!isAdmin.value) {
    ElMessage.warning("仅管理员可删除中心");
    return;
  }
  const message = "删除该中心会删除中心所有数据，请谨慎操作。输入“确认删除”继续。";
  const result = await ElMessageBox.prompt(message, "危险操作", {
    type: "warning",
    confirmButtonText: TEXT.common.actions.confirm,
    cancelButtonText: TEXT.common.actions.cancel,
    inputPlaceholder: "确认删除",
    inputPattern: /^确认删除$/,
    inputErrorMessage: "请输入“确认删除”",
  }).catch(() => null);
  if (!result) return;
  try {
    await deleteSite(projectId.value, row.id);
    ElMessage.success(TEXT.common.messages.deleteSuccess);
    loadSites();
    logAudit("SITE_DELETED", {
      targetId: row.id,
      targetName: row.name,
      severity: "high",
    });
  } catch (e: any) {
    ElMessage.error(e?.response?.data?.message || TEXT.common.messages.deleteFailed);
    logAudit("SITE_DELETED", {
      targetId: row.id,
      targetName: row.name,
      severity: "warning",
      reason: e?.response?.data?.message,
    });
  }
};

onMounted(async () => {
  await Promise.all([loadProject(), loadUsers(), loadMembers()]);
  loadSites();
});
</script>

<style scoped>
.page {
  display: flex;
  flex-direction: column;
}

.actions-only-bar {
  display: flex;
  justify-content: flex-end;
  align-items: center;
}

.site-table-section {
  padding-top: 12px;
  padding-bottom: 12px;
}

.site-name-cell {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

</style>

<style>
.row-inactive td {
  color: var(--ctms-text-secondary);
  background-color: #fff7d6 !important;
}

.row-inactive .el-tag {
  opacity: 0.6;
}

.row-lead-unit td {
  background-color: #f3f8ff !important;
}

.row-lead-unit.row-inactive td {
  background-color: #edf2fb !important;
}

.el-table .action-column .cell {
  padding-left: 8px;
  padding-right: 8px;
}
</style>
