<template>
    <div class="tenants-page">
        <a-card class="mb-4">
            <template #title>机构管理</template>
            <template #extra>
                <a-button v-permission="'tenant:create'" type="primary" @click="handleAdd">
                    <template #icon><plus-outlined /></template>
                    添加机构
                </a-button>
            </template>
        </a-card>

        <!-- 搜索 -->
        <a-form layout="inline" class="search-form" @finish="handleSearch">
            <a-form-item label="机构名称">
                <a-input v-model:value="searchKeyword" placeholder="搜索机构名称或编码" allow-clear style="width: 200px"
                    @press-enter="handleSearch" />
            </a-form-item>
            <a-form-item label="机构类型">
                <a-select v-model:value="searchType" placeholder="全部类型" allow-clear style="width: 130px">
                    <a-select-option value="library">图书馆</a-select-option>
                    <a-select-option value="kindergarten">幼儿园</a-select-option>
                    <a-select-option value="school">学校</a-select-option>
                    <a-select-option value="institution">社会机构</a-select-option>
                    <a-select-option value="other">其他</a-select-option>
                </a-select>
            </a-form-item>
            <a-form-item>
                <a-space>
                    <a-button type="primary" html-type="submit">搜索</a-button>
                    <a-button @click="handleResetSearch">重置</a-button>
                </a-space>
            </a-form-item>
        </a-form>

        <!-- 机构列表 -->
        <a-table :columns="columns" :data-source="filteredData" :loading="loading" :pagination="pagination"
            row-key="id" @change="handleTableChange">
            <template #bodyCell="{ column, record }">
                <template v-if="column.key === 'nameInfo'">
                    <div class="org-cell">
                        <div class="org-name">{{ record.name }}</div>
                        <div class="org-code">
                            <a-tag size="small" color="blue">{{ record.code }}</a-tag>
                        </div>
                    </div>
                </template>
                <template v-else-if="column.key === 'tenantType'">
                    <a-tag :color="tenantTypeColor(record.tenantType)">
                        {{ tenantTypeLabel(record.tenantType) }}
                    </a-tag>
                </template>
                <template v-else-if="column.key === 'statistics'">
                    <a-space :size="12">
                        <span class="stat-item">
                            <user-outlined />
                            {{ record._count?.users || 0 }}
                        </span>
                        <span class="stat-item">
                            <safety-outlined />
                            {{ record._count?.roles || 0 }}
                        </span>
                    </a-space>
                </template>
                <template v-else-if="column.key === 'validState'">
                    <a-badge :status="record.validState === 1 ? 'success' : 'error'"
                        :text="record.validState === 1 ? '正常' : '停用'" />
                </template>
                <template v-else-if="column.key === 'createTime'">
                    {{ formatDate(record.createTime) }}
                </template>
                <template v-else-if="column.key === 'action'">
                    <a-space>
                        <a-button v-permission="'tenant:update'" type="link" size="small"
                            @click="handleEdit(record)">
                            编辑
                        </a-button>
                        <a-button v-permission="'tenant:delete'" v-if="record.isSuper !== 1 && record.code !== 'public'"
                            type="link" size="small" danger @click="handleDelete(record)">
                            删除
                        </a-button>
                    </a-space>
                </template>
            </template>
        </a-table>

        <!-- 新增/编辑弹窗 -->
        <a-modal v-model:open="modalVisible" :title="modalTitle" :confirm-loading="submitLoading" @ok="handleSubmit"
            @cancel="handleCancel" width="800px" :loading="detailLoading">
            <a-tabs v-model:activeKey="activeTab">
                <a-tab-pane key="basic" tab="基本信息">
                    <a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 5 }"
                        :wrapper-col="{ span: 17 }" style="max-width: 560px; margin: 16px auto 0;">
                        <a-form-item label="机构名称" name="name">
                            <a-input v-model:value="form.name" placeholder="如：广东省立中山图书馆" :maxlength="50" />
                        </a-form-item>
                        <a-form-item label="机构编码" name="code">
                            <a-input v-model:value="form.code" placeholder="如：gdlib（用于登录地址）" :maxlength="50"
                                :disabled="!!editingId" />
                            <template #extra>
                                <span class="form-hint" v-if="form.code">登录地址：/{{ form.code }}/login</span>
                            </template>
                        </a-form-item>
                        <a-form-item label="机构类型" name="tenantType">
                            <a-select v-model:value="form.tenantType" placeholder="请选择机构类型">
                                <a-select-option value="library">图书馆</a-select-option>
                                <a-select-option value="kindergarten">幼儿园</a-select-option>
                                <a-select-option value="school">学校</a-select-option>
                                <a-select-option value="institution">社会机构</a-select-option>
                                <a-select-option value="other">其他</a-select-option>
                            </a-select>
                        </a-form-item>
                        <a-form-item label="描述" name="description">
                            <a-textarea v-model:value="form.description" placeholder="机构描述（可选）" :rows="3"
                                :maxlength="500" />
                        </a-form-item>
                        <a-form-item v-if="editingId" label="状态" name="validState">
                            <a-radio-group v-model:value="form.validState">
                                <a-radio :value="1">正常</a-radio>
                                <a-radio :value="2">停用</a-radio>
                            </a-radio-group>
                        </a-form-item>
                    </a-form>
                </a-tab-pane>
                <a-tab-pane key="menus" tab="功能菜单">
                    <div v-if="menusLoading" style="text-align: center; padding: 40px;">
                        <a-spin size="large" />
                    </div>
                    <div v-else class="menu-config">
                        <p class="menu-config-hint">选择该机构可以使用的功能模块：</p>
                        <div v-for="parentMenu in topLevelMenus" :key="parentMenu.id" class="menu-group">
                            <div class="menu-group-header">
                                <a-checkbox :checked="isMenuAllChecked(parentMenu)"
                                    :indeterminate="isMenuIndeterminate(parentMenu)"
                                    @change="handleMenuCheckAll(parentMenu, $event)">
                                    <strong>{{ parentMenu.name }}</strong>
                                </a-checkbox>
                            </div>
                            <div v-if="parentMenu.children && parentMenu.children.length > 0" class="menu-items">
                                <a-row :gutter="[16, 8]">
                                    <a-col :span="8" v-for="childMenu in parentMenu.children" :key="childMenu.id">
                                        <a-checkbox :checked="form.menuIds?.includes(childMenu.id)"
                                            @change="handleChildMenuChange(childMenu.id, $event)">
                                            {{ childMenu.name }}
                                        </a-checkbox>
                                    </a-col>
                                </a-row>
                            </div>
                        </div>
                        <div v-if="topLevelMenus.length === 0"
                            style="text-align: center; padding: 40px; color: #999">
                            暂无菜单数据
                        </div>
                    </div>
                </a-tab-pane>
            </a-tabs>
        </a-modal>
    </div>
