<script setup>
import { TenantService } from '@/service/TenantService';
import { UserService } from '@/service/UserService';
import SearchField from '@/components/SearchField.vue';
import SearchPanel from '@/components/SearchPanel.vue';
import { useToast } from 'primevue/usetoast';
import { computed, onMounted, ref } from 'vue';

const toast = useToast();

const tenants = ref([]);
const loading = ref(false);

const totalRecords = ref(0);
const page = ref(1);
const rows = ref(10);

const nameKeyword = ref('');
const codeKeyword = ref('');
const status = ref('');
const tenantID = ref(null);
const ownerUserID = ref(null);
const expiredAtFrom = ref(null);
const expiredAtTo = ref(null);
const createdAtFrom = ref(null);
const createdAtTo = ref(null);
const sortField = ref('id');
const sortOrder = ref(-1);

const healthDialogVisible = ref(false);
const healthLoading = ref(false);
const healthItems = ref([]);
const healthTotal = ref(0);
const healthPage = ref(1);
const healthRows = ref(10);
const healthSortField = ref('tenant_id');
const healthSortOrder = ref(-1);

const tenantUsersDialogVisible = ref(false);
const tenantUsersLoading = ref(false);
const tenantUsersTenant = ref(null);
const tenantUsers = ref([]);
const tenantUsersTotal = ref(0);
const tenantUsersPage = ref(1);
const tenantUsersRows = ref(10);
const tenantUsersUsername = ref('');
const tenantUsersUserID = ref(null);
const tenantUsersRole = ref('');
const tenantUsersStatus = ref('');

const createDialogVisible = ref(false);
const creating = ref(false);
const createCode = ref('');
const createName = ref('');
const createDuration = ref(365);
const createAdminUserID = ref(null);

const adminSearchUsername = ref('');
const adminSearchLoading = ref(false);
const adminSearchResults = ref([]);

function formatDate(value) {
    if (!value) return '-';
    const date = new Date(value);
    if (Number.isNaN(date.getTime())) return String(value);
    return date.toLocaleString();
}

function formatCny(amountInCents) {
    const amount = Number(amountInCents) / 100;
    if (!Number.isFinite(amount)) return '-';
    return new Intl.NumberFormat('zh-CN', { style: 'currency', currency: 'CNY' }).format(amount);
}

function formatPercent(value) {
    const rate = Number(value);
    if (!Number.isFinite(rate)) return '-';
    return `${(rate * 100).toFixed(1)}%`;
}

function getStatusSeverity(status) {
    switch (status) {
        case 'verified':
            return 'success';
        case 'pending_verify':
            return 'warn';
        case 'banned':
            return 'danger';
        default:
            return 'secondary';
    }
}

function getExpiryDaysInfo(expiredAt) {
    if (!expiredAt) return { daysLeft: null, tooltipText: '未设置过期时间', textClass: '' };
    const expiredDate = new Date(expiredAt);
    if (Number.isNaN(expiredDate.getTime())) return { daysLeft: null, tooltipText: String(expiredAt), textClass: '' };

    const msPerDay = 24 * 60 * 60 * 1000;
    const deltaDays = Math.ceil((expiredDate.getTime() - Date.now()) / msPerDay);
    const isExpired = deltaDays < 0;
    const daysAbs = Math.abs(deltaDays);
    const tooltipText = isExpired ? `已过期 ${daysAbs} 天` : `剩余 ${deltaDays} 天`;

    let textClass = '';
    if (isExpired) textClass = 'text-red-500';
    else if (deltaDays < 10) textClass = 'text-red-500';
    else if (deltaDays < 30) textClass = 'text-orange-500';

    return { daysLeft: deltaDays, tooltipText, textClass };
}

function getHealthSeverity(level) {
    switch (level) {
        case 'healthy':
            return 'success';
        case 'warning':
            return 'warn';
        case 'risk':
            return 'danger';
        default:
            return 'secondary';
    }
}

function formatHealthLevel(level) {
    switch (level) {
        case 'healthy':
            return '健康';
        case 'warning':
            return '预警';
        case 'risk':
            return '风险';
        default:
            return level || '-';
    }
}

