<template>
  <div class="admin-logs">
    <h1 class="page-title">操作日志管理</h1>
    
    <div class="toolbar">
      <div class="filter-section">
        <div class="filter-main">
          <button
            type="button"
            class="filter-toggle btn btn-sm btn-secondary"
            @click="filterExpanded = !filterExpanded"
          >
            {{ filterExpanded ? '收起筛选 ▲' : '展开筛选 ▼' }}
          </button>
          <div class="filter-actions">
            <button type="button" class="btn btn-sm btn-primary" @click="handleSearch">查询</button>
            <button type="button" class="btn btn-sm btn-secondary" @click="resetFilters">重置</button>
          </div>
        </div>
        <Transition name="filter-panel">
          <div v-if="filterExpanded" class="filter-panel">
            <div class="filter-group">
              <label>操作描述</label>
              <input v-model="filters.action" type="text" class="filter-input" placeholder="模糊搜索" @keyup.enter="handleSearch" />
            </div>
            <div class="filter-group">
              <label>方法</label>
              <CustomSelect v-model="filters.method" :options="methodOptions" style="width: 100px;" />
            </div>
            <div class="filter-group">
              <label>状态</label>
              <CustomSelect v-model.number="filters.status" :options="statusOptions" style="width: 100px;" />
            </div>
            <div class="filter-group">
              <label>操作人</label>
              <UserPickerPopover v-model="filters.userId" />
            </div>
            <div class="filter-group">
              <label>开始时间</label>
              <input v-model="startDateTime" type="datetime-local" class="filter-input datetime-input" />
            </div>
            <div class="filter-group">
              <label>结束时间</label>
              <input v-model="endDateTime" type="datetime-local" class="filter-input datetime-input" />
            </div>
            <div class="filter-group">
              <label>每页</label>
              <CustomSelect
                v-model.number="pageSize"
                :options="pageSizeOptions"
                style="width: 80px;"
              />
            </div>
          </div>
        </Transition>
      </div>
    </div>
    
    <div class="table-container">
      <table class="admin-table">
        <thead>
          <tr>
            <th>ID</th>
            <th>操作人</th>
            <th>操作描述</th>
            <th>IP地址</th>
            <th>归属地</th>
            <th>路径</th>
            <th>方法</th>
            <th>状态</th>
            <th>耗时(ms)</th>
            <th>操作时间</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="log in logs.list" :key="log.id">
            <td>{{ log.id }}</td>
            <td>{{ log.username }}</td>
            <td class="action-description">{{ log.action || `${log.method} ${log.path}` }}</td>
            <td class="font-mono text-xs">{{ log.ip }}</td>
            <td>{{ log.region || 'Unknown' }}</td>
            <td class="log-path">{{ log.path }}</td>
            <td>
              <span :class="['method-badge', `method-${log.method.toLowerCase()}`]">
                {{ log.method }}
              </span>
            </td>
            <td>
              <span :class="['status-badge', getStatusClass(log.status)]">
                {{ log.status }}
              </span>
            </td>
            <td>{{ log.duration }}</td>
            <td>{{ formatDate(log.createdAt) }}</td>
          </tr>
        </tbody>
      </table>
    </div>
    
    <div v-if="logs.list.length === 0" class="empty-state">
      <p>暂无操作日志</p>
    </div>
    
    <!-- Pagination -->
    <div v-if="logs.list.length > 0" class="pagination">
      <button 
        class="btn btn-sm btn-secondary" 
        :disabled="currentPage === 1" 
        @click="changePage(currentPage - 1)"
      >
        上一页
      </button>
      <span class="page-info">
        第 {{ currentPage }} 页，共 {{ totalPages }} 页，总计 {{ logs.total }} 条记录
      </span>
      <button 
        class="btn btn-sm btn-secondary" 
        :disabled="currentPage === totalPages" 
        @click="changePage(currentPage + 1)"
      >
        下一页
      </button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, computed, reactive } from 'vue'
import { getOperationLogs, PaginationResponse, OperationLog } from '../../services/api'
import { useToast } from '../../composables/useToast'
import CustomSelect from '../../components/CustomSelect.vue'
import UserPickerPopover from '../../components/admin/UserPickerPopover.vue'
import { getDefaultMonthRange, toApiDateTime } from '../../utils/dateRange'

