<template>
  <section class="space-y-6">
    <ListSection :page="page" :total-pages="totalPages" @prev="page--" @next="page++">
      <template #title>审计日志</template>
      <template #subtitle>记录关键操作与配置变更。</template>
      <template #filters>
        <input class="mos-input !py-1 !px-2 !text-xs w-56" v-model="query" placeholder="搜索操作人/资源" />
        <input class="mos-input !py-1 !px-2 !text-xs" type="date" v-model="startDate" />
        <input class="mos-input !py-1 !px-2 !text-xs" type="date" v-model="endDate" />
      </template>
      <template #actions>
        <button class="mos-btn mos-btn-secondary !py-1 !px-2 !text-xs" @click="selectAll">
          {{ allSelected ? '取消全选' : '全选' }}
        </button>
        <button class="mos-btn mos-btn-secondary !py-1 !px-2 !text-xs" @click="batchExport">批量导出</button>
      </template>
      <template #default>
        <div class="space-y-3">
          <div v-for="log in pagedLogs" :key="log.id" class="flex items-center justify-between rounded-xl border border-mosquito-line px-4 py-3">
            <div class="flex items-center gap-3">
              <input
                type="checkbox"
                class="h-4 w-4"
                :checked="selectedIds.includes(log.id)"
                @click.stop
                @change.stop="toggleSelect(log.id)"
              />
              <div>
                <div class="text-sm font-semibold text-mosquito-ink">{{ log.action }}</div>
                <div class="mos-muted text-xs">{{ log.resource }}</div>
              </div>
            </div>
            <div class="text-xs text-mosquito-ink/70">
              <div>{{ log.actor }}</div>
              <div class="mos-muted">{{ formatDate(log.createdAt) }}</div>
            </div>
          </div>
        </div>
      </template>
      <template #footer>
        <ExportFieldPanel
          title="导出字段"
          :fields="exportFields"
          :selected="exportSelected"
          @update:selected="setExportSelected"
          @export="exportLogs"
        />
      </template>
    </ListSection>
  </section>
</template>

<script setup lang="ts">
import { computed, onMounted, ref, watch } from 'vue'
import { useDataService } from '../services'
import { downloadCsv } from '../utils/export'
import { useAuditStore } from '../stores/audit'
import ListSection from '../components/ListSection.vue'
import ExportFieldPanel, { type ExportField } from '../components/ExportFieldPanel.vue'
import { useExportFields } from '../composables/useExportFields'

type AuditLog = {
  id: string
  actor: string
  action: string
  resource: string
  createdAt: string
}

const logs = ref<AuditLog[]>([])
const service = useDataService()
const auditStore = useAuditStore()
const query = ref('')
const startDate = ref('')
const endDate = ref('')
const selectedIds = ref<string[]>([])
const page = ref(0)
const pageSize = 8

const formatDate = (value: string) => new Date(value).toLocaleString('zh-CN')

onMounted(async () => {
  const initial = await service.getAuditLogs()
  auditStore.init(initial)
  logs.value = auditStore.items
})

const exportFields: ExportField[] = [
  { key: 'actor', label: '操作人', required: true },
  { key: 'action', label: '动作' },
  { key: 'resource', label: '资源' },
  { key: 'createdAt', label: '时间' }
]
const { selected: exportSelected, setSelected: setExportSelected } = useExportFields(
  exportFields,
  exportFields.map((field) => field.key)
)

const exportLogs = () => {
  const headers = exportFields
    .filter((field) => exportSelected.value.includes(field.key))
    .map((field) => field.label)
  const rows = logs.value.map((item) =>
    exportFields
      .filter((field) => exportSelected.value.includes(field.key))
      .map((field) => {
        if (field.key === 'actor') return item.actor
        if (field.key === 'action') return item.action
        if (field.key === 'resource') return item.resource
        return formatDate(item.createdAt)
      })
  )
  downloadCsv('audit-logs-demo.csv', headers, rows)
}

const filteredLogs = computed(() => {
  return logs.value.filter((item) => {
    const keyword = query.value.trim()
    const matchesKeyword = keyword ? item.actor.includes(keyword) || item.resource.includes(keyword) : true
    const startOk = startDate.value ? new Date(item.createdAt).getTime() >= new Date(startDate.value).getTime() : true
    const endOk = endDate.value ? new Date(item.createdAt).getTime() <= new Date(endDate.value).getTime() : true
    return matchesKeyword && startOk && endOk
  })
})

const totalPages = computed(() => Math.max(1, Math.ceil(filteredLogs.value.length / pageSize)))

const pagedLogs = computed(() => {
  const start = page.value * pageSize
  return filteredLogs.value.slice(start, start + pageSize)
})

watch([query, startDate, endDate], () => {
  page.value = 0
})

const allSelected = computed(() => {
  return filteredLogs.value.length > 0 && filteredLogs.value.every((item) => selectedIds.value.includes(item.id))
})

const toggleSelect = (id: string) => {
  if (selectedIds.value.includes(id)) {
    selectedIds.value = selectedIds.value.filter((item) => item !== id)
  } else {
    selectedIds.value = [...selectedIds.value, id]
  }
}

const selectAll = () => {
  if (allSelected.value) {
    selectedIds.value = []
  } else {
    selectedIds.value = filteredLogs.value.map((item) => item.id)
  }
}

const batchExport = () => {
  const rows = filteredLogs.value
    .filter((item) => selectedIds.value.includes(item.id))
    .map((item) => [item.actor, item.action, item.resource, formatDate(item.createdAt)])
  downloadCsv('audit-logs-selected.csv', ['操作人', '动作', '资源', '时间'], rows)
}
</script>