</template>

<script setup lang="ts">
import { ref, reactive, nextTick, onMounted, computed } from 'vue'
import { message, Modal } from 'ant-design-vue'
import type { TableColumnsType, FormInstance } from 'ant-design-vue'
import { PlusOutlined, UserOutlined, SafetyOutlined } from '@ant-design/icons-vue'
import {
    tenantsApi,
    type Tenant,
    type CreateTenantForm,
    type UpdateTenantForm,
} from '@/api/tenants'
import { menusApi, type Menu } from '@/api/menus'
import { useListRequest } from '@/composables/useListRequest'
import { useAuthStore } from '@/stores/auth'

const authStore = useAuthStore()

const submitLoading = ref(false)
const detailLoading = ref(false)
const menusLoading = ref(false)
const modalVisible = ref(false)
const modalTitle = ref('添加机构')
const formRef = ref<FormInstance>()
const editingId = ref<number | null>(null)
const activeTab = ref('basic')

// 搜索
const searchKeyword = ref('')
const searchType = ref<string | undefined>(undefined)

// 菜单相关
const allMenus = ref<Menu[]>([])
const topLevelMenus = computed(() => buildMenuTree(allMenus.value))

const {
    loading,
    dataSource,
    pagination,
    handleTableChange,
    refresh: refreshList,
} = useListRequest<Tenant>({
    requestFn: tenantsApi.getList,
    errorMessage: '获取机构列表失败',
})