const toast = useToast()
const filterExpanded = ref(false)
const defaultRange = getDefaultMonthRange()
const logs = ref<PaginationResponse<OperationLog>>({
  list: [],
  total: 0,
  page: 1,
  size: 10
})
const currentPage = ref(1)
const pageSize = ref(10)
const startDateTime = ref(defaultRange.start)
const endDateTime = ref(defaultRange.end)

const filters = reactive({
  action: '',
  method: '',
  status: 0,
  userId: null as number | null
})

const pageSizeOptions = [
  { value: 10, label: '10' },
  { value: 20, label: '20' },
  { value: 50, label: '50' },
  { value: 100, label: '100' }
]

const methodOptions = [
  { value: '', label: '全部' },
  { value: 'GET', label: 'GET' },
  { value: 'POST', label: 'POST' },
  { value: 'PUT', label: 'PUT' },
  { value: 'PATCH', label: 'PATCH' },
  { value: 'DELETE', label: 'DELETE' }
]

const statusOptions = [
  { value: 0, label: '全部' },
  { value: 200, label: '200' },
  { value: 201, label: '201' },
  { value: 400, label: '400' },
  { value: 401, label: '401' },
  { value: 403, label: '403' },
  { value: 404, label: '404' },
  { value: 500, label: '500' }
]

const totalPages = computed(() => Math.ceil(logs.value.total / pageSize.value) || 1)

const buildFilters = () => ({
  action: filters.action || undefined,
  method: filters.method || undefined,
  status: filters.status || undefined,
  userId: filters.userId ?? undefined,
  startDate: toApiDateTime(startDateTime.value) || undefined,
  endDate: toApiDateTime(endDateTime.value) || undefined
})

const fetchLogs = async () => {
  try {
    logs.value = await getOperationLogs(currentPage.value, pageSize.value, buildFilters())
  } catch (error) {
    console.error('Error fetching operation logs:', error)
    toast.error('获取操作日志失败')
  }
}

const handleSearch = () => {
  currentPage.value = 1
  fetchLogs()
}

const resetFilters = () => {
  const range = getDefaultMonthRange()
  filters.action = ''
  filters.method = ''
  filters.status = 0
  filters.userId = null
  startDateTime.value = range.start
  endDateTime.value = range.end
  currentPage.value = 1
  fetchLogs()
}

const changePage = (page: number) => {
  currentPage.value = page
  fetchLogs()
}

const getStatusClass = (status: number) => {
  if (status >= 200 && status < 300) {
    return 'success'
  } else if (status >= 400 && status < 500) {
    return 'warning'
  } else if (status >= 500) {
    return 'error'
  }
  return ''
}

const formatDate = (dateString: string) => {
  const date = new Date(dateString)
  return date.toLocaleString('zh-CN')
}

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

<style scoped>
.admin-logs {
  max-width: 1200px;
  margin: 0 auto;
}

.page-title {
  font-size: 1.5rem;
  font-weight: 600;
  margin-bottom: 1.5rem;
  color: #d4b383;
  font-family: 'Inter', sans-serif;
}

.toolbar {
  margin-bottom: 1rem;
}

.filter-section {
  background: rgba(255, 255, 255, 0.05);
  padding: 1rem;
  border-radius: 0.5rem;
  border: 1px solid rgba(255, 255, 255, 0.1);
}

.filter-main {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1rem;
}

.filter-toggle {
  flex-shrink: 0;
  white-space: nowrap;
}

.filter-panel {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.75rem 1rem;
  width: 100%;
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}

.filter-panel-enter-active,
.filter-panel-leave-active {
  transition: opacity 0.2s ease, max-height 0.25s ease;
  overflow: hidden;
}

.filter-panel-enter-from,
.filter-panel-leave-to {
  opacity: 0;
  max-height: 0;
}

.filter-panel-enter-to,
.filter-panel-leave-from {
  opacity: 1;
  max-height: 500px;
}

.filter-actions {
  display: flex;
  gap: 0.5rem;
  flex: 0 0 auto;
  flex-shrink: 0;
  margin-left: auto;
}

.filter-input {
  padding: 0.5rem 0.75rem;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 0.375rem;
  font-size: 0.875rem;
  background: rgba(255, 255, 255, 0.05);
  color: white;
  font-family: 'Inter', sans-serif;
  min-width: 140px;
}

.datetime-input {
  min-width: 180px;
}

.filter-input:focus {
  outline: none;
  border-color: #d4b383;
}