function buildTenantFilters() {
    return {
        id: tenantID.value || undefined,
        user_id: ownerUserID.value || undefined,
        name: nameKeyword.value,
        code: codeKeyword.value,
        status: status.value,
        expired_at_from: expiredAtFrom.value || undefined,
        expired_at_to: expiredAtTo.value || undefined,
        created_at_from: createdAtFrom.value || undefined,
        created_at_to: createdAtTo.value || undefined
    };
}

async function loadTenants() {
    loading.value = true;
    try {
        const result = await TenantService.listTenants({
            page: page.value,
            limit: rows.value,
            ...buildTenantFilters(),
            sortField: sortField.value,
            sortOrder: sortOrder.value
        });
        tenants.value = result.items;
        totalRecords.value = result.total;
    } catch (error) {
        toast.add({
            severity: 'error',
            summary: '加载失败',
            detail: error?.message || '无法加载租户列表',
            life: 4000
        });
    } finally {
        loading.value = false;
    }
}

function normalizeHealthSortField(field) {
    if (field === 'tenant_id') return 'id';
    return field;
}

async function loadTenantHealth() {
    healthLoading.value = true;
    try {
        const result = await TenantService.listTenantHealth({
            page: healthPage.value,
            limit: healthRows.value,
            ...buildTenantFilters(),
            sortField: normalizeHealthSortField(healthSortField.value),
            sortOrder: healthSortOrder.value
        });
        healthItems.value = result.items;
        healthTotal.value = result.total;
    } catch (error) {
        toast.add({
            severity: 'error',
            summary: '加载失败',
            detail: error?.message || '无法加载租户健康概览',
            life: 4000
        });
    } finally {
        healthLoading.value = false;
    }
}

function openHealthDialog() {
    healthDialogVisible.value = true;
    healthPage.value = 1;
    healthRows.value = 10;
    healthSortField.value = 'tenant_id';
    healthSortOrder.value = -1;
    loadTenantHealth();
}

function onHealthPage(event) {
    healthPage.value = (event.page ?? 0) + 1;
    healthRows.value = event.rows ?? healthRows.value;
    loadTenantHealth();
}

function onHealthSort(event) {
    healthSortField.value = event.sortField ?? healthSortField.value;
    healthSortOrder.value = event.sortOrder ?? healthSortOrder.value;
    loadTenantHealth();
}

function onSearch() {
    page.value = 1;
    loadTenants();
}

function onReset() {
    nameKeyword.value = '';
    codeKeyword.value = '';
    status.value = '';
    tenantID.value = null;
    ownerUserID.value = null;
    expiredAtFrom.value = null;
    expiredAtTo.value = null;
    createdAtFrom.value = null;
    createdAtTo.value = null;
    sortField.value = 'id';
    sortOrder.value = -1;
    page.value = 1;
    rows.value = 10;
    loadTenants();
}

function onPage(event) {
    page.value = (event.page ?? 0) + 1;
    rows.value = event.rows ?? rows.value;
    loadTenants();
}

function onSort(event) {
    sortField.value = event.sortField ?? sortField.value;
    sortOrder.value = event.sortOrder ?? sortOrder.value;
    loadTenants();
}

function openTenantUsersDialog(tenant) {
    tenantUsersTenant.value = tenant;
    tenantUsersDialogVisible.value = true;
    tenantUsersPage.value = 1;
    tenantUsersRows.value = 10;
    tenantUsersUsername.value = '';
    tenantUsersUserID.value = null;
    tenantUsersRole.value = '';
    tenantUsersStatus.value = '';
    loadTenantUsers();
}

async function loadTenantUsers() {
    const tenant = tenantUsersTenant.value;
    const id = tenant?.id;
    if (!id) return;

    tenantUsersLoading.value = true;
    try {
        const data = await TenantService.listTenantUsers(id, {
            page: tenantUsersPage.value,
            limit: tenantUsersRows.value,
            username: tenantUsersUsername.value,
            user_id: tenantUsersUserID.value || undefined,
            role: tenantUsersRole.value || undefined,
            status: tenantUsersStatus.value || undefined
        });

        const normalizeItems = (items) => {
            if (Array.isArray(items)) return items;
            if (items && typeof items === 'object') return [items];
            return [];
        };

        tenantUsers.value = normalizeItems(data?.items);
        tenantUsersTotal.value = data?.total ?? 0;
    } catch (error) {
        toast.add({ severity: 'error', summary: '加载失败', detail: error?.message || '无法加载租户成员列表', life: 4000 });
    } finally {
        tenantUsersLoading.value = false;
    }
}