// 前端过滤（搜索 + 类型筛选）
const filteredData = computed(() => {
    let result = dataSource.value
    if (searchKeyword.value) {
        const kw = searchKeyword.value.toLowerCase()
        result = result.filter(
            (t) =>
                t.name.toLowerCase().includes(kw) ||
                t.code.toLowerCase().includes(kw),
        )
    }
    if (searchType.value) {
        result = result.filter((t: any) => t.tenantType === searchType.value)
    }
    // 隐藏公众用户租户（系统内部使用，不应在机构列表展示）
    result = result.filter((t) => t.code !== 'public')
    return result
})

const form = reactive<CreateTenantForm & { validState?: number; menuIds?: number[]; tenantType?: string }>({
    name: '',
    code: '',
    domain: '',
    description: '',
    tenantType: 'other',
    validState: 1,
    menuIds: [],
})

const rules = {
    name: [
        { required: true, message: '请输入机构名称', trigger: 'blur' },
        { max: 50, message: '名称不能超过50个字符', trigger: 'blur' },
    ],
    code: [
        { required: true, message: '请输入机构编码', trigger: 'blur' },
        { max: 50, message: '编码不能超过50个字符', trigger: 'blur' },
        {
            pattern: /^[a-z][a-z0-9_-]*$/,
            message: '编码只能包含小写字母、数字、下划线和连字符，且以字母开头',
            trigger: 'blur',
        },
    ],
}

const columns: TableColumnsType = [
    { title: '机构信息', key: 'nameInfo', width: 260 },
    { title: '类型', key: 'tenantType', width: 100 },
    { title: '用户/角色', key: 'statistics', width: 120 },
    { title: '状态', key: 'validState', width: 80 },
    { title: '创建时间', key: 'createTime', width: 160 },
    { title: '操作', key: 'action', width: 140, fixed: 'right' },
]

const tenantTypeLabel = (type: string) => {
    const map: Record<string, string> = {
        platform: '平台', library: '图书馆', kindergarten: '幼儿园',
        school: '学校', institution: '社会机构', other: '其他',
    }
    return map[type] || type
}

const tenantTypeColor = (type: string) => {
    const map: Record<string, string> = {
        platform: 'red', library: 'purple', kindergarten: 'green',
        school: 'blue', institution: 'orange', other: 'default',
    }
    return map[type] || 'default'
}

const formatDate = (dateStr?: string) => {
    if (!dateStr) return '-'
    const date = new Date(dateStr)
    return date.toLocaleDateString('zh-CN')
}

const handleSearch = () => { /* 前端过滤，computed 自动触发 */ }

const handleResetSearch = () => {
    searchKeyword.value = ''
    searchType.value = undefined
}

// ========== 菜单相关逻辑（保持不变） ==========

const fetchAllMenus = async () => {
    menusLoading.value = true
    try {
        allMenus.value = await menusApi.getList()
    } catch {
        message.error('获取菜单列表失败')
    } finally {
        menusLoading.value = false
    }
}

const getTenantMenuIds = (): Set<number> => {
    const tenantMenuIds = new Set<number>()
    const tenantMenu = findMenuInTree(allMenus.value, '租户管理')
    if (tenantMenu) collectMenuIds(tenantMenu, tenantMenuIds)
    // 也过滤掉"机构管理"相关菜单
    const orgMenu = findMenuInTree(allMenus.value, '机构管理')
    if (orgMenu) collectMenuIds(orgMenu, tenantMenuIds)
    return tenantMenuIds
}

// 保存编辑时被排除但原本已分配的菜单 ID，保存时合并回去
const preservedExcludedMenuIds = ref<number[]>([])

