<template>
  <div>
    <!-- Page Header -->
    <div class="mb-8">
      <h1 class="text-2xl font-bold text-white">{{ $t('persons.title') }}</h1>
      <p class="text-slate-400 mt-1">{{ $t('persons.subtitle') }}</p>
    </div>

    <!-- Search & Filter Bar -->
    <div class="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4 mb-6">
      <div class="relative flex-1 max-w-md">
        <svg class="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
        </svg>
        <input
          v-model="searchQuery"
          type="text"
          :placeholder="$t('persons.search_placeholder')"
          class="w-full pl-10 pr-4 py-2.5 bg-slate-800 border border-slate-700 rounded-lg text-sm text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500 transition"
        />
      </div>
      <div class="flex items-center gap-2 flex-wrap">
        <!-- Ghost Filter -->
        <select
          v-model="ghostFilter"
          class="px-3 py-2.5 bg-slate-800 border border-slate-700 rounded-lg text-sm text-slate-300 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 transition"
        >
          <option value="all">{{ $t('persons.all_ghost_statuses') }}</option>
          <option value="no">{{ $t('persons.ghost_no') }}</option>
          <option value="yes">{{ $t('persons.ghost_yes') }}</option>
        </select>
        <!-- Active Filter -->
        <select
          v-model="activeFilter"
          class="px-3 py-2.5 bg-slate-800 border border-slate-700 rounded-lg text-sm text-slate-300 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 transition"
        >
          <option value="all">{{ $t('persons.all_active_statuses') }}</option>
          <option value="active">{{ $t('persons.active_yes') }}</option>
          <option value="inactive">{{ $t('persons.active_no') }}</option>
        </select>
        <!-- Has User Filter -->
        <select
          v-model="hasUserFilter"
          class="px-3 py-2.5 bg-slate-800 border border-slate-700 rounded-lg text-sm text-slate-300 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 transition"
        >
          <option value="all">{{ $t('persons.all_user_statuses') }}</option>
          <option value="yes">{{ $t('persons.has_user_yes') }}</option>
          <option value="no">{{ $t('persons.has_user_no') }}</option>
        </select>
        <!-- Merged Filter -->
        <select
          v-model="mergedFilter"
          class="px-3 py-2.5 bg-slate-800 border border-slate-700 rounded-lg text-sm text-slate-300 focus:outline-none focus:ring-2 focus:ring-indigo-500/50 transition"
        >
          <option value="all">{{ $t('persons.all_merged_statuses') }}</option>
          <option value="no">{{ $t('persons.merged_no') }}</option>
          <option value="yes">{{ $t('persons.merged_yes') }}</option>
        </select>
      </div>
    </div>

    <!-- Loading State -->
    <div v-if="loading" class="flex items-center justify-center py-20">
      <div class="flex flex-col items-center gap-3">
        <svg class="w-8 h-8 text-indigo-400 animate-spin" fill="none" viewBox="0 0 24 24">
          <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" />
          <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
        </svg>
        <p class="text-slate-400 text-sm">{{ $t('persons.loading') }}</p>
      </div>
    </div>

    <!-- Error State -->
    <div v-else-if="error" class="flex flex-col items-center justify-center py-20 text-center">
      <svg class="w-12 h-12 text-red-500 mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z" />
      </svg>
      <p class="text-red-400 text-sm mb-2">{{ error }}</p>
      <button @click="fetchPersons" class="px-4 py-2 text-sm bg-indigo-600/20 text-indigo-300 hover:bg-indigo-600/30 rounded-lg transition">
        {{ $t('persons.retry') }}
      </button>
    </div>

    <!-- Content -->
    <template v-else>
      <!-- Stats Cards Row -->
      <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 mb-8">
        <!-- Total Persons -->
        <div class="bg-slate-800 rounded-xl border border-slate-700 p-4">
          <div class="flex items-center gap-3">
            <div class="p-2 rounded-lg bg-indigo-500/10 text-indigo-400">
              <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0z" />
              </svg>
            </div>
            <div>
              <p class="text-xs text-slate-400 uppercase tracking-wider">{{ $t('persons.total_persons') }}</p>
              <p class="text-2xl font-bold text-white">{{ totalCount }}</p>
            </div>
          </div>
        </div>
        <!-- Active Persons -->
        <div class="bg-slate-800 rounded-xl border border-slate-700 p-4">
          <div class="flex items-center gap-3">
            <div class="p-2 rounded-lg bg-emerald-500/10 text-emerald-400">
              <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
              </svg>
            </div>
            <div>
              <p class="text-xs text-slate-400 uppercase tracking-wider">{{ $t('persons.active_persons') }}</p>
              <p class="text-2xl font-bold text-emerald-400">{{ activeCount }}</p>
            </div>
          </div>
        </div>
        <!-- Ghost Persons -->
        <div class="bg-slate-800 rounded-xl border border-slate-700 p-4">
          <div class="flex items-center gap-3">
            <div class="p-2 rounded-lg bg-amber-500/10 text-amber-400">
              <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636" />
              </svg>
            </div>
            <div>
              <p class="text-xs text-slate-400 uppercase tracking-wider">{{ $t('persons.ghost_persons') }}</p>
              <p class="text-2xl font-bold text-amber-400">{{ ghostCount }}</p>
            </div>
          </div>
        </div>
        <!-- Merged Persons -->
        <div class="bg-slate-800 rounded-xl border border-slate-700 p-4">
          <div class="flex items-center gap-3">
            <div class="p-2 rounded-lg bg-red-500/10 text-red-400">
              <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
              </svg>
            </div>
            <div>
              <p class="text-xs text-slate-400 uppercase tracking-wider">{{ $t('persons.merged_persons') }}</p>
              <p class="text-2xl font-bold text-red-400">{{ mergedCount }}</p>
            </div>
          </div>
        </div>
      </div>

      <!-- Filtered results indicator -->
      <div v-if="isFilterActive" class="mb-4 text-xs text-slate-500">
        {{ $t('persons.filtered_results') }}: <span class="text-slate-300 font-semibold">{{ persons.length }}</span> / {{ totalCount }} db
      </div>

      <!-- Data Table -->
      <div class="bg-slate-800/50 border border-slate-700 rounded-xl overflow-hidden">
        <div class="overflow-x-auto">
          <table class="w-full text-sm">
            <thead>
              <tr class="border-b border-slate-700 bg-slate-800/80">
                <th class="text-left py-3.5 px-4 text-xs font-semibold uppercase tracking-wider text-slate-400">ID</th>
                <th class="text-left py-3.5 px-4 text-xs font-semibold uppercase tracking-wider text-slate-400">{{ $t('persons.name') }}</th>
                <th class="text-left py-3.5 px-4 text-xs font-semibold uppercase tracking-wider text-slate-400">{{ $t('persons.phone') }}</th>
                <th class="text-left py-3.5 px-4 text-xs font-semibold uppercase tracking-wider text-slate-400">{{ $t('persons.birth_date') }}</th>
                <th class="text-left py-3.5 px-4 text-xs font-semibold uppercase tracking-wider text-slate-400">{{ $t('persons.status') }}</th>
                <th class="text-left py-3.5 px-4 text-xs font-semibold uppercase tracking-wider text-slate-400">{{ $t('persons.users_count') }}</th>
                <th class="text-left py-3.5 px-4 text-xs font-semibold uppercase tracking-wider text-slate-400">{{ $t('persons.active_user') }}</th>
                <th class="text-left py-3.5 px-4 text-xs font-semibold uppercase tracking-wider text-slate-400">{{ $t('persons.address') }}</th>
                <th class="text-left py-3.5 px-4 text-xs font-semibold uppercase tracking-wider text-slate-400">{{ $t('persons.actions') }}</th>
              </tr>
            </thead>
            <tbody>
              <tr
                v-for="person in persons"
                :key="person.id"
                class="border-b border-slate-700/50 hover:bg-slate-700/30 transition"
              >
                <!-- ID -->
                <td class="py-3.5 px-4 text-slate-400 font-mono text-xs">{{ person.id }}</td>
                <!-- Name -->
                <td class="py-3.5 px-4">
                  <NuxtLink
                    :to="'/persons/' + person.id"
                    class="text-sm font-medium text-white hover:underline cursor-pointer hover:text-indigo-400 transition-colors"
                  >
                    {{ person.last_name }} {{ person.first_name }}
                  </NuxtLink>
                </td>
                <!-- Phone -->
                <td class="py-3.5 px-4 text-slate-300">{{ person.phone || '—' }}</td>
                <!-- Birth Date -->
                <td class="py-3.5 px-4 text-slate-300 text-xs">{{ formatDate(person.birth_date) }}</td>
                <!-- Status -->
                <td class="py-3.5 px-4">
                  <div class="flex flex-wrap gap-1">
                    <span
                      class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium"
                      :class="person.is_active ? 'bg-emerald-500/10 text-emerald-400' : 'bg-amber-500/10 text-amber-400'"
                    >
                      <span
                        class="w-1.5 h-1.5 rounded-full mr-1.5"
                        :class="person.is_active ? 'bg-emerald-400' : 'bg-amber-400'"
                      ></span>
                      {{ person.is_active ? $t('persons.active') : $t('persons.inactive') }}
                    </span>
                    <span
                      v-if="person.is_ghost"
                      class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-purple-500/20 text-purple-300"
                    >
                      {{ $t('persons.ghost') }}
                    </span>
                    <span
                      v-if="person.merged_into_id"
                      class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-500/20 text-red-300"
                    >
                      {{ $t('persons.merged') }}
                    </span>
                  </div>
                </td>
                <!-- Users Count -->
                <td class="py-3.5 px-4">
                  <span class="text-slate-300">{{ person.users_count }}</span>
                </td>
                <!-- Active User -->
                <td class="py-3.5 px-4">
                  <div v-if="person.active_user">
                    <p class="text-slate-300 text-xs">{{ person.active_user.email }}</p>
                    <span
                      class="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium"
                      :class="roleBadgeClass(person.active_user.role)"
                    >
                      {{ person.active_user.role }}
                    </span>
                  </div>
                  <span v-else class="text-slate-500">—</span>
                </td>
                <!-- Address -->
                <td class="py-3.5 px-4">
                  <span v-if="person.address" class="text-slate-300 text-xs">{{ person.address.full_address_text || (person.address.address_city + ', ' + person.address.address_street_name + ' ' + (person.address.address_house_number || '')) }}</span>
                  <span v-else class="text-slate-500">—</span>
                </td>
                <!-- Actions -->
                <td class="py-3.5 px-4">
                  <div class="flex items-center gap-2">
                    <NuxtLink
                      :to="'/persons/' + person.id"
                      class="px-3 py-1.5 text-xs font-medium bg-slate-600/20 text-slate-300 hover:bg-slate-600/30 rounded-lg transition"
                    >
                      {{ $t('persons.view') }}
                    </NuxtLink>
                  </div>
                </td>
              </tr>
            </tbody>
          </table>
        </div>

        <!-- Empty State -->
        <div
          v-if="persons.length === 0 && !loading"
          class="flex flex-col items-center justify-center py-16 text-center"
        >
          <svg class="w-12 h-12 text-slate-600 mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0z" />
          </svg>
          <p class="text-slate-400 text-sm">{{ $t('persons.no_results') }}</p>
        </div>
      </div>

      <!-- Pagination -->
      <div v-if="totalCount > limit" class="flex items-center justify-between mt-6">
        <p class="text-xs text-slate-500">
          {{ $t('persons.showing') }} {{ skip + 1 }}–{{ Math.min(skip + limit, totalCount) }} / {{ totalCount }}
        </p>
        <div class="flex items-center gap-2">
          <button
            @click="prevPage"
            :disabled="skip === 0"
            class="px-3 py-1.5 text-xs font-medium rounded-lg transition disabled:opacity-30 disabled:cursor-not-allowed"
            :class="skip > 0 ? 'bg-slate-700 text-slate-300 hover:bg-slate-600' : 'bg-slate-800 text-slate-600'"
          >
            {{ $t('persons.prev') }}
          </button>
          <button
            @click="nextPage"
            :disabled="skip + limit >= totalCount"
            class="px-3 py-1.5 text-xs font-medium rounded-lg transition disabled:opacity-30 disabled:cursor-not-allowed"
            :class="skip + limit < totalCount ? 'bg-slate-700 text-slate-300 hover:bg-slate-600' : 'bg-slate-800 text-slate-600'"
          >
            {{ $t('persons.next') }}
          </button>
        </div>
      </div>
    </template>

    <!-- Notification -->
    <div
      v-if="notification"
      class="fixed bottom-6 right-6 px-5 py-3 rounded-xl shadow-xl text-sm font-medium z-50"
      :class="notification.type === 'success'
        ? 'bg-emerald-600 text-white'
        : 'bg-red-600 text-white'"
    >
      {{ notification.message }}
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
import { useRouter } from 'vue-router'
import { useAuthStore } from '~/stores/auth'

