import { ref, computed } from 'vue'
import type { AuditLog } from '~/services/dto/audit-log'
import { fetchAuditLogs, type AuditLogFilters } from '~/services/audit-logs'

type Range = { start: string, end: string } | null

export const useAuditLogsList = () => {
  const items = ref<AuditLog[]>([])
  const total = ref(0)
  const page = ref(1)
  const perPage = ref(10)
  const loading = ref(false)
  const filterOpen = ref(false)

  // Applied filters (drive the fetch)
  const appliedEmployee = ref('')
  const appliedRange = ref<Range>(null)
  const appliedEntityTypes = ref<string[]>([])
  const appliedActions = ref<string[]>([])
  const appliedUsername = ref('')
  const appliedIp = ref('')
  const appliedDevice = ref('')

  // Draft filters (edited inside the drawer)
  const draftEmployee = ref('')
  const draftRange = ref<Range>(null)
  const draftEntityTypes = ref<string[]>([])
  const draftActions = ref<string[]>([])
  const draftUsername = ref('')
  const draftIp = ref('')
  const draftDevice = ref('')

  const activeFilterCount = computed(() => {
    let n = 0
    if (appliedEmployee.value.trim() !== '') n++
    if (appliedRange.value?.start || appliedRange.value?.end) n++
    if (appliedEntityTypes.value.length > 0) n++
    if (appliedActions.value.length > 0) n++
    if (appliedUsername.value.trim() !== '') n++
    if (appliedIp.value.trim() !== '') n++
    if (appliedDevice.value.trim() !== '') n++
    return n
  })

  const buildFilters = (): AuditLogFilters => ({
    employee: appliedEmployee.value.trim() || undefined,
    from: appliedRange.value?.start || undefined,
    to: appliedRange.value?.end || undefined,
    entityType: appliedEntityTypes.value.length > 0 ? [...appliedEntityTypes.value] : undefined,
    action: appliedActions.value.length > 0 ? [...appliedActions.value] : undefined,
    username: appliedUsername.value.trim() || undefined,
    ip: appliedIp.value.trim() || undefined,
    device: appliedDevice.value.trim() || undefined,
    page: page.value,
    perPage: perPage.value,
  })

  // Race guard: only the latest request may commit its result.
  let requestSeq = 0
  const load = async () => {
    const seq = ++requestSeq
    loading.value = true
    try {
      const result = await fetchAuditLogs(buildFilters())
      if (seq !== requestSeq) return
      items.value = result.items
      total.value = result.total
      page.value = result.page
      perPage.value = result.perPage
    } finally {
      if (seq === requestSeq) loading.value = false
    }
  }

  const init = async () => {
    await load()
  }

  const goToPage = (n: number) => {
    page.value = n
    load()
  }

  const setPerPage = (n: number) => {
    perPage.value = n
    page.value = 1
    load()
  }

  const openFilters = () => {
    draftEmployee.value = appliedEmployee.value
    draftRange.value = appliedRange.value ? { ...appliedRange.value } : null
    draftEntityTypes.value = [...appliedEntityTypes.value]
    draftActions.value = [...appliedActions.value]
    draftUsername.value = appliedUsername.value
    draftIp.value = appliedIp.value
    draftDevice.value = appliedDevice.value
    filterOpen.value = true
  }

  const applyFilters = () => {
    appliedEmployee.value = draftEmployee.value
    appliedRange.value = draftRange.value ? { ...draftRange.value } : null
    appliedEntityTypes.value = [...draftEntityTypes.value]
    appliedActions.value = [...draftActions.value]
    appliedUsername.value = draftUsername.value
    appliedIp.value = draftIp.value
    appliedDevice.value = draftDevice.value
    page.value = 1
    filterOpen.value = false
    load()
  }

  const resetFilters = () => {
    draftEmployee.value = ''
    draftRange.value = null
    draftEntityTypes.value = []
    draftActions.value = []
    draftUsername.value = ''
    draftIp.value = ''
    draftDevice.value = ''
    appliedEmployee.value = ''
    appliedRange.value = null
    appliedEntityTypes.value = []
    appliedActions.value = []
    appliedUsername.value = ''
    appliedIp.value = ''
    appliedDevice.value = ''
    page.value = 1
    load() // drawer stays open
  }

  const toggle = (arr: typeof draftEntityTypes, value: string, selected: boolean) => {
    arr.value = selected ? [...arr.value, value] : arr.value.filter(v => v !== value)
  }
  const toggleEntityType = (value: string, selected: boolean) => toggle(draftEntityTypes, value, selected)
  const toggleAction = (value: string, selected: boolean) => toggle(draftActions, value, selected)

  return {
    items, total, page, perPage, loading, filterOpen, activeFilterCount,
    draftEmployee, draftRange, draftEntityTypes, draftActions, draftUsername, draftIp, draftDevice,
    init, goToPage, setPerPage, openFilters, applyFilters, resetFilters, toggleEntityType, toggleAction,
  }
}