const fetchTenantMenus = async (tenantId: number) => {
    try {
        const tenantMenus = await tenantsApi.getTenantMenus(tenantId)
        const extractMenuIds = (menus: Menu[]): number[] => {
            const ids: number[] = []
            menus.forEach((menu) => {
                ids.push(menu.id)
                if (menu.children?.length) ids.push(...extractMenuIds(menu.children))
            })
            return ids
        }
        const allMenuIds = extractMenuIds(tenantMenus)
        const excludeIds = getTenantMenuIds()
        // 记录被排除但原本已分配的菜单（如机构管理、用户中心等），保存时需要保留
        preservedExcludedMenuIds.value = allMenuIds.filter((id) => excludeIds.has(id))
        form.menuIds = allMenuIds.filter((id) => !excludeIds.has(id))
    } catch {
        message.error('获取机构菜单失败')
    }
}

const flattenMenus = (menus: Menu[]): Menu[] => {
    const result: Menu[] = []
    const traverse = (menuList: Menu[]) => {
        menuList.forEach((menu) => {
            const { children, ...rest } = menu
            result.push(rest as Menu)
            if (children?.length) traverse(children)
        })
    }
    traverse(menus)
    return result
}

const findMenuInTree = (menus: Menu[], name: string): Menu | null => {
    for (const menu of menus) {
        if (menu.name === name) return menu
        if (menu.children?.length) {
            const found = findMenuInTree(menu.children, name)
            if (found) return found
        }
    }
    return null
}

const collectMenuIds = (menu: Menu, ids: Set<number>) => {
    ids.add(menu.id)
    menu.children?.forEach((child) => collectMenuIds(child, ids))
}

const buildMenuTree = (menus: Menu[]): Menu[] => {
    const flatMenus = flattenMenus(menus)
    const excludeIds = getTenantMenuIds()
    // 也排除用户中心的菜单（超管专属）
    const userCenterMenu = findMenuInTree(menus, '用户中心')
    if (userCenterMenu) collectMenuIds(userCenterMenu, excludeIds)

    const filteredMenus = flatMenus.filter((m) => !excludeIds.has(m.id))
    const menuMap = new Map<number, Menu>()
    const rootMenus: Menu[] = []

    filteredMenus.forEach((m) => menuMap.set(m.id, { ...m, children: [] }))
    filteredMenus.forEach((m) => {
        const node = menuMap.get(m.id)!
        if (m.parentId && menuMap.has(m.parentId)) {
            const parent = menuMap.get(m.parentId)!
            if (!parent.children) parent.children = []
            parent.children.push(node)
        } else {
            rootMenus.push(node)
        }
    })

    const sortMenus = (list: Menu[]) => {
        list.sort((a, b) => (a.sort || 0) - (b.sort || 0))
        list.forEach((m) => { if (m.children?.length) sortMenus(m.children) })
    }
    sortMenus(rootMenus)
    return rootMenus
}

const isMenuAllChecked = (menu: Menu): boolean => {
    if (!menu.children?.length) return form.menuIds?.includes(menu.id) || false
    return menu.children.every((c) => form.menuIds?.includes(c.id))
}

const isMenuIndeterminate = (menu: Menu): boolean => {
    if (!menu.children?.length) return false
    const count = menu.children.filter((c) => form.menuIds?.includes(c.id)).length
    return count > 0 && count < menu.children.length
}

const handleMenuCheckAll = (menu: Menu, e: any) => {
    const checked = e.target.checked
    if (!menu.children?.length) {
        form.menuIds = checked
            ? [...(form.menuIds || []), menu.id]
            : (form.menuIds || []).filter((id) => id !== menu.id)
        return
    }
    const childIds = menu.children.map((c) => c.id)
    if (checked) {
        const ids = [...(form.menuIds || [])]
        childIds.forEach((id) => { if (!ids.includes(id)) ids.push(id) })
        form.menuIds = ids
    } else {
        form.menuIds = (form.menuIds || []).filter((id) => !childIds.includes(id))
    }
}

const handleChildMenuChange = (menuId: number, e: any) => {
    if (!form.menuIds) form.menuIds = []
    if (e.target.checked) {
        if (!form.menuIds.includes(menuId)) form.menuIds = [...form.menuIds, menuId]
    } else {
        form.menuIds = form.menuIds.filter((id) => id !== menuId)
    }
}

// ========== CRUD 操作 ==========

