<template>
	<div class="pages-sidebar-layout log-page">
		<div class="left-box">
			<div class="header">日志筛选</div>
			<div class="body">
				<a-tree
					v-model:selectedKeys="selectedTreeKeys"
					:tree-data="filterTreeData"
					show-line
					:field-names="{
						title: 'title',
						key: 'key',
						children: 'children',
					}"
					@select="onTreeSelect"
				>
					<template #icon="{ dataRef }">
						<ApiOutlined v-if="dataRef.type === 'method'" />
						<CheckCircleOutlined v-else-if="dataRef.type === 'status' && dataRef.key === 'success'" />
						<CloseCircleOutlined v-else-if="dataRef.type === 'status' && dataRef.key === 'error'" />
					</template>
				</a-tree>
			</div>
		</div>
		<div class="right-box">
			<!-- 统计卡片 -->
			<div class="statistics-cards">
				<a-row :gutter="16">
					<a-col :span="6">
						<a-card size="small" class="stat-card">
							<a-statistic title="总日志数" :value="statistics.total || 0">
								<template #prefix>
									<FileTextOutlined style="color: #1890ff" />
								</template>
							</a-statistic>
						</a-card>
					</a-col>
					<a-col :span="6">
						<a-card size="small" class="stat-card">
							<a-statistic title="成功数" :value="statistics.success || 0">
								<template #prefix>
									<CheckCircleOutlined style="color: #52c41a" />
								</template>
							</a-statistic>
						</a-card>
					</a-col>
					<a-col :span="6">
						<a-card size="small" class="stat-card">
							<a-statistic title="失败数" :value="statistics.error || 0">
								<template #prefix>
									<CloseCircleOutlined style="color: #ff4d4f" />
								</template>
							</a-statistic>
						</a-card>
					</a-col>
					<a-col :span="6">
						<a-card size="small" class="stat-card">
							<a-statistic title="平均响应时间" :value="statistics.avg_time || 0" suffix="ms">
								<template #prefix>
									<ClockCircleOutlined style="color: #faad14" />
								</template>
							</a-statistic>
						</a-card>
					</a-col>
				</a-row>
			</div>

			<!-- 工具栏 -->
			<div class="tool-bar">
				<div class="left-panel">
					<a-space>
						<a-range-picker v-model:value="dateRange" :placeholder="['开始时间', '结束时间']" style="width: 260px" @change="handleDateChange" />
						<a-button type="primary" @click="handleSearch">
							<template #icon><SearchOutlined /></template>
							搜索
						</a-button>
						<a-button @click="handleLogReset">
							<template #icon><RedoOutlined /></template>
							清除
						</a-button>
					</a-space>
				</div>
				<div class="right-panel">
					<a-space>
						<a-button @click="handleExport" :loading="exportLoading">
							<template #icon><DownloadOutlined /></template>
							导出
						</a-button>
						<a-dropdown>
							<a-button>
								更多
								<DownOutlined />
							</a-button>
							<template #overlay>
								<a-menu>
									<a-menu-item @click="handleClearLogs"> <DeleteOutlined />清理日志 </a-menu-item>
									<a-menu-item @click="handleRefreshStats"> <ReloadOutlined />刷新统计 </a-menu-item>
								</a-menu>
							</template>
						</a-dropdown>
					</a-space>
				</div>
			</div>
			<div class="table-content">
				<sc-table ref="tableRef" :columns="columns" :data-source="tableData" :loading="loading" :pagination="pagination" :row-key="rowKey" @refresh="refreshTable" @paginationChange="handlePaginationChange">
					<template #status="{ record }">
						<a-tag :color="record.status === 'success' ? 'success' : 'error'">
							{{ record.status === 'success' ? '成功' : '失败' }}
						</a-tag>
					</template>
					<template #method="{ record }">
						<a-tag :color="getMethodColor(record.method)">
							{{ record.method }}
						</a-tag>
					</template>
					<template #execution_time="{ record }">
						<span
							:style="{
								color: record.execution_time > 1000 ? '#ff4d4f' : record.execution_time > 500 ? '#faad14' : '#52c41a',
							}"
						>
							{{ record.execution_time }}ms
						</span>
					</template>
					<template #action="{ record }">
						<a-space>
							<a-button type="link" size="small" @click="handleView(record)">查看详情</a-button>
							<a-popconfirm title="确定删除该日志吗？" @confirm="handleDelete(record)">
								<a-button type="link" size="small" danger>删除</a-button>
							</a-popconfirm>
						</a-space>
					</template>
				</sc-table>
			</div>
		</div>
	</div>

	<!-- 日志详情弹窗 -->
	<detail-dialog ref="detailDialogRef" />

	<!-- 清理日志确认弹窗 -->
	<a-modal v-model:open="dialog.clear" title="清理日志" :confirm-loading="clearLoading" @ok="handleConfirmClear">
		<a-form layout="vertical">
			<a-form-item label="清理天数">
				<a-input-number v-model:value="clearDays" :min="1" :max="365" style="width: 100%" placeholder="请输入天数" />
			</a-form-item>
			<a-alert message="删除指定天数之前的日志记录，此操作不可恢复" type="warning" show-icon />
		</a-form>
	</a-modal>
