<template>
  <div class="flex flex-col gap-6">
    <UCard class="brand-card border border-transparent backdrop-blur-sm">
      <template #header>
        <div class="flex flex-col gap-2">
          <h2 class="text-xl font-semibold text-[var(--brand-text)]">Explorador de Datos</h2>
          <p class="text-sm text-[var(--brand-text-muted)]">
            Explore y analice los datos de las tablas disponibles con funciones avanzadas de filtrado y ordenamiento.
          </p>
        </div>
      </template>

      <!-- Table Selection and Refresh Controls -->
      <div class="flex flex-col gap-4">
        <!-- Table Selector -->
        <UFieldGroup>
          <UButton
            :label="selectedTable ? selectedTable.label : 'Seleccionar tabla'"
            :icon="selectedTable ? 'i-lucide-table' : 'i-lucide-loader-circle'"
            color="neutral"
            variant="subtle"
            :loading="metadataStore.loading && !metadataStore.hasMetadata"
          />

          <UDropdownMenu :items="tableDropdownItems" :loading="metadataStore.loading && !metadataStore.hasMetadata">
            <UButton
              color="neutral"
              variant="outline"
              icon="i-lucide-chevron-down"
              :disabled="metadataStore.loading && !metadataStore.hasMetadata"
            />
          </UDropdownMenu>
        </UFieldGroup>

        <!-- Metadata Card for selected table -->
        <MetadatosCard
          v-if="selectedTable"
          :metadata="selectedTable"
        />
      </div>
    </UCard>

    <!-- Loading State -->
    <UCard v-if="metadataStore.loading && !metadataStore.hasMetadata" class="brand-card border border-transparent">
      <div class="flex items-center justify-center gap-3 py-10 text-[var(--brand-text-muted)]">
        <span class="inline-flex h-8 w-8 animate-spin rounded-full border-2 border-[#c08040] border-t-transparent align-middle" aria-hidden="true" />
        <span class="text-sm uppercase tracking-[0.3em]">Cargando metadatos...</span>
      </div>
      <p class="text-center text-sm text-[var(--brand-text-muted)] mt-2">
        Por favor espera mientras se cargan los metadatos de las tablas disponibles.
      </p>
    </UCard>

    <!-- Table Content -->
    <UCard v-else-if="selectedTable && currentTableStore" class="brand-card border border-transparent">
      <template #header>
        <div class="flex flex-wrap items-center justify-between gap-3">
          <h2 class="text-lg font-semibold brand-section-title">
            Tabla: {{ selectedTable.name }}
          </h2>
          <div class="flex flex-wrap gap-2 text-xs text-[var(--brand-text-muted)]">
            <span class="brand-pill inline-flex items-center gap-2 rounded-full px-3 py-1 text-xs">
              {{ currentTableStore.recordCount }} registros cargados
            </span>
            <span v-if="selectedTable.rowCount" class="brand-pill inline-flex items-center gap-2 rounded-full px-3 py-1 text-xs">
              {{ formatNumber(selectedTable.rowCount) }} total en BD
            </span>
          </div>
        </div>
      </template>

      <!-- Loading State for Table Data -->
      <div v-if="currentTableStore.isLoading && !currentTableStore.hasData" class="flex items-center justify-center gap-3 py-10 text-[var(--brand-text-muted)]">
        <span class="inline-flex h-8 w-8 animate-spin rounded-full border-2 border-[#c08040] border-t-transparent align-middle" aria-hidden="true" />
        <span class="text-sm uppercase tracking-[0.3em]">Cargando datos...</span>
      </div>

      <!-- Error State -->
      <div v-else-if="currentTableStore.hasError" class="py-10 text-center">
        <div class="rounded-lg border border-red-500/40 bg-red-500/18 p-4 text-sm text-red-200 max-w-md mx-auto">
          {{ currentTableStore.error }}
        </div>
        <UButton
          class="mt-4"
          :ui="{ base: 'bg-[#c08040] text-[#1b1209] border border-[#d99a56] hover:bg-[#d99a56] hover:border-[#f0c07c]' }"
          @click="refreshTableData"
        >
          Reintentar
        </UButton>
      </div>

      <!-- NuxtUI Table -->
      <div v-else-if="currentTableStore.hasData" class="flex-1 divide-y divide-accented w-full">
        <!-- Table Controls -->
        <div class="flex items-center gap-2 px-4 py-3.5 overflow-x-auto">
          <UInput
            :model-value="globalFilter"
            class="max-w-sm min-w-[12ch]"
            placeholder="Buscar en todos los campos..."
            icon="i-lucide-search"
            @update:model-value="updateGlobalFilter"
          />

          <UDropdownMenu
            v-if="table?.tableApi"
            :items="columnVisibilityItems"
            :content="{ align: 'end' }"
          >
            <UButton
              label="Columnas"
              color="neutral"
              variant="outline"
              trailing-icon="i-lucide-chevron-down"
              class="ml-auto"
              aria-label="Selector de columnas visibles"
            />
          </UDropdownMenu>
        </div>

        <!-- Table Component -->
        <UTable
          ref="table"
          :data="currentTableStore.allRecords"
          :columns="tableColumns"
          :global-filter="globalFilter"
          sticky
          class="h-96"
        />

        <!-- Table Footer with Meta Information -->
        <div class="px-4 py-3.5 text-sm text-muted">
          {{ filteredRowCount }} de {{ totalRowCount }} filas mostradas.
          <span v-if="selectedTable.primaryKey" class="ml-2">
            Clave primaria: <code class="text-xs bg-elevated px-1 py-0.5 rounded">{{ selectedTable.primaryKey }}</code>
          </span>
        </div>
      </div>

      <!-- Empty State -->
      <div v-else class="py-10 text-center text-sm text-[var(--brand-text-muted)]">
        <UIcon name="i-lucide-inbox" class="mx-auto mb-4 size-12 text-[var(--brand-text-muted)]" />
        <h3 class="text-lg font-semibold text-[var(--brand-text)] mb-2">No hay datos disponibles</h3>
        <p class="text-sm text-[var(--brand-text-muted)] mb-4">
          Haz clic en "Actualizar datos" para cargar la información de esta tabla.
        </p>
        <UButton
          :loading="currentTableStore.isLoading"
          :ui="{ base: 'bg-[#c08040] text-[#1b1209] border border-[#d99a56] hover:bg-[#d99a56] hover:border-[#f0c07c]' }"
          @click="refreshTableData"
        >
          <template #leading>
            <UIcon name="i-lucide-refresh-cw" />
          </template>
          Cargar datos
        </UButton>
      </div>
    </UCard>

    <!-- No Table Selected -->
    <UCard v-else class="brand-card border border-transparent">
      <div class="py-10 text-center text-sm text-[var(--brand-text-muted)]">
        Selecciona una tabla para explorar sus datos.
      </div>
    </UCard>
  </div>