const router = useRouter()
const auth = useAuthStore()

definePageMeta({
  middleware: 'auth',
})

// ── RBAC Permission Check ──────────────────────────────────────────

const canViewPersons = computed(() => {
  if (auth.isAdmin) return true
  return !!auth.user?.system_capabilities?.['persons:view']
})

const canEditPersons = computed(() => {
  if (auth.isAdmin) return true
  return !!auth.user?.system_capabilities?.['persons:edit']
})

const canMergePersons = computed(() => {
  if (auth.isAdmin) return true
  return !!auth.user?.system_capabilities?.['persons:merge']
})

// Redirect if no view permission
if (!canViewPersons.value && !auth.isAdmin) {
  router.push('/')
}

// ── Types ──────────────────────────────────────────────────────────

interface PersonListItemActiveUser {
  id: number
  email: string | null
  role: string | null
}

interface PersonAddress {
  address_zip: string | null
  address_city: string | null
  address_street_name: string | null
  address_street_type: string | null
  address_house_number: string | null
  address_stairwell: string | null
  address_floor: string | null
  address_door: string | null
  address_hrsz: string | null
  full_address_text: string | null
  latitude: number | null
  longitude: number | null
}

interface PersonListItem {
  id: number
  last_name: string
  first_name: string
  phone: string | null
  birth_date: string | null
  is_ghost: boolean
  is_active: boolean
  merged_into_id: number | null
  users_count: number
  active_user: PersonListItemActiveUser | null
  address: PersonAddress | null
}