.filter-group {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  flex: 0 0 auto;
  flex-shrink: 0;
}

.filter-group label {
  font-weight: 500;
  color: rgba(255, 255, 255, 0.8);
  font-size: 0.875rem;
  font-family: 'Inter', sans-serif;
}

.form-select {
  padding: 0.5rem;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 0.375rem;
  font-size: 0.875rem;
  background: rgba(255, 255, 255, 0.05);
  color: white;
  font-family: 'Inter', sans-serif;
}

.table-container {
  background: rgba(255, 255, 255, 0.05);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-radius: 0.5rem;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  overflow-x: auto;
  margin-bottom: 1rem;
  border: 1px solid rgba(255, 255, 255, 0.1);
}

.admin-table {
  width: 100%;
  border-collapse: collapse;
  min-width: 800px;
  color: white;
}

.admin-table th,
.admin-table td {
  padding: 0.75rem 1rem;
  text-align: left;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  font-size: 0.875rem;
  font-family: 'Inter', sans-serif;
}

.admin-table th {
  background: rgba(255, 255, 255, 0.08);
  font-weight: 600;
  color: #d4b383;
  white-space: nowrap;
}

.admin-table tr:hover {
  background: rgba(212, 179, 131, 0.05);
}

.log-path {
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.action-description {
  color: #d4b383;
  font-weight: 500;
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.method-badge {
  display: inline-block;
  padding: 0.125rem 0.375rem;
  border-radius: 9999px;
  font-size: 0.75rem;
  font-weight: 600;
  color: white;
  min-width: 40px;
  text-align: center;
  font-family: 'Inter', sans-serif;
}

.method-get {
  background-color: #3b82f6;
}

.method-post {
  background-color: #10b981;
}

.method-put {
  background-color: #f59e0b;
}

.method-delete {
  background-color: #ef4444;
}

.method-patch {
  background-color: #8b5cf6;
}

.method-options {
  background-color: #6b7280;
}

.status-badge {
  display: inline-block;
  padding: 0.125rem 0.375rem;
  border-radius: 9999px;
  font-size: 0.75rem;
  font-weight: 600;
  min-width: 40px;
  text-align: center;
  font-family: 'Inter', sans-serif;
}

.status-badge.success {
  background-color: rgba(16, 185, 129, 0.2);
  color: #10b981;
  border: 1px solid rgba(16, 185, 129, 0.3);
}

.status-badge.warning {
  background-color: rgba(251, 191, 36, 0.2);
  color: #f59e0b;
  border: 1px solid rgba(251, 191, 36, 0.3);
}

.status-badge.error {
  background-color: rgba(239, 68, 68, 0.2);
  color: #ef4444;
  border: 1px solid rgba(239, 68, 68, 0.3);
}

.btn {
  padding: 0.5rem 1rem;
  border-radius: 0.375rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  border: 1px solid transparent;
  font-family: 'Inter', sans-serif;
}

.btn-sm {
  padding: 0.25rem 0.5rem;
  font-size: 0.875rem;
}

.btn-primary {
  background-color: #d4b383;
  color: #050505;
  border-color: #d4b383;
}

.btn-primary:hover {
  background-color: transparent;
  color: #d4b383;
  box-shadow: 0 0 15px rgba(212, 179, 131, 0.3);
}

.btn-secondary {
  background-color: rgba(255, 255, 255, 0.1);
  color: rgba(255, 255, 255, 0.8);
  border-color: rgba(255, 255, 255, 0.2);
}

.btn-secondary:hover:not(:disabled) {
  background-color: rgba(212, 179, 131, 0.1);
  border-color: #d4b383;
  color: #d4b383;
}

.btn-secondary:disabled {
  background-color: rgba(255, 255, 255, 0.05);
  color: rgba(255, 255, 255, 0.4);
  border-color: rgba(255, 255, 255, 0.1);
  cursor: not-allowed;
}

.empty-state {
  text-align: center;
  padding: 2rem;
  color: rgba(255, 255, 255, 0.6);
  background: rgba(255, 255, 255, 0.05);
  border-radius: 0.5rem;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.1);
  font-family: 'Inter', sans-serif;
}

.pagination {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 1rem;
  margin-top: 1rem;
}

.page-info {
  font-size: 0.875rem;
  color: rgba(255, 255, 255, 0.6);
  font-family: 'Inter', sans-serif;
}
</style>