<template>
  <PageContainer title="租户管理">
    <QueryToolbar>
      <el-button v-if="canCreate" type="primary" @click="openCreateDrawer">新增租户</el-button>
      <el-button v-if="canManage" @click="load">刷新</el-button>
    </QueryToolbar>

    <el-table :data="rows" class="mt-md" empty-text="暂无数据">
      <el-table-column prop="tenantCode" label="租户编码" width="220" />
      <el-table-column prop="tenantName" label="租户名称" />
      <el-table-column label="Logo" width="180">
        <template #default="{ row }">
          <img
            v-if="tenantLogoMap[row.id]"
            :src="tenantLogoMap[row.id]"
            alt="tenant-logo"
            style="max-height: 36px; max-width: 140px; object-fit: contain;"
          />
          <span v-else>-</span>
        </template>
      </el-table-column>
      <el-table-column prop="status" label="状态" width="120" :formatter="statusFormatter" />
      <el-table-column prop="createdAt" label="创建时间" width="190" />
      <el-table-column label="操作" width="520">
        <template #default="{ row }">
          <el-button v-if="canManage" size="small" @click="openEdit(row)">编辑</el-button>
          <el-button
            v-if="canToggleStatus && row.status !== 'ENABLED'"
            size="small"
            type="success"
            @click="handleEnable(row.id)"
          >
            启用
          </el-button>
          <el-button
            v-else-if="canToggleStatus"
            size="small"
            type="warning"
            @click="handleDisable(row.id)"
          >
            停用
          </el-button>
          <el-button
            v-if="isPlatform && canManage"
            size="small"
            @click="openSetAdmin(row)"
          >
            设置管理员
          </el-button>
          <el-button
            v-if="isPlatform && canManage"
            size="small"
            type="primary"
            plain
            @click="handleInitBaseline(row)"
          >
            初始化基线
          </el-button>
          <el-button
            v-if="isPlatform && canManage && row.status === 'DISABLED'"
            size="small"
            type="danger"
            @click="handleDeleteTenant(row.id, row.tenantName)"
          >
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <el-drawer v-model="createVisible" title="新增租户" :size="DRAWER_SIZE.sm" destroy-on-close>
      <el-form ref="formRef" :model="form" label-position="left" :label-width="LABEL_WIDTH.md" :rules="formRules">
        <el-form-item label="租户编码" prop="tenantCode">
          <el-input v-model="form.tenantCode" placeholder="如 TENANT_BJ_XINXIN" />
        </el-form-item>
        <el-form-item label="租户名称" prop="tenantName">
          <el-input v-model="form.tenantName" placeholder="如 北京欣欣" />
        </el-form-item>
        <el-form-item label="Logo地址">
          <el-input v-model="form.logoUrl" placeholder="可选：OSSKey 或 URL" />
        </el-form-item>
        <el-form-item label="上传Logo">
          <el-upload accept="image/*" :show-file-list="false" :http-request="uploadCreateLogo">
            <el-button>选择并自动上传</el-button>
          </el-upload>
        </el-form-item>
        <el-form-item v-if="createLogoPreviewUrl" label="Logo预览">
          <img :src="createLogoPreviewUrl" alt="logo-preview" style="max-height: 48px; max-width: 220px; object-fit: contain;" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="createVisible = false">取消</el-button>
        <el-button v-if="canManage" type="primary" @click="handleCreate">创建</el-button>
      </template>
    </el-drawer>

    <el-dialog v-model="editVisible" title="编辑租户" :width="DIALOG_WIDTH.md">
      <el-form ref="editFormRef" :model="editForm" label-position="left" :label-width="LABEL_WIDTH.md" :rules="editFormRules">
        <el-form-item label="租户编码">
          <el-input v-model="editForm.tenantCode" disabled />
        </el-form-item>
        <el-form-item label="租户名称" prop="tenantName">
          <el-input v-model="editForm.tenantName" placeholder="如 北京欣欣" />
        </el-form-item>
        <el-form-item label="Logo地址">
          <el-input v-model="editForm.logoUrl" placeholder="可选：OSSKey 或 URL" />
        </el-form-item>
        <el-form-item label="上传Logo">
          <el-upload accept="image/*" :show-file-list="false" :http-request="uploadEditLogo">
            <el-button>选择并自动上传</el-button>
          </el-upload>
        </el-form-item>
        <el-form-item v-if="editLogoPreviewUrl" label="Logo预览">
          <img :src="editLogoPreviewUrl" alt="logo-preview" style="max-height: 48px; max-width: 220px; object-fit: contain;" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="editVisible = false">取消</el-button>
        <el-button v-if="canManage" type="primary" @click="handleSave">保存</el-button>
      </template>
    </el-dialog>

    <el-dialog v-model="adminDialogVisible" title="设置租户管理员" :width="DIALOG_WIDTH.md">
      <div class="mb-md text-regular">
        当前租户：{{ selectedTenant?.tenantName }}（{{ selectedTenant?.tenantCode }}）
      </div>
      <el-form ref="adminFormRef" :model="adminForm" label-position="left" :label-width="LABEL_WIDTH.md" :rules="adminFormRules">
        <el-form-item label="管理员姓名" prop="userName">
          <el-input v-model="adminForm.userName" />
        </el-form-item>
        <el-form-item label="管理员手机号" prop="phone">
          <el-input v-model="adminForm.phone" />
        </el-form-item>
        <el-form-item label="邮箱" prop="email">
          <el-input v-model="adminForm.email" />
        </el-form-item>
        <el-form-item label="角色编码">
          <el-input v-model="adminForm.roleCode" placeholder="默认 TENANT_ADMIN" />
        </el-form-item>
        <el-alert
          type="info"
          :closable="false"
          show-icon
          title="系统会向该邮箱发送一次性首次设密链接，不再发送明文初始密码。"
        />
      </el-form>
      <template #footer>
        <el-button @click="adminDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleSetAdmin">确认</el-button>
      </template>
    </el-dialog>
  </PageContainer>