interface PersonListResponse {
  total: number
  skip: number
  limit: number
  items: PersonListItem[]
}

// ── State ──────────────────────────────────────────────────────────

const loading = ref(true)
const error = ref<string | null>(null)
const persons = ref<PersonListItem[]>([])
const totalCount = ref(0)
const skip = ref(0)
const limit = ref(50)

const searchQuery = ref('')
const ghostFilter = ref('all')
const activeFilter = ref('all')
const hasUserFilter = ref('all')
const mergedFilter = ref('all')

// Notification
const notification = ref<{ type: 'success' | 'error'; message: string } | null>(null)

// ── Computed Stats ─────────────────────────────────────────────────

const activeCount = computed(() => persons.value.filter(p => p.is_active).length)
const ghostCount = computed(() => persons.value.filter(p => p.is_ghost).length)
const mergedCount = computed(() => persons.value.filter(p => p.merged_into_id).length)

// ── Debounced Search Timer ──────────────────────────────────────────

let searchDebounceTimer: ReturnType<typeof setTimeout> | null = null

function debouncedFetchPersons() {
  if (searchDebounceTimer) {
    clearTimeout(searchDebounceTimer)
  }
  searchDebounceTimer = setTimeout(() => {
    skip.value = 0
    fetchPersons()
  }, 400)
}

