<template>
	<div class="container">
		<div class="search-area">
			<Form ref="searchForm" inline :label-width="100" :model="formInline">
				<FormItem prop="username" label="用户名：">
					<Input v-model="formInline.username" clearable placeholder="请输入用户名" @on-enter="handleSubmit" />
				</FormItem>
				<FormItem>
					<Button type="primary" @click="handleSubmit">搜索</Button>
					<Button style="margin-left: 8px" @click="resetSearch">重置</Button>
				</FormItem>
			</Form>
		</div>
		<div class="action-btn">
			<Button type="primary" @click="handleAdd">添加用户</Button>
		</div>
		<div class="table-container">
			<Table border stripe :loading="tableLoading" :columns="columns" :height="tableHeight" :data="data">
				<template #roles="{ row }">
					<span>{{ formatRoleLabel(row.roles) }}</span>
				</template>
				<template #action="{ row }">
					<Button type="primary" size="small" style="margin-right: 5px"
						@click="handleEdit(row.id)">编辑</Button>
					<Button type="error" size="small" @click="handleRemove(row.id)">删除</Button>
				</template>
			</Table>

			<Page :total="total" show-total show-sizer class="page" @on-change="onChangePage"
				@on-page-size-change="onChangePageSize" />
		</div>

		<Modal v-model="showModal" :title="modalTitle" :mask-closable="false" @on-cancel="cancel">
			<Form ref="formValidate" :model="formValidate" :rules="formRules" :label-width="100">
				<FormItem label="用户名" prop="username" :required="true">
					<Input v-model="formValidate.username" placeholder="请输入用户名" />
				</FormItem>
				<FormItem label="姓名" prop="nickname" :required="true">
					<Input v-model="formValidate.nickname" placeholder="请输入姓名" />
				</FormItem>
				<FormItem label="登录密码" prop="password" :required="!isEdit">
					<Input type="password" password v-model="formValidate.password"
						:placeholder="isEdit ? '不修改可留空' : '请输入登录密码'" />
				</FormItem>
				<FormItem label="手机号" prop="phone" :required="true">
					<Input v-model="formValidate.phone" placeholder="请输入11位手机号" />
				</FormItem>
				<FormItem label="邮箱" prop="email">
					<Input v-model="formValidate.email" placeholder="选填，需符合邮箱格式" />
				</FormItem>
				<FormItem label="角色" prop="roles" :required="true">
					<Select v-model="formValidate.roles" placeholder="请选择角色">
						<Option v-for="item in roleOptions" :value="item.id" :key="item.id">{{ item.name }}</Option>
					</Select>
				</FormItem>
			</Form>
			<div slot="footer">
				<Button type="text" @click="cancel">取消</Button>
				<Button type="primary" :loading="submitLoading" @click="ok">确定</Button>
			</div>
		</Modal>
	</div>
</template>