</template>

<script setup lang="ts">
import { h, resolveComponent } from 'vue'
import { upperFirst } from 'scule'
import type { TableColumn, DropdownMenuItem } from '@nuxt/ui'
import { useMetadataStore } from '~/stores/metadata'
import { useTableDataStore } from '~/stores/tableDataFactory'

definePageMeta({
  layout: 'dashboard',
  title: 'Explorador de datos'
})

const UButton = resolveComponent('UButton')

// State
const selectedTableName = ref<string>('')
const globalFilter = ref('')
const currentTableStore = ref<ReturnType<typeof useTableDataStore> | null>(null)

const table = useTemplateRef('table')
const metadataStore = useMetadataStore()
const { $getTableStore } = useNuxtApp()

// Computed properties
const selectedTable = computed(() => {
  if (!selectedTableName.value || !metadataStore.hasMetadata) return null

  const metadata = metadataStore.getTableMetadata(selectedTableName.value)
  if (!metadata) return null

  return {
    ...metadata,
    label: `${metadata.table} (${metadata.rowCount || 0} registros)`
  }
})

const tableDropdownItems = computed((): DropdownMenuItem[] => {
  if (metadataStore.loading && !metadataStore.hasMetadata) {
    return [{
      type: 'label',
      label: 'Cargando...'
    }]
  }

  if (!metadataStore.hasMetadata) {
    return [{
      type: 'label',
      label: 'No hay tablas disponibles'
    }]
  }

  return metadataStore.allTables.map(metadata => ({
    label: `${metadata.table} (${metadata.rowCount || 0})`,
    icon: 'i-lucide-table',
    onSelect: () => selectTable(metadata.name)
  }))
})