function onTenantUsersSearch() {
    tenantUsersPage.value = 1;
    loadTenantUsers();
}

function onTenantUsersReset() {
    tenantUsersUsername.value = '';
    tenantUsersUserID.value = null;
    tenantUsersRole.value = '';
    tenantUsersStatus.value = '';
    tenantUsersPage.value = 1;
    tenantUsersRows.value = 10;
    loadTenantUsers();
}

function onTenantUsersPageChange(event) {
    tenantUsersPage.value = (event.page ?? 0) + 1;
    tenantUsersRows.value = event.rows ?? tenantUsersRows.value;
    loadTenantUsers();
}

const renewDialogVisible = ref(false);
const renewing = ref(false);
const renewTenant = ref(null);
const renewDuration = ref(30);
const durationOptions = [
    { label: '7 天', value: 7 },
    { label: '30 天', value: 30 },
    { label: '90 天', value: 90 },
    { label: '180 天', value: 180 },
    { label: '365 天', value: 365 }
];

const canCreateTenant = computed(() => {
    return Boolean(createCode.value?.trim()) && Boolean(createName.value?.trim()) && Number(createAdminUserID.value) > 0 && Number(createDuration.value) > 0;
});

function openCreateDialog() {
    createCode.value = '';
    createName.value = '';
    createDuration.value = 365;
    createAdminUserID.value = null;
    adminSearchUsername.value = '';
    adminSearchResults.value = [];
    createDialogVisible.value = true;
}

async function searchAdminUsers() {
    const keyword = String(adminSearchUsername.value || '').trim();
    if (!keyword) {
        adminSearchResults.value = [];
        return;
    }

    adminSearchLoading.value = true;
    try {
        const result = await UserService.listUsers({ page: 1, limit: 10, username: keyword });
        adminSearchResults.value = result?.items || [];
    } catch (error) {
        toast.add({ severity: 'error', summary: '搜索失败', detail: error?.message || '无法搜索用户', life: 4000 });
    } finally {
        adminSearchLoading.value = false;
    }
}

function pickAdmin(user) {
    createAdminUserID.value = user?.id ?? null;
}

async function confirmCreateTenant() {
    if (!canCreateTenant.value) return;

    creating.value = true;
    try {
        await TenantService.createTenant({
            code: createCode.value.trim(),
            name: createName.value.trim(),
            admin_user_id: Number(createAdminUserID.value),
            duration: Number(createDuration.value)
        });
        toast.add({ severity: 'success', summary: '创建成功', detail: `租户：${createName.value.trim()}`, life: 3000 });
        createDialogVisible.value = false;
        await loadTenants();
    } catch (error) {
        toast.add({ severity: 'error', summary: '创建失败', detail: error?.message || '无法创建租户', life: 4000 });
    } finally {
        creating.value = false;
    }
}

function openRenewDialog(item) {
    renewTenant.value = item;
    renewDuration.value = 30;
    renewDialogVisible.value = true;
}

const tenantStatusDialogVisible = ref(false);
const tenantStatusOptionsLoading = ref(false);
const tenantStatusUpdating = ref(false);
const tenantStatusOptions = ref([]);
const tenantStatusTenant = ref(null);
const tenantStatusValue = ref(null);

async function ensureTenantStatusOptionsLoaded() {
    if (tenantStatusOptions.value.length > 0) return;
    tenantStatusOptionsLoading.value = true;
    try {
        const list = await TenantService.getTenantStatuses();
        tenantStatusOptions.value = (list || [])
            .map((kv) => ({
                label: kv?.value ?? kv?.key ?? '-',
                value: kv?.key ?? ''
            }))
            .filter((item) => item.value);
    } finally {
        tenantStatusOptionsLoading.value = false;
    }
}