</template>

<script setup lang="ts">
import { computed, onMounted, ref } from "vue";
import PageContainer from "../../components/PageContainer.vue";
import QueryToolbar from "../../components/QueryToolbar.vue";
import { DRAWER_SIZE, DIALOG_WIDTH, LABEL_WIDTH } from "../../constants/ui";
import { ElMessage, ElMessageBox } from "element-plus";
import type { FormInstance, FormRules } from "element-plus";
import {
  createPlatformTenant,
  createTenant,
  deletePlatformTenant,
  disablePlatformTenant,
  disableTenant,
  enablePlatformTenant,
  enableTenant,
  fetchFilePresignDownload,
  fetchPlatformTenantAdmin,
  fetchPlatformTenantLogoUploadSign,
  fetchPlatformTenants,
  fetchTenantLogoUploadSign,
  fetchTenants,
  initPlatformTenantBaseline,
  setPlatformTenantAdmin,
  updatePlatformTenant,
  updateTenant,
} from "../../api/modules";
import { PERMS } from "../../constants/permissions";
import { useAuthStore } from "../../stores/auth";
import { toZhStatus } from "../../utils/status";

const authStore = useAuthStore();
const isPlatform = computed(() => authStore.scope === "PLATFORM");
const canManage = computed(() =>
  isPlatform.value ? authStore.hasPermission(PERMS.platform.tenantManage) : authStore.hasPermission(PERMS.tenant.manage),
);
const canCreate = computed(() => isPlatform.value && canManage.value);
const canToggleStatus = computed(() => isPlatform.value && canManage.value);
const rows = ref<any[]>([]);
const tenantLogoMap = ref<Record<number, string>>({});
const createVisible = ref(false);
const createLogoPreviewUrl = ref("");
const editVisible = ref(false);
const editId = ref<number | null>(null);
const editLogoPreviewUrl = ref("");
const adminDialogVisible = ref(false);
const selectedTenant = ref<any>(null);
const adminForm = ref({
  userName: "",
  phone: "",
  email: "",
  roleCode: "TENANT_ADMIN",
});
const form = ref({
  tenantCode: "",
  tenantName: "",
  logoUrl: "",
});
const editForm = ref({
  tenantCode: "",
  tenantName: "",
  logoUrl: "",
});
const formRef = ref<FormInstance>();
const editFormRef = ref<FormInstance>();
const adminFormRef = ref<FormInstance>();
const formRules = ref<FormRules>({
  tenantCode: [{ required: true, message: "请输入租户编码", trigger: "blur" }],
  tenantName: [{ required: true, message: "请输入租户名称", trigger: "blur" }],
});
const editFormRules = ref<FormRules>({
  tenantName: [{ required: true, message: "请输入租户名称", trigger: "blur" }],
});
const adminFormRules = ref<FormRules>({
  userName: [{ required: true, message: "请输入管理员姓名", trigger: "blur" }],
  phone: [{ required: true, message: "请输入管理员手机号", trigger: "blur" }],
  email: [{ required: true, message: "请输入邮箱", trigger: "blur" }],
});
const statusFormatter = (_row: any, _column: any, value: unknown) => toZhStatus(value);

const openCreateDrawer = () => {
  form.value = {
    tenantCode: "",
    tenantName: "",
    logoUrl: "",
  };
  createLogoPreviewUrl.value = "";
  createVisible.value = true;
};