</template>

<script setup>
import { ref, reactive, onMounted, computed } from 'vue'
import { message } from 'ant-design-vue'
import { SearchOutlined, RedoOutlined, DeleteOutlined, DownOutlined, ApiOutlined, CheckCircleOutlined, CloseCircleOutlined, FileTextOutlined, ClockCircleOutlined, DownloadOutlined, ReloadOutlined } from '@ant-design/icons-vue'
import scTable from '@/components/scTable/index.vue'
import detailDialog from './components/DetailDialog.vue'
import systemApi from '@/api/system'
import { useTable } from '@/hooks/useTable'

defineOptions({
	name: 'systemLog',
})

// 统计数据
const statistics = ref({
	total: 0,
	success: 0,
	error: 0,
	avg_time: 0,
})

// 使用useTable hooks
const { tableRef, searchForm, tableData, loading, pagination, handleSearch, handlePaginationChange, refreshTable } = useTable({
	api: systemApi.log.list.get,
	searchForm: {
		method: '',
		status: '',
		start_date: '',
		end_date: '',
	},
	columns: [],
	needPagination: true,
})

// 对话框状态
const dialog = reactive({
	detail: false,
	clear: false,
})

// 弹窗引用
const detailDialogRef = ref(null)

// 清理日志相关
const clearDays = ref(30)
const clearLoading = ref(false)

// 导出相关
const exportLoading = ref(false)

// 日期范围
const dateRange = ref([])

// 树形筛选数据
const treeData = ref([
	{
		title: '请求方式',
		key: 'method-root',
		type: 'root',
		children: [
			{ title: 'GET', key: 'GET', type: 'method' },
			{ title: 'POST', key: 'POST', type: 'method' },
			{ title: 'PUT', key: 'PUT', type: 'method' },
			{ title: 'DELETE', key: 'DELETE', type: 'method' },
			{ title: 'PATCH', key: 'PATCH', type: 'method' },
		],
	},
	{
		title: '返回状态',
		key: 'status-root',
		type: 'root',
		children: [
			{ title: '成功', key: 'success', type: 'status' },
			{ title: '失败', key: 'error', type: 'status' },
		],
	},
])

// 选中的树节点
const selectedTreeKeys = ref([])

// 行key
const rowKey = 'id'

// 过滤后的树数据
const filterTreeData = computed(() => {
	return treeData.value
})

// 获取请求方式颜色
const getMethodColor = (method) => {
	const colors = {
		GET: 'blue',
		POST: 'green',
		PUT: 'orange',
		DELETE: 'red',
		PATCH: 'purple',
	}
	return colors[method] || 'default'
}

// 表格列配置
const columns = [
	{ title: 'ID', dataIndex: 'id', key: 'id', width: 80 },
	{ title: '用户名', dataIndex: 'username', key: 'username', width: 120 },
	{ title: '模块', dataIndex: 'module', key: 'module', width: 120 },
	{ title: '操作', dataIndex: 'action', key: 'action', width: 150 },
	{
		title: '请求方式',
		dataIndex: 'method',
		key: 'method',
		width: 100,
		align: 'center',
		slot: 'method',
	},
	{ title: 'URL', dataIndex: 'url', key: 'url', ellipsis: true },
	{ title: 'IP地址', dataIndex: 'ip', key: 'ip', width: 140 },
	{
		title: '状态码',
		dataIndex: 'status_code',
		key: 'status_code',
		width: 100,
		align: 'center',
	},
	{
		title: '状态',
		dataIndex: 'status',
		key: 'status',
		width: 100,
		align: 'center',
		slot: 'status',
	},
	{
		title: '执行时间',
		dataIndex: 'execution_time',
		key: 'execution_time',
		width: 120,
		align: 'center',
		slot: 'execution_time',
	},
	{
		title: '创建时间',
		dataIndex: 'created_at',
		key: 'created_at',
		width: 180,
	},
	{
		title: '操作',
		dataIndex: 'table_action',
		key: 'table_action',
		width: 150,
		align: 'center',
		slot: 'action',
		fixed: 'right',
	},
]