async function openTenantStatusDialog(tenant) {
    tenantStatusTenant.value = tenant;
    tenantStatusValue.value = tenant?.status ?? null;
    tenantStatusDialogVisible.value = true;

    try {
        await ensureTenantStatusOptionsLoaded();
    } catch (error) {
        toast.add({ severity: 'error', summary: '加载失败', detail: error?.message || '无法加载租户状态列表', life: 4000 });
    }
}

async function confirmUpdateTenantStatus() {
    const tenantID = tenantStatusTenant.value?.id;
    if (!tenantID || !tenantStatusValue.value) return;

    tenantStatusUpdating.value = true;
    try {
        await TenantService.updateTenantStatus({ tenantID, status: tenantStatusValue.value });
        toast.add({ severity: 'success', summary: '更新成功', detail: `TenantID: ${tenantID}`, life: 3000 });
        tenantStatusDialogVisible.value = false;
        await loadTenants();
    } catch (error) {
        toast.add({ severity: 'error', summary: '更新失败', detail: error?.message || '无法更新租户状态', life: 4000 });
    } finally {
        tenantStatusUpdating.value = false;
    }
}

async function confirmRenew() {
    const tenantID = renewTenant.value?.id;
    if (!tenantID) return;

    renewing.value = true;
    try {
        await TenantService.renewTenantExpire({ tenantID, duration: renewDuration.value });
        toast.add({ severity: 'success', summary: '续期成功', detail: `TenantID: ${tenantID}`, life: 3000 });
        renewDialogVisible.value = false;
        await loadTenants();
    } catch (error) {
        toast.add({ severity: 'error', summary: '续期失败', detail: error?.message || '无法续期', life: 4000 });
    } finally {
        renewing.value = false;
    }
}

onMounted(() => {
    loadTenants();
    ensureTenantStatusOptionsLoaded().catch(() => {});
});
</script>