const handleAdd = () => {
    modalTitle.value = '添加机构'
    editingId.value = null
    activeTab.value = 'basic'
    modalVisible.value = true
    preservedExcludedMenuIds.value = []
    nextTick(() => {
        formRef.value?.resetFields()
        Object.assign(form, { name: '', code: '', domain: '', description: '', tenantType: 'other', validState: 1, menuIds: [] })
    })
}

const handleEdit = async (record: Tenant) => {
    modalTitle.value = '编辑机构'
    editingId.value = record.id
    activeTab.value = 'basic'
    modalVisible.value = true
    detailLoading.value = true
    try {
        const detail = await tenantsApi.getDetail(record.id)
        Object.assign(form, {
            name: detail.name,
            code: detail.code,
            domain: detail.domain || '',
            description: detail.description || '',
            tenantType: (detail as any).tenantType || 'other',
            validState: detail.validState,
            menuIds: [],
        })
        await fetchTenantMenus(record.id)
    } catch {
        message.error('获取机构详情失败')
        modalVisible.value = false
    } finally {
        detailLoading.value = false
    }
}

const handleDelete = (record: Tenant) => {
    Modal.confirm({
        title: '确认删除',
        content: `确定要删除机构「${record.name}」吗？此操作不可恢复。`,
        okText: '确定删除',
        okType: 'danger',
        cancelText: '取消',
        onOk: async () => {
            try {
                await tenantsApi.delete(record.id)
                message.success('删除成功')
                refreshList()
            } catch (error: any) {
                message.error(error?.response?.data?.message || '删除失败')
            }
        },
    })
}

const handleSubmit = async () => {
    try {
        await formRef.value?.validate()
        submitLoading.value = true

        const excludeIds = getTenantMenuIds()
        const visibleMenuIds = (form.menuIds || []).filter((id) => !excludeIds.has(id))
        // 编辑时：把被排除但原本已分配的菜单 ID 保留回去，避免保存时丢失
        const menuIds = editingId.value
            ? [...visibleMenuIds, ...preservedExcludedMenuIds.value]
            : visibleMenuIds

        if (editingId.value) {
            await tenantsApi.update(editingId.value, {
                name: form.name, code: form.code,
                domain: form.domain || undefined,
                description: form.description || undefined,
                validState: form.validState,
                menuIds,
            } as UpdateTenantForm)
            message.success('保存成功')
        } else {
            await tenantsApi.create({
                name: form.name, code: form.code,
                domain: form.domain || undefined,
                description: form.description || undefined,
                tenantType: form.tenantType,
                menuIds,
            } as CreateTenantForm)
            message.success('添加成功')
        }

        modalVisible.value = false
        refreshList()
    } catch (error: any) {
        if (error?.errorFields) return
        message.error(error?.response?.data?.message || '操作失败')
    } finally {
        submitLoading.value = false
    }
}

const handleCancel = () => {
    modalVisible.value = false
    formRef.value?.resetFields()
    activeTab.value = 'basic'
    form.menuIds = []
}

onMounted(() => { fetchAllMenus() })
</script>

<style scoped lang="scss">
$primary: #6366f1;

.search-form {
    margin-bottom: 16px;
}

.org-cell {
    .org-name {
        font-weight: 600;
        color: #1e1b4b;
        font-size: 14px;
        margin-bottom: 4px;
    }

    .org-code {
        :deep(.ant-tag) {
            font-size: 11px;
        }
    }
}

.stat-item {
    font-size: 13px;
    color: #6b7280;
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

.form-hint {
    font-size: 12px;
    color: #9ca3af;
}

// 菜单配置区域
.menu-config {
    .menu-config-hint {
        font-size: 13px;
        color: #6b7280;
        margin-bottom: 16px;
    }
}

.menu-group {
    margin-bottom: 16px;
    padding: 16px;
    background: #faf9fe;
    border-radius: 12px;

    .menu-group-header {
        margin-bottom: 10px;
        padding-bottom: 8px;
        border-bottom: 1px solid #f0ecf9;
    }

    .menu-items {
        padding-left: 24px;
    }
}
</style>