// ── Watchers ────────────────────────────────────────────────────────

watch(searchQuery, () => {
  debouncedFetchPersons()
})

watch([ghostFilter, activeFilter, hasUserFilter, mergedFilter], () => {
  skip.value = 0
  fetchPersons()
})

// ── Computed ───────────────────────────────────────────────────────

const isFilterActive = computed(() => {
  return searchQuery.value !== ''
    || ghostFilter.value !== 'all'
    || activeFilter.value !== 'all'
    || hasUserFilter.value !== 'all'
    || mergedFilter.value !== 'all'
})

// ── Auth Helper ────────────────────────────────────────────────────

function getAuthHeaders() {
  const tokenCookie = useCookie('access_token')
  const token = tokenCookie.value
  return token ? { Authorization: `Bearer ${token}` } : {}
}

// ── Data Fetching ──────────────────────────────────────────────────

async function fetchPersons() {
  loading.value = true
  error.value = null
  try {
    const params: Record<string, any> = { skip: skip.value, limit: limit.value }

    if (searchQuery.value) {
      params.search = searchQuery.value
    }
    if (ghostFilter.value !== 'all') {
      params.is_ghost = ghostFilter.value === 'yes'
    }
    if (activeFilter.value !== 'all') {
      params.is_active = activeFilter.value === 'active'
    }
    if (hasUserFilter.value !== 'all') {
      params.has_user = hasUserFilter.value === 'yes'
    }
    if (mergedFilter.value !== 'all') {
      params.is_merged = mergedFilter.value === 'yes'
    }

    const response = await $fetch<PersonListResponse>('/api/v1/admin/persons', {
      params,
      headers: getAuthHeaders(),
    })
    persons.value = response.items
    totalCount.value = response.total
  } catch (err: any) {
    console.error('[Persons] Failed to fetch persons:', err)
    error.value = err?.data?.detail || err?.message || 'Failed to load persons'
  } finally {
    loading.value = false
  }
}

// ── Pagination ─────────────────────────────────────────────────────

function nextPage() {
  if (skip.value + limit.value < totalCount.value) {
    skip.value += limit.value
    fetchPersons()
  }
}

function prevPage() {
  if (skip.value > 0) {
    skip.value = Math.max(0, skip.value - limit.value)
    fetchPersons()
  }
}

// ── Helpers ────────────────────────────────────────────────────────

function roleBadgeClass(role: string | null): string {
  const r = (role || '').toLowerCase()
  if (r === 'superadmin') return 'bg-purple-500/20 text-purple-300'
  if (r === 'admin') return 'bg-indigo-500/20 text-indigo-300'
  if (r === 'staff') return 'bg-cyan-500/20 text-cyan-300'
  return 'bg-slate-500/20 text-slate-300'
}

function formatDate(dateStr: string | null): string {
  if (!dateStr) return '—'
  try {
    const d = new Date(dateStr)
    return d.toLocaleDateString('hu-HU', {
      year: 'numeric',
      month: 'short',
      day: 'numeric',
    })
  } catch {
    return dateStr
  }
}

function showNotification(type: 'success' | 'error', message: string) {
  notification.value = { type, message }
  setTimeout(() => {
    notification.value = null
  }, 4000)
}

// ── Lifecycle ──────────────────────────────────────────────────────

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