<template>
    <div>
        <div class="card">
            <div class="flex items-center justify-between mb-4">
                <h4 class="m-0">租户列表</h4>
                <div class="flex items-center gap-2">
                    <Button label="健康概览" icon="pi pi-heart" severity="secondary" @click="openHealthDialog" />
                    <Button label="创建租户" icon="pi pi-plus" @click="openCreateDialog" />
                </div>
            </div>

            <SearchPanel :loading="loading" @search="onSearch" @reset="onReset">
                <SearchField label="TenantID">
                    <InputNumber v-model="tenantID" :min="1" placeholder="精确匹配" class="w-full" />
                </SearchField>
                <SearchField label="Owner UserID">
                    <InputNumber v-model="ownerUserID" :min="1" placeholder="精确匹配" class="w-full" />
                </SearchField>
                <SearchField label="名称">
                    <IconField>
                        <InputIcon>
                            <i class="pi pi-search" />
                        </InputIcon>
                        <InputText v-model="nameKeyword" placeholder="模糊匹配" class="w-full" @keyup.enter="onSearch" />
                    </IconField>
                </SearchField>
                <SearchField label="Code">
                    <IconField>
                        <InputIcon>
                            <i class="pi pi-search" />
                        </InputIcon>
                        <InputText v-model="codeKeyword" placeholder="模糊匹配（小写）" class="w-full" @keyup.enter="onSearch" />
                    </IconField>
                </SearchField>
                <SearchField label="状态">
                    <Select v-model="status" :options="tenantStatusOptions" optionLabel="label" optionValue="value" placeholder="请选择" :loading="tenantStatusOptionsLoading" class="w-full" />
                </SearchField>
                <SearchField label="过期时间 From">
                    <DatePicker v-model="expiredAtFrom" showIcon showButtonBar placeholder="开始时间" class="w-full" />
                </SearchField>
                <SearchField label="过期时间 To">
                    <DatePicker v-model="expiredAtTo" showIcon showButtonBar placeholder="结束时间" class="w-full" />
                </SearchField>
                <SearchField label="创建时间 From">
                    <DatePicker v-model="createdAtFrom" showIcon showButtonBar placeholder="开始时间" class="w-full" />
                </SearchField>
                <SearchField label="创建时间 To">
                    <DatePicker v-model="createdAtTo" showIcon showButtonBar placeholder="结束时间" class="w-full" />
                </SearchField>
            </SearchPanel>

            <DataTable
                :value="tenants"
                dataKey="id"
                :loading="loading"
                lazy
                :paginator="true"
                :rows="rows"
                :totalRecords="totalRecords"
                :first="(page - 1) * rows"
                :rowsPerPageOptions="[10, 20, 50, 100]"
                sortMode="single"
                :sortField="sortField"
                :sortOrder="sortOrder"
                @page="onPage"
                @sort="onSort"
                currentPageReportTemplate="显示第 {first} - {last} 条，共 {totalRecords} 条"
                paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown"
                scrollable
                scrollHeight="flex"
                responsiveLayout="scroll"
            >
                <Column field="id" header="ID" sortable style="min-width: 6rem" />
                <Column field="code" header="Code" style="min-width: 10rem" />
                <Column field="name" header="名称" sortable style="min-width: 16rem">
                    <template #body="{ data }">
                        <Button :label="data.name || '-'" icon="pi pi-external-link" text size="small" class="p-0" as="router-link" :to="`/superadmin/tenants/${data.id}`" />
                    </template>
                </Column>
                <Column field="user_id" header="Owner" sortable style="min-width: 12rem">
                    <template #body="{ data }">
                        <span v-if="data.owner?.username">{{ data.owner.username }}</span>
                        <span v-else class="text-muted-color">{{ data.user_id ?? '-' }}</span>
                    </template>
                </Column>
                <Column header="管理员" style="min-width: 14rem">
                    <template #body="{ data }">
                        <div class="flex flex-wrap gap-1">
                            <Tag v-for="u in data.admin_users || []" :key="u.id" :value="u.username || String(u.id)" severity="info" />
                            <span v-if="!data.admin_users || data.admin_users.length === 0" class="text-muted-color">-</span>
                        </div>
                    </template>
                </Column>
                <Column field="status_description" header="状态" style="min-width: 10rem">
                    <template #body="{ data }">
                        <Tag :value="data.status_description || data.status || '-'" :severity="getStatusSeverity(data.status)" class="cursor-pointer" @click="openTenantStatusDialog(data)" />
                    </template>
                </Column>
                <Column field="user_count" header="用户数" sortable style="min-width: 8rem">
                    <template #body="{ data }">
                        <Button :label="String(data.user_count ?? 0)" text size="small" icon="pi pi-users" class="p-0" @click="openTenantUsersDialog(data)" />
                    </template>
                </Column>
                <Column field="income_amount_paid_sum" header="累计收入" sortable style="min-width: 10rem">
                    <template #body="{ data }">
                        {{ formatCny(data.income_amount_paid_sum) }}
                    </template>
                </Column>
                <Column field="expired_at" header="过期时间" sortable style="min-width: 14rem">
                    <template #body="{ data }">
                        <span v-if="data.expired_at" v-tooltip="getExpiryDaysInfo(data.expired_at).tooltipText" :class="getExpiryDaysInfo(data.expired_at).textClass">
                            {{ formatDate(data.expired_at) }}
                        </span>
                        <span v-else>-</span>
                    </template>
                </Column>
                <Column field="created_at" header="创建时间" sortable style="min-width: 14rem">
                    <template #body="{ data }">
                        {{ formatDate(data.created_at) }}
                    </template>
                </Column>
                <Column field="updated_at" header="更新时间" sortable style="min-width: 14rem">
                    <template #body="{ data }">
                        {{ formatDate(data.updated_at) }}
                    </template>
                </Column>
                <Column header="操作" :exportable="false" style="min-width: 10rem">
                    <template #body="{ data }">
                        <Button label="续期" icon="pi pi-refresh" size="small" severity="secondary" @click="openRenewDialog(data)" />
                    </template>
                </Column>
            </DataTable>
        </div>

        <Dialog v-model:visible="healthDialogVisible" :modal="true" :style="{ width: '1200px' }">
            <template #header>
                <div class="flex items-center justify-between w-full">
                    <div class="flex items-center gap-2">
                        <span class="font-medium">租户健康概览</span>
                        <Tag value="使用当前筛选条件" severity="secondary" />
                    </div>
                    <Button label="刷新" icon="pi pi-refresh" text :loading="healthLoading" @click="loadTenantHealth" />
                </div>
            </template>
            <Message severity="info" icon="pi pi-info-circle" class="mb-3">健康指标基于当前筛选条件聚合，退款率=退款订单/已支付订单。</Message>
            <DataTable
                :value="healthItems"
                dataKey="tenant_id"
                :loading="healthLoading"
                lazy
                :paginator="true"
                :rows="healthRows"
                :totalRecords="healthTotal"
                :first="(healthPage - 1) * healthRows"
                :rowsPerPageOptions="[10, 20, 50, 100]"
                sortMode="single"
                :sortField="healthSortField"
                :sortOrder="healthSortOrder"
                @page="onHealthPage"
                @sort="onHealthSort"
                currentPageReportTemplate="显示第 {first} - {last} 条，共 {totalRecords} 条"
                paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown"
                scrollable
                scrollHeight="420px"
                responsiveLayout="scroll"
            >
                <Column field="tenant_id" header="TenantID" sortable style="min-width: 7rem" />
                <Column field="name" header="名称" sortable style="min-width: 16rem">
                    <template #body="{ data }">
                        <div class="flex flex-col">
                            <Button :label="data.name || '-'" icon="pi pi-external-link" text size="small" class="p-0" as="router-link" :to="`/superadmin/tenants/${data.tenant_id}`" />
                            <span class="text-xs text-muted-color">Code: {{ data.code || '-' }}</span>
                        </div>
                    </template>
                </Column>
                <Column field="status" header="状态" sortable style="min-width: 10rem">
                    <template #body="{ data }">
                        <Tag :value="data.status_description || data.status || '-'" :severity="getStatusSeverity(data.status)" />
                    </template>
                </Column>
                <Column field="health_level" header="健康等级" style="min-width: 9rem">
                    <template #body="{ data }">
                        <Tag :value="formatHealthLevel(data.health_level)" :severity="getHealthSeverity(data.health_level)" />
                    </template>
                </Column>
                <Column field="refund_rate" header="退款率" style="min-width: 8rem">
                    <template #body="{ data }">
                        {{ formatPercent(data.refund_rate) }}
                    </template>
                </Column>
                <Column header="异常提示" style="min-width: 18rem">
                    <template #body="{ data }">
                        <div class="flex flex-wrap gap-1">
                            <Tag v-for="alert in data.alerts || []" :key="alert" :value="alert" severity="warning" />
                            <span v-if="!data.alerts || data.alerts.length === 0" class="text-muted-color">-</span>
                        </div>
                    </template>
                </Column>
                <Column field="member_count" header="成员数" style="min-width: 8rem" />
                <Column header="内容(已发布/总)" style="min-width: 12rem">
                    <template #body="{ data }">{{ data.published_content_count ?? 0 }} / {{ data.content_count ?? 0 }}</template>
                </Column>
                <Column field="paid_orders" header="成交单" style="min-width: 8rem" />
                <Column field="paid_amount" header="成交金额" style="min-width: 10rem">
                    <template #body="{ data }">
                        {{ formatCny(data.paid_amount) }}
                    </template>
                </Column>
                <Column field="refund_orders" header="退款单" style="min-width: 8rem" />
                <Column field="refund_amount" header="退款金额" style="min-width: 10rem">
                    <template #body="{ data }">
                        {{ formatCny(data.refund_amount) }}
                    </template>
                </Column>
                <Column field="last_paid_at" header="最近成交" style="min-width: 14rem">
                    <template #body="{ data }">
                        {{ formatDate(data.last_paid_at) }}
                    </template>
                </Column>
            </DataTable>
            <template #footer>
                <Button label="关闭" icon="pi pi-times" text @click="healthDialogVisible = false" />
            </template>
        </Dialog>

        <Dialog v-model:visible="renewDialogVisible" :modal="true" :style="{ width: '420px' }">
            <template #header>
                <div class="flex items-center gap-2">
                    <span class="font-medium">为【 {{ renewTenant?.name ?? '-' }} 】续期</span>
                </div>
            </template>
            <div class="flex flex-col gap-4">
                <div>
                    <label class="block font-medium mb-2">续期时长</label>
                    <Select v-model="renewDuration" :options="durationOptions" optionLabel="label" optionValue="value" placeholder="选择续期时长" fluid />
                </div>
            </div>
            <template #footer>
                <Button label="取消" icon="pi pi-times" text @click="renewDialogVisible = false" :disabled="renewing" />
                <Button label="确认续期" icon="pi pi-check" @click="confirmRenew" :loading="renewing" />
            </template>
        </Dialog>

        <Dialog v-model:visible="tenantStatusDialogVisible" :modal="true" :style="{ width: '420px' }">
            <template #header>
                <div class="flex items-center gap-2">
                    <span class="font-medium">更新租户状态</span>
                    <span class="text-muted-color truncate max-w-[240px]">{{ tenantStatusTenant?.name ?? '-' }}</span>
                </div>
            </template>
            <div class="flex flex-col gap-4">
                <div>
                    <label class="block font-medium mb-2">租户状态</label>
                    <Select v-model="tenantStatusValue" :options="tenantStatusOptions" optionLabel="label" optionValue="value" placeholder="选择状态" :disabled="tenantStatusUpdating" fluid />
                </div>
            </div>
            <template #footer>
                <Button label="取消" icon="pi pi-times" text @click="tenantStatusDialogVisible = false" :disabled="tenantStatusUpdating" />
                <Button label="确认" icon="pi pi-check" @click="confirmUpdateTenantStatus" :loading="tenantStatusUpdating" :disabled="!tenantStatusValue" />
            </template>
        </Dialog>

        <Dialog v-model:visible="createDialogVisible" :modal="true" :style="{ width: '720px' }">
            <template #header>
                <div class="flex items-center gap-2">
                    <span class="font-medium">创建租户</span>
                    <span class="text-muted-color">并关联租户管理员</span>
                </div>
            </template>
            <div class="flex flex-col gap-4">
                <div class="grid grid-cols-12 gap-4">
                    <div class="col-span-12 md:col-span-6">
                        <label class="block font-medium mb-2">租户 Code</label>
                        <InputText v-model="createCode" placeholder="例如：acme" class="w-full" :disabled="creating" />
                        <small class="text-muted-color">用于 URL 标识（建议小写字母/数字），创建后不建议修改</small>
                    </div>
                    <div class="col-span-12 md:col-span-6">
                        <label class="block font-medium mb-2">租户名称</label>
                        <InputText v-model="createName" placeholder="例如：ACME 工作室" class="w-full" :disabled="creating" />
                    </div>
                    <div class="col-span-12 md:col-span-6">
                        <label class="block font-medium mb-2">有效期</label>
                        <Select v-model="createDuration" :options="durationOptions" optionLabel="label" optionValue="value" placeholder="选择有效期" fluid :disabled="creating" />
                    </div>
                    <div class="col-span-12 md:col-span-6">
                        <label class="block font-medium mb-2">租户管理员 UserID</label>
                        <InputNumber v-model="createAdminUserID" :min="1" placeholder="输入用户ID" class="w-full" :disabled="creating" />
                        <small class="text-muted-color">下方可通过用户名搜索并一键填入</small>
                    </div>
                </div>

                <Divider />

                <div class="flex items-end gap-2">
                    <div class="flex-1">
                        <label class="block font-medium mb-2">按用户名搜索管理员</label>
                        <InputText v-model="adminSearchUsername" placeholder="输入用户名关键字" class="w-full" :disabled="creating" @keyup.enter="searchAdminUsers" />
                    </div>
                    <Button label="搜索" icon="pi pi-search" :loading="adminSearchLoading" :disabled="creating" @click="searchAdminUsers" />
                </div>

                <DataTable :value="adminSearchResults" dataKey="id" size="small" :loading="adminSearchLoading" scrollable scrollHeight="220px">
                    <Column field="id" header="ID" style="width: 7rem" />
                    <Column field="username" header="用户名" />
                    <Column field="status_description" header="状态" style="width: 10rem" />
                    <Column header="操作" style="width: 8rem">
                        <template #body="{ data }">
                            <Button label="设为管理员" size="small" severity="secondary" @click="pickAdmin(data)" />
                        </template>
                    </Column>
                </DataTable>
            </div>
            <template #footer>
                <Button label="取消" icon="pi pi-times" text @click="createDialogVisible = false" :disabled="creating" />
                <Button label="确认创建" icon="pi pi-check" @click="confirmCreateTenant" :loading="creating" :disabled="!canCreateTenant" />
            </template>
        </Dialog>

        <Dialog v-model:visible="tenantUsersDialogVisible" :modal="true" :style="{ width: '980px' }">
            <template #header>
                <div class="flex items-center gap-2">
                    <span class="font-medium">租户成员</span>
                    <span class="text-muted-color truncate max-w-[420px]">{{ tenantUsersTenant?.name ?? tenantUsersTenant?.code ?? '-' }}</span>
                </div>
            </template>
            <div class="flex flex-col gap-4">
                <SearchPanel :loading="tenantUsersLoading" @search="onTenantUsersSearch" @reset="onTenantUsersReset">
                    <SearchField label="UserID">
                        <InputNumber v-model="tenantUsersUserID" :min="1" placeholder="精确匹配" class="w-full" />
                    </SearchField>
                    <SearchField label="用户名">
                        <IconField>
                            <InputIcon>
                                <i class="pi pi-search" />
                            </InputIcon>
                            <InputText v-model="tenantUsersUsername" placeholder="模糊匹配" class="w-full" @keyup.enter="onTenantUsersSearch" />
                        </IconField>
                    </SearchField>
                    <SearchField label="角色">
                        <Select
                            v-model="tenantUsersRole"
                            :options="[
                                { label: '全部', value: '' },
                                { label: 'member', value: 'member' },
                                { label: 'tenant_admin', value: 'tenant_admin' }
                            ]"
                            optionLabel="label"
                            optionValue="value"
                            placeholder="请选择"
                            class="w-full"
                        />
                    </SearchField>
                    <SearchField label="状态">
                        <Select
                            v-model="tenantUsersStatus"
                            :options="[
                                { label: '全部', value: '' },
                                { label: 'pending_verify', value: 'pending_verify' },
                                { label: 'verified', value: 'verified' },
                                { label: 'banned', value: 'banned' }
                            ]"
                            optionLabel="label"
                            optionValue="value"
                            placeholder="请选择"
                            class="w-full"
                        />
                    </SearchField>
                </SearchPanel>

                <DataTable
                    :value="tenantUsers"
                    dataKey="tenant_user.id"
                    :loading="tenantUsersLoading"
                    lazy
                    :paginator="true"
                    :rows="tenantUsersRows"
                    :totalRecords="tenantUsersTotal"
                    :first="(tenantUsersPage - 1) * tenantUsersRows"
                    :rowsPerPageOptions="[10, 20, 50, 100]"
                    @page="onTenantUsersPageChange"
                    currentPageReportTemplate="显示第 {first} - {last} 条，共 {totalRecords} 条"
                    paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown"
                    scrollable
                    scrollHeight="420px"
                    responsiveLayout="scroll"
                >
                    <Column field="tenant_user.user_id" header="UserID" style="min-width: 7rem" />
                    <Column field="user.username" header="用户名" style="min-width: 14rem" />
                    <Column field="tenant_user.role" header="角色" style="min-width: 12rem">
                        <template #body="{ data }">
                            <div class="flex flex-wrap gap-1">
                                <Tag v-for="r in data?.tenant_user?.role || []" :key="r" :value="r" severity="secondary" />
                                <span v-if="!data?.tenant_user?.role || data.tenant_user.role.length === 0" class="text-muted-color">-</span>
                            </div>
                        </template>
                    </Column>
                    <Column field="user.status_description" header="状态" style="min-width: 10rem" />
                    <Column field="tenant_user.created_at" header="加入时间" style="min-width: 14rem">
                        <template #body="{ data }">
                            {{ formatDate(data?.tenant_user?.created_at) }}
                        </template>
                    </Column>
                </DataTable>
            </div>
            <template #footer>
                <Button label="关闭" icon="pi pi-times" text @click="tenantUsersDialogVisible = false" />
            </template>
        </Dialog>
    </div>
</template>