const resolveLogoPreviewUrl = async (logoValue: unknown) => {
  const normalizedLogo = String(logoValue || "").trim();
  if (!normalizedLogo) {
    return "";
  }
  if (normalizedLogo.startsWith("http://") || normalizedLogo.startsWith("https://")) {
    return normalizedLogo;
  }
  const previewResp = await fetchFilePresignDownload({ objectKey: normalizedLogo });
  return String(previewResp?.data?.signedUrl || "");
};

const putToSignedUrl = async (url: string, file: File, contentType: string) => {
  const result = await fetch(url, {
    method: "PUT",
    headers: {
      "Content-Type": contentType || "application/octet-stream",
    },
    body: file,
  });
  if (!result.ok) {
    throw new Error(`上传失败: ${result.status}`);
  }
};

const uploadCreateLogo = async (options: any) => {
  const file = options?.file as File;
  if (!file) {
    ElMessage.warning("请选择 Logo 文件");
    return;
  }
  try {
    const signApi = isPlatform.value ? fetchPlatformTenantLogoUploadSign : fetchTenantLogoUploadSign;
    const resp = await signApi({
      fileName: file.name,
      contentType: file.type || "application/octet-stream",
    });
    const uploadUrl = resp?.data?.uploadUrl;
    const objectKey = resp?.data?.objectKey;
    const contentType = resp?.data?.contentType || file.type || "application/octet-stream";
    if (!uploadUrl || !objectKey) {
      ElMessage.error("获取 Logo 上传签名失败");
      return;
    }
    await putToSignedUrl(uploadUrl, file, contentType);
    form.value.logoUrl = objectKey;
    createLogoPreviewUrl.value = await resolveLogoPreviewUrl(objectKey);
    ElMessage.success("Logo 上传成功");
  } catch (_e: any) {
    ElMessage.error(_e?.response?.data?.message || "Logo 上传失败");
  }
};

const uploadEditLogo = async (options: any) => {
  const file = options?.file as File;
  if (!file) {
    ElMessage.warning("请选择 Logo 文件");
    return;
  }
  try {
    const signApi = isPlatform.value ? fetchPlatformTenantLogoUploadSign : fetchTenantLogoUploadSign;
    const resp = await signApi({
      fileName: file.name,
      contentType: file.type || "application/octet-stream",
    });
    const uploadUrl = resp?.data?.uploadUrl;
    const objectKey = resp?.data?.objectKey;
    const contentType = resp?.data?.contentType || file.type || "application/octet-stream";
    if (!uploadUrl || !objectKey) {
      ElMessage.error("获取 Logo 上传签名失败");
      return;
    }
    await putToSignedUrl(uploadUrl, file, contentType);
    editForm.value.logoUrl = objectKey;
    editLogoPreviewUrl.value = await resolveLogoPreviewUrl(objectKey);
    ElMessage.success("Logo 上传成功");
  } catch (_e: any) {
    ElMessage.error(_e?.response?.data?.message || "Logo 上传失败");
  }
};

const load = async () => {
  const resp = isPlatform.value ? await fetchPlatformTenants() : await fetchTenants();
  rows.value = resp?.data?.list || [];
  const nextMap: Record<number, string> = {};
  await Promise.all(
    rows.value.map(async (item: any) => {
      const id = Number(item?.id || 0);
      const logoKey = String(item?.logoUrl || "").trim();
      if (!id || !logoKey) {
        return;
      }
      try {
        const signedUrl = await resolveLogoPreviewUrl(logoKey);
        if (signedUrl) {
          nextMap[id] = signedUrl;
        }
      } catch (_e) {
        // ignore single row logo load failure
      }
    }),
  );
  tenantLogoMap.value = nextMap;
};

const handleCreate = async () => {
  if (!formRef.value) return;
  const valid = await formRef.value.validate().catch(() => false);
  if (!valid) return;

  const createApi = isPlatform.value ? createPlatformTenant : createTenant;
  await createApi({
    tenantCode: form.value.tenantCode.trim(),
    tenantName: form.value.tenantName.trim(),
    logoUrl: form.value.logoUrl.trim() || undefined,
  });
  ElMessage.success("租户创建成功");
  createVisible.value = false;
  await load();
};

const openEdit = async (row: any) => {
  editId.value = Number(row?.id || 0) || null;
  editForm.value = {
    tenantCode: String(row?.tenantCode || "").trim(),
    tenantName: String(row?.tenantName || "").trim(),
    logoUrl: String(row?.logoUrl || "").trim(),
  };
  try {
    editLogoPreviewUrl.value = await resolveLogoPreviewUrl(row?.logoUrl);
  } catch (_e) {
    editLogoPreviewUrl.value = "";
  }
  editVisible.value = true;
};