<script>
	import {
		getAdminList,
		addAdmin,
		getAdmin,
		getAdminUpdate,
		getAdminDelete,
		getRoleList,
	} from '@/api'

	const createDefaultForm = () => ({
		id: '',
		username: '',
		nickname: '',
		password: '',
		email: '',
		phone: '',
		roles: '',
	})

	export default {
		name: 'system_admin',
		data() {
			return {
				showModal: false,
				tableHeight: 500,
				tableLoading: false,
				submitLoading: false,
				page: 1,
				pageSize: 10,
				total: 0,
				formInline: {
					username: '',
				},
				// 表格列的结构描述，保持字段展示的一致性
				columns: [{
						title: 'ID',
						key: 'id',
						minWidth: 80,
					},
					{
						title: '用户名',
						key: 'username',
						minWidth: 140,
					},
					{
						title: '姓名',
						key: 'nickname',
						minWidth: 120,
					},
					{
						title: '手机号',
						key: 'phone',
						minWidth: 140,
					},
					{
						title: '邮箱',
						key: 'email',
						minWidth: 180,
					},
					{
						title: '角色',
						slot: 'roles',
						minWidth: 120,
					},
					{
						title: '操作',
						slot: 'action',
						width: 150,
						align: 'center',
					},
				],
				data: [], // 系统用户表格数据
				roleOptions: [], // 角色下拉选项
				formValidate: createDefaultForm(), // 弹窗表单数据
			}
		},
		computed: {
			isEdit() {
				return Boolean(this.formValidate.id)
			},
			modalTitle() {
				return this.isEdit ? '编辑系统用户' : '新增系统用户'
			},
			formRules() {
				return {
					username: [{
						required: true,
						message: '请输入用户名',
						trigger: 'blur',
					}],
					nickname: [{
						required: true,
						message: '请输入姓名',
						trigger: 'blur',
					}],
					password: [{
						validator: this.validatePassword,
						trigger: 'blur',
					}],
					phone: [{
						validator: this.validatePhone,
						trigger: 'blur',
					}],
					email: [{
						validator: this.validateEmail,
						trigger: 'blur',
					}],
					roles: [{
						validator: this.validateRoles,
						trigger: 'change',
					}],
				}
			},
		},
		mounted() {
			this.getList()
			this.fetchRoles()
			this.calculateTableHeight()
			window.addEventListener('resize', this.calculateTableHeight)
		},
		beforeDestroy() {
			window.removeEventListener('resize', this.calculateTableHeight)
		},
		methods: {
			// 统一创建弹窗表单的初始值，方便新增/编辑时复用
			getDefaultForm() {
				return createDefaultForm()
			},
			calculateTableHeight() {
				const searchHeight = document.querySelector('.search-area').offsetHeight
				const pageHeight = 32 // 分页组件大约高度
				const margins = 40 // 上下边距总和
				this.tableHeight = window.innerHeight - searchHeight - pageHeight - margins - 230
			},
			async fetchRoles() {
				const res = await getRoleList()
				this.roleOptions = res.data.data
			},
			async getList() {
				this.tableLoading = true
				try {
					const res = await getAdminList({
						page: this.page,
						pageSize: this.pageSize,
						...this.formInline,
					})
					this.data = res.data.data
					this.total = res.data.total
				} finally {
					this.tableLoading = false
				}
			},
			handleSubmit() {
				this.page = 1
				this.getList()
			},
			resetSearch() {
				this.formInline.username = ''
				this.handleSubmit()
			},
			handleAdd() {
				this.formValidate = this.getDefaultForm()
				this.showModal = true
			},
			async handleEdit(id) {
				// 编辑前需要获取详情，避免列表中数据字段不完整
				try {
					const res = await getAdmin({
						id,
					})
					const detail = res.data || {}
					this.formValidate = {
						id: detail.id,
						username: detail.username || '',
						nickname: detail.nickname || '',
						password: detail.password || '',
						email: detail.email || '',
						phone: detail.phone || '',
						roles: detail.roles === 0 || detail.roles ? Number(detail.roles) : '',
					}
					this.showModal = true
				} catch (error) {
					this.$Message.error('获取用户信息失败')
				}
			},
			async handleRemove(id) {
				// 删除需二次确认，避免误操作
				const confirm = await new Promise(resolve => {
					this.$Modal.confirm({
						title: '删除确认',
						content: '删除后不可恢复，是否继续？',
						onOk: () => resolve(true),
						onCancel: () => resolve(false),
					})
				})
				if (!confirm) {
					return
				}
				try {
					await getAdminDelete({
						id,
					})
					this.$Message.success('删除成功')
					if (this.data.length === 1 && this.page > 1) {
						this.page -= 1
					}
					this.getList()
				} catch (error) {
					this.$Message.error('删除失败，请稍后重试')
				}
			},
			validatePhone(rule, value, callback) {
				// 手机号验证：要求以 1 开头且总长 11 位，避免明显输入错误
				const phonePattern = /^1[3-9]\d{9}$/
				if (!value) {
					callback(new Error('请输入手机号'))
					return
				}
				if (!phonePattern.test(value)) {
					callback(new Error('手机号格式不正确'))
					return
				}
				callback()
			},
			validateEmail(rule, value, callback) {
				// 邮箱验证：允许省略，填写时需符合基础格式，连字符放在末尾避免正则范围冲突
				if (!value) {
					callback()
					return
				}
				const emailPattern = /^[\w.-]+@[\w-]+(\.[\w-]+)+$/
				if (!emailPattern.test(value)) {
					callback(new Error('邮箱格式不正确'))
					return
				}
				callback()
			},
			validatePassword(rule, value, callback) {
				// 密码验证：编辑时可留空，新建或主动修改时必须至少 6 位
				if (this.isEdit && !value) {
					callback()
					return
				}
				if (!value) {
					callback(new Error('请输入登录密码'))
					return
				}
				if (value.length < 6) {
					callback(new Error('密码至少6位'))
					return
				}
				callback()
			},
			validateRoles(rule, value, callback) {
				// 角色校验：接口允许 0 作为合法角色 ID，因此判空时需单独处理
				if (value === 0 || value === '0') {
					callback()
					return
				}
				if (!value) {
					callback(new Error('请选择角色'))
					return
				}
				callback()
			},
			formatRoleLabel(value) {
				// 将角色 ID 转为人类可读名称，兼容数组或单个值
				if (Array.isArray(value)) {
					return value.map(item => this.formatRoleLabel(item)).join('、')
				}
				const target = this.roleOptions.find(item => String(item.id) === String(value))
				return target ? target.name : value || '--'
			},
			async ok() {
				const valid = await new Promise(resolve => this.$refs.formValidate.validate(resolve))
				if (!valid) {
					this.$Message.error('请正确填写表单')
					return
				}
				const payload = {
					...this.formValidate,
				}
				if (this.isEdit) {
					if (!payload.password) {
						delete payload.password
					}
				} else {
					delete payload.id
				}
				this.submitLoading = true
				try {
					if (this.isEdit) {
						await getAdminUpdate(payload)
						this.$Message.success('更新成功')
					} else {
						await addAdmin(payload)
						this.$Message.success('新增成功')
					}
					this.cancel()
					this.getList()
				} finally {
					this.submitLoading = false
				}
			},
			cancel() {
				this.showModal = false
				this.formValidate = this.getDefaultForm()
				this.$nextTick(() => {
					if (this.$refs.formValidate) {
						this.$refs.formValidate.resetFields()
					}
				})
			},
			onChangePage(page) {
				if (this.page !== page) {
					this.page = page
					this.getList()
				}
			},
			onChangePageSize(size) {
				if (this.pageSize !== size) {
					this.page = 1
					this.pageSize = size
					this.getList()
				}
			},
		},
	}
</script>
<style scoped>
	.container {
		display: flex;
		flex-direction: column;
		height: 100vh;
		padding: 20px;
		box-sizing: border-box;
	}

	.action-btn {
		margin: 20px 0;
		background-color: white;
		padding: 20px;
		border: 1px solid #F3F7FD;
		border-radius: 15px;
		display: flex;
		align-items: center;
	}

	.action-btn button {
		margin-right: 20px;
	}

	.table-container {
		flex: 1;
		display: flex;
		flex-direction: column;
	}

	.page {
		margin-top: 10px;
		text-align: right;
	}

	.search-area {
		background-color: white;
		padding: 20px;
		border: 1px solid #F3F7FD;
		border-radius: 15px;
	}
</style>