// 加载统计数据
const loadStatistics = async () => {
	try {
		const res = await systemApi.log.statistics.get(searchForm)
		if (res.code === 200) {
			statistics.value = res.data
		}
	} catch (error) {
		console.error('加载统计数据失败:', error)
	}
}

// 树形选择事件
const onTreeSelect = (selectedKeys, { selectedNodes }) => {
	if (selectedKeys.length > 0) {
		const key = selectedKeys[0]
		const node = selectedNodes[0]

		// 重置搜索表单
		searchForm.method = ''
		searchForm.status = ''

		// 根据节点类型设置对应的筛选条件
		if (node.type === 'method') {
			searchForm.method = key
		} else if (node.type === 'status') {
			searchForm.status = key
		}

		// 触发搜索
		handleSearch()
		// 同时刷新统计数据
		loadStatistics()
	} else {
		// 取消选择时清空筛选条件
		searchForm.method = ''
		searchForm.status = ''
		handleSearch()
		// 同时刷新统计数据
		loadStatistics()
	}
}

// 日期变化
const handleDateChange = (dates) => {
	if (dates && dates.length === 2) {
		searchForm.start_date = dates[0].format('YYYY-MM-DD HH:mm:ss')
		searchForm.end_date = dates[1].format('YYYY-MM-DD HH:mm:ss')
	} else {
		searchForm.start_date = ''
		searchForm.end_date = ''
	}
	// 自动触发搜索
	handleSearch()
	// 同时刷新统计数据
	loadStatistics()
}

// 重置
const handleLogReset = () => {
	// 重置日期范围
	dateRange.value = []
	searchForm.start_date = ''
	searchForm.end_date = ''

	// 重置树形选择
	selectedTreeKeys.value = []
	searchForm.method = ''
	searchForm.status = ''

	// 重置分页到第一页
	pagination.current = 1

	// 触发搜索
	handleSearch()
	// 同时刷新统计数据
	loadStatistics()
}

// 查看详情
const handleView = async (record) => {
	const dialog = await detailDialogRef.value?.open()
	dialog?.setData(record)
}

// 删除日志
const handleDelete = async (record) => {
	try {
		const res = await systemApi.log.delete.delete(record.id)
		if (res.code === 200) {
			message.success('删除成功')
			refreshTable()
			// 同时刷新统计数据
			loadStatistics()
		} else {
			message.error(res.message || '删除失败')
		}
	} catch (error) {
		console.error('删除日志失败:', error)
		message.error('删除失败')
	}
}

// 清理日志
const handleClearLogs = () => {
	dialog.clear = true
}

// 确认清理日志
const handleConfirmClear = async () => {
	if (!clearDays.value || clearDays.value < 1) {
		message.warning('请输入有效的天数')
		return
	}

	clearLoading.value = true
	try {
		const res = await systemApi.log.clear.post({ days: clearDays.value })
		if (res.code === 200) {
			message.success('清理成功')
			dialog.clear = false
			clearDays.value = 30
			refreshTable()
			// 同时刷新统计数据
			loadStatistics()
		} else {
			message.error(res.message || '清理失败')
		}
	} catch (error) {
		console.error('清理日志失败:', error)
		message.error('清理失败')
	} finally {
		clearLoading.value = false
	}
}

// 刷新统计
const handleRefreshStats = () => {
	loadStatistics()
}

// 导出日志
const handleExport = async () => {
	exportLoading.value = true
	try {
		const blob = await systemApi.log.export.get(searchForm)

		// 创建下载链接
		const url = window.URL.createObjectURL(blob)
		const link = document.createElement('a')
		link.href = url
		link.download = `系统日志_${new Date().getTime()}.xlsx`
		document.body.appendChild(link)
		link.click()
		document.body.removeChild(link)
		window.URL.revokeObjectURL(url)

		message.success('导出成功')
	} catch (error) {
		console.error('导出失败:', error)
		message.error('导出失败')
	} finally {
		exportLoading.value = false
	}
}

// 初始化
onMounted(() => {
	// 页面加载时自动搜索一次
	handleSearch()
	// 加载统计数据
	loadStatistics()
})
</script>

<style scoped lang="scss">
.log-page {
	.statistics-cards {
		margin-bottom: 16px;
		background: #fff;
		padding: 16px;
		border-bottom: 1px solid #f0f0f0;

		.stat-card {
			text-align: center;
		}
	}
}
</style>