const tableColumns = computed((): TableColumn<Record<string, unknown>>[] => {
  if (!currentTableStore.value?.hasData) return []

  const firstRow = currentTableStore.value.allRecords[0]
  if (!firstRow) return []

  const columns = Object.keys(firstRow)

  return columns.map(column => ({
    accessorKey: column,
    header: ({ column: tableColumn }) => {
      const isSorted = tableColumn.getIsSorted()

      return h(UButton, {
        color: 'neutral',
        variant: 'ghost',
        label: upperFirst(column),
        icon: isSorted ? (isSorted === 'asc' ? 'i-lucide-arrow-up-narrow-wide' : 'i-lucide-arrow-down-wide-narrow') : 'i-lucide-arrow-up-down',
        class: '-mx-2.5',
        onClick: () => tableColumn.toggleSorting(tableColumn.getIsSorted() === 'asc')
      })
    },
    cell: ({ row }) => formatCellValue(row.getValue(column))
  }))
})

const columnVisibilityItems = computed(() => {
  if (!table.value?.tableApi) return []

  return table.value.tableApi
    .getAllColumns()
    .filter(column => column.getCanHide())
    .map(column => ({
      label: upperFirst(column.id),
      type: 'checkbox' as const,
      checked: column.getIsVisible(),
      onUpdateChecked(checked: boolean) {
        table.value?.tableApi?.getColumn(column.id)?.toggleVisibility(!!checked)
      },
      onSelect(e?: Event) {
        e?.preventDefault()
      }
    }))
})

const filteredRowCount = computed(() => {
  return table.value?.tableApi?.getFilteredRowModel().rows.length || 0
})

const totalRowCount = computed(() => {
  return currentTableStore.value?.recordCount || 0
})

// Methods
async function selectTable(tableName: string) {
  console.log(`[Explorer] selectTable called with: ${tableName}`)
  if (selectedTableName.value === tableName) {
    console.log(`[Explorer] Table ${tableName} already selected, skipping`)
    return
  }

  selectedTableName.value = tableName

  // Get the table store using the plugin
  if (typeof $getTableStore === 'function') {
    const store = $getTableStore(tableName)
    if (store) {
      console.log(`[Explorer] Got store for ${tableName} via plugin`)
      currentTableStore.value = store

      // Load from cache first (async from IndexedDB)
      await store.loadFromCache()
      console.log(`[Explorer] After loadFromCache, store has ${store.recordCount} records`)

      // Note: We don't call initialize() here because MetadatosCard will handle loading
      // initialize() would trigger a fetch, but we want manual control via the buttons
    }
  } else {
    // Fallback: create store directly
    console.log(`[Explorer] Creating store for ${tableName} directly (fallback)`)
    currentTableStore.value = useTableDataStore(tableName)
    await currentTableStore.value.loadFromCache()
    console.log(`[Explorer] After loadFromCache, store has ${currentTableStore.value.recordCount} records`)
  }
}

async function refreshTableData() {
  console.log('[Explorer] refreshTableData called')
  if (currentTableStore.value) {
    console.log(`[Explorer] Refreshing data for current table (${selectedTableName.value})`)
    await currentTableStore.value.refreshData()
    console.log(`[Explorer] After refresh, store has ${currentTableStore.value.recordCount} records`)
  }
}

function updateGlobalFilter(value: string) {
  globalFilter.value = value
}

function formatNumber(value: number): string {
  return new Intl.NumberFormat('es-ES').format(value)
}

function formatCellValue(value: unknown): string {
  if (value === null || value === undefined) {
    return '—'
  }

  if (value instanceof Date) {
    return value.toISOString()
  }

  if (typeof value === 'object') {
    try {
      return JSON.stringify(value)
    } catch {
      return '[objeto]'
    }
  }

  const stringValue = String(value)

  // Truncate long strings
  if (stringValue.length > 100) {
    return stringValue.substring(0, 100) + '...'
  }

  return stringValue
}

// Lifecycle
onMounted(async () => {
  console.log('[Explorer] onMounted: Initializing metadata store')
  await metadataStore.initialize()

  // Auto-select first table if available
  if (metadataStore.hasMetadata && !selectedTableName.value) {
    const firstTable = metadataStore.allTables[0]
    if (firstTable) {
      console.log(`[Explorer] Auto-selecting first table: ${firstTable.name}`)
      selectTable(firstTable.name) // Use name instead of table
    }
  }
})

// Auto-select first table when metadata becomes available
watch(() => metadataStore.hasMetadata, (hasMetadata) => {
  if (hasMetadata && !selectedTableName.value && metadataStore.allTables.length > 0) {
    console.log('[Explorer] Metadata became available, auto-selecting first table')
    selectTable(metadataStore.allTables[0].name) // Use name instead of table
  }
})
</script>