const syncCurrentTenantProfile = (tenant: any) => {
  const currentTenantId = Number(authStore.tenantId || 0);
  const updatedTenantId = Number(tenant?.id || editId.value || 0);
  if (authStore.scope !== "TENANT" || !currentTenantId || currentTenantId !== updatedTenantId) {
    return;
  }
  authStore.updateTenantProfile({
    tenantName: String(tenant?.tenantName || editForm.value.tenantName || "").trim(),
    logoUrl: String(tenant?.logoUrl || editForm.value.logoUrl || "").trim(),
  });
};

const handleSave = async () => {
  if (!editId.value) return;
  if (!editFormRef.value) return;
  const valid = await editFormRef.value.validate().catch(() => false);
  if (!valid) return;

  const updateApi = isPlatform.value ? updatePlatformTenant : updateTenant;
  const resp = await updateApi(editId.value, {
    tenantName: editForm.value.tenantName.trim(),
    logoUrl: editForm.value.logoUrl.trim() || undefined,
  });
  syncCurrentTenantProfile(resp?.data || null);
  ElMessage.success("租户更新成功");
  editVisible.value = false;
  await load();
};

const handleEnable = async (id: number) => {
  const enableApi = isPlatform.value ? enablePlatformTenant : enableTenant;
  await enableApi(id);
  ElMessage.success("租户已启用");
  await load();
};

const handleDisable = async (id: number) => {
  const disableApi = isPlatform.value ? disablePlatformTenant : disableTenant;
  await disableApi(id);
  ElMessage.success("租户已停用");
  await load();
};

const handleDeleteTenant = async (id: number, name: string) => {
  await ElMessageBox.confirm(`确认删除租户「${name}」？删除后不可恢复。`, "删除租户", {
    type: "warning",
    confirmButtonText: "确认删除",
    cancelButtonText: "取消",
  });
  await deletePlatformTenant(id);
  ElMessage.success("租户已删除");
  await load();
};

const openSetAdmin = async (row: any) => {
  selectedTenant.value = row;
  const defaultForm = {
    userName: `${row.tenantName || "租户"}管理员`,
    phone: "",
    email: "",
    roleCode: "TENANT_ADMIN",
  };
  try {
    const resp = await fetchPlatformTenantAdmin(row.id);
    const data = resp?.data;
    adminForm.value = data
      ? {
          userName: String(data.userName || defaultForm.userName),
          phone: String(data.phone || ""),
          email: String(data.email || ""),
          roleCode: String(data.roleCode || "TENANT_ADMIN"),
        }
      : defaultForm;
  } catch (_e) {
    adminForm.value = defaultForm;
  }
  adminDialogVisible.value = true;
};

const handleSetAdmin = async () => {
  if (!selectedTenant.value?.id) return;
  if (!adminFormRef.value) return;
  const valid = await adminFormRef.value.validate().catch(() => false);
  if (!valid) return;

  const resp = await setPlatformTenantAdmin(selectedTenant.value.id, {
    userName: adminForm.value.userName.trim(),
    phone: adminForm.value.phone.trim(),
    email: adminForm.value.email.trim(),
    roleCode: adminForm.value.roleCode.trim() || undefined,
  });
  const action = String(resp?.data?.action || "");
  ElMessage.success(
    action === "UPDATED"
      ? "租户管理员更新成功，首次设密链接已发送到邮箱"
      : "租户管理员创建成功，首次设密链接已发送到邮箱",
  );
  adminDialogVisible.value = false;
};

const handleInitBaseline = async (row: any) => {
  try {
    await ElMessageBox.confirm(
      `将为租户 ${row.tenantName}（${row.tenantCode}）补齐菜单、角色、角色权限和角色菜单，可重复执行。是否继续？`,
      "初始化确认",
      { type: "warning", confirmButtonText: "继续", cancelButtonText: "取消" },
    );
    const resp = await initPlatformTenantBaseline(row.id);
    const data = resp?.data || {};
    ElMessage.success(
      `初始化完成：菜单 +${data.menuInitialized || 0}，角色 +${data.roleInitialized || 0}，角色权限 +${data.rolePermissionInitialized || 0}，角色菜单 +${data.roleMenuInitialized || 0}`,
    );
  } catch (_e) {
    const message = (_e as any)?.response?.data?.message;
    if (message) {
      ElMessage.error(String(message));
    }
  }
};

onMounted(async () => {
  if (canManage.value) {
    await load();
  }
});
</script>
