<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 visualice los datos de las tablas disponibles en Metabase.
          </p>
        </div>
      </template>

      <!-- Database and Table Selection -->
      <div class="flex flex-col gap-4">
        <!-- Database Selector -->
        <UFieldGroup label="Base de datos">
          <USelectMenu
            v-model="selectedDatabase"
            :items="databaseOptions"
            placeholder="Seleccionar base de datos"
            :loading="loadingDatabases"
            :disabled="loadingDatabases"
          />
        </UFieldGroup>

        <!-- Table Selector -->
        <UFieldGroup label="Tabla" v-if="selectedDatabase">
          <USelectMenu
            v-model="selectedTable"
            :items="tableOptions"
            placeholder="Seleccionar tabla"
            :loading="loadingTables"
            :disabled="loadingTables || !selectedDatabase"
          />
        </UFieldGroup>

        <!-- Limit Selector -->
        <UFieldGroup label="Límite de registros" v-if="selectedTable">
          <USelectMenu
            v-model="selectedLimit"
            :items="limitOptions"
            placeholder="Seleccionar límite"
          />
        </UFieldGroup>

        <!-- Load Data Button -->
        <UButton
          v-if="selectedTable"
          :loading="loadingData"
          :disabled="!selectedTable"
          @click="loadTableData"
          color="primary"
          icon="i-lucide-refresh-cw"
        >
          Cargar datos
        </UButton>
      </div>
    </UCard>

    <!-- Loading State -->
    <UCard v-if="loadingData" 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-[var(--brand-primary-strong)] border-t-transparent align-middle" aria-hidden="true" />
        <span class="text-sm uppercase tracking-[0.3em]">Cargando datos...</span>
      </div>
    </UCard>

    <!-- Error State -->
    <UCard v-else-if="error" class="brand-card border border-transparent">
      <div 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">
          {{ error }}
        </div>
        <UButton
          class="mt-4"
          @click="loadTableData"
          color="primary"
        >
          Reintentar
        </UButton>
      </div>
    </UCard>

    <!-- Table Data Display -->
    <UCard v-else-if="tableData && tableData.length > 0" 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">
            {{ selectedTableName }}
          </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">
              {{ tableData.length }} registros cargados{{ hasMoreData ? ` (limitado a ${selectedLimit})` : '' }}
            </span>
          </div>
        </div>
      </template>

      <div class="flex-1 divide-y divide-accented w-full">
        <!-- Search Input -->
        <div class="flex items-center gap-2 px-4 py-3.5 overflow-x-auto">
          <UInput
            v-model="searchQuery"
            class="max-w-sm min-w-[12ch]"
            placeholder="Buscar en todos los campos..."
            icon="i-lucide-search"
          />

          <UButton
            v-if="tableColumns.length > 0"
            label="Columnas"
            color="neutral"
            variant="outline"
            trailing-icon="i-lucide-chevron-down"
            class="ml-auto"
            @click="showColumnSelector = !showColumnSelector"
          />
        </div>

        <!-- Column Selector -->
        <div v-if="showColumnSelector" class="px-4 py-3 bg-elevated border-b border-accented">
          <div class="grid grid-cols-2 md:grid-cols-4 gap-2">
            <label
              v-for="column in tableColumns"
              :key="column.id"
              class="flex items-center gap-2 text-sm cursor-pointer hover:text-[var(--brand-text)]"
            >
              <input
                type="checkbox"
                :checked="visibleColumns.includes(column.id)"
                @change="toggleColumn(column.id)"
                class="rounded"
              />
              <span>{{ column.header }}</span>
            </label>
          </div>
        </div>

        <!-- Table -->
        <UTable
          :data="paginatedData"
          :columns="displayColumns"
          :loading="loadingData"
        />

        <!-- Pagination -->
        <div class="flex items-center justify-between px-4 py-3.5">
          <div class="text-sm text-muted">
            Mostrando {{ startRow }} a {{ endRow }} de {{ filteredData.length }} filas{{ filteredData.length !== tableData.length ? ` (filtradas de ${tableData.length} totales)` : '' }}
          </div>
          <UPagination
            v-if="filteredData.length > rowsPerPage"
            v-model="page"
            :page-count="rowsPerPage"
            :total="filteredData.length"
            :max="5"
            size="xs"
          />
        </div>
      </div>
    </UCard>

    <!-- Empty State -->
    <UCard v-else-if="selectedTable" class="brand-card border border-transparent">
      <div 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 "Cargar datos" para obtener la información de esta tabla.
        </p>
      </div>
    </UCard>

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

<script setup lang="ts">
import { upperFirst } from 'scule'

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

// Get query params from URL
const route = useRoute()
const router = useRouter()

// State
const selectedDatabase = ref<any | null>(null)
const selectedTable = ref<any | null>(null)
const selectedLimit = ref(100)
const loadingDatabases = ref(false)
const loadingTables = ref(false)
const loadingData = ref(false)
const error = ref<string | null>(null)
const searchQuery = ref('')
const showColumnSelector = ref(false)
const page = ref(1)
const rowsPerPage = ref(50)

const databases = ref<any[]>([])
const tables = ref<any[]>([])
const tableData = ref<any[]>([])
const visibleColumns = ref<string[]>([])

// Track if we should auto-load data from URL params
const shouldAutoLoad = ref(false)

// Limit options
const limitOptions = [10, 50, 100, 500, 1000, 5000, 10000]

// Track if there might be more data
const hasMoreData = computed(() => tableData.value.length >= selectedLimit.value)

// Computed
const databaseOptions = computed(() => {
  return databases.value.map(db => db.name)
})

const tableOptions = computed(() => {
  return tables.value.map(table => table.display_name || table.name)
})

const selectedDatabaseId = computed(() => {
  if (!selectedDatabase.value) return null
  const db = databases.value.find(d => d.name === selectedDatabase.value)
  return db?.id
})

const selectedTableId = computed(() => {
  if (!selectedTable.value) return null
  const table = tables.value.find(t => (t.display_name || t.name) === selectedTable.value)
  return table?.id
})

const selectedTableName = computed(() => {
  return selectedTable.value || ''
})

const tableColumns = computed(() => {
  if (!tableData.value || tableData.value.length === 0) {
    console.log('📊 tableColumns: No data')
    return []
  }

  const firstRow = tableData.value[0]
  const cols = Object.keys(firstRow).map(key => ({
    accessorKey: key,
    header: upperFirst(key),
    id: key
  }))
  console.log('📊 tableColumns computed:', cols.length, 'columns')
  return cols
})

const displayColumns = computed(() => {
  const filtered = tableColumns.value
    .filter(col => visibleColumns.value.includes(col.id))
    .map(col => ({
      accessorKey: col.accessorKey,
      header: col.header,
      id: col.id
    }))
  console.log('📊 displayColumns computed:', filtered.length, 'visible columns')
  return filtered
})

const filteredData = computed(() => {
  if (!searchQuery.value) return tableData.value

  const query = searchQuery.value.toLowerCase()
  return tableData.value.filter(row => {
    return Object.values(row).some(value => {
      if (value === null || value === undefined) return false
      return String(value).toLowerCase().includes(query)
    })
  })
})

// Paginated data
const paginatedData = computed(() => {
  const start = (page.value - 1) * rowsPerPage.value
  const end = start + rowsPerPage.value
  const paginated = filteredData.value.slice(start, end)
  console.log('📊 paginatedData computed:', paginated.length, 'rows for page', page.value)
  return paginated
})

// Pagination helpers
const startRow = computed(() => {
  if (filteredData.value.length === 0) return 0
  return (page.value - 1) * rowsPerPage.value + 1
})

const endRow = computed(() => {
  const end = page.value * rowsPerPage.value
  return Math.min(end, filteredData.value.length)
})

// Methods
async function loadDatabases() {
  loadingDatabases.value = true
  error.value = null

  try {
    const response = await $fetch('/api/metabase/databases')
    databases.value = response as any[]

    // Check if we have a database from URL params
    const dbParam = route.query.db as string

    if (dbParam && databases.value.length > 0) {
      // Try to find database by name
      const db = databases.value.find(d => d.name === dbParam)
      if (db) {
        selectedDatabase.value = db.name
        shouldAutoLoad.value = true
      } else {
        // If not found, auto-select first database
        selectedDatabase.value = databases.value[0].name
      }
    } else if (databases.value.length > 0) {
      // Auto-select first database if no param
      selectedDatabase.value = databases.value[0].name
    }
  } catch (err: any) {
    error.value = `Error al cargar bases de datos: ${err.message || 'Error desconocido'}`
    console.error('Error loading databases:', err)
  } finally {
    loadingDatabases.value = false
  }
}

async function loadTables() {
  if (!selectedDatabase.value || !selectedDatabaseId.value) return

  loadingTables.value = true
  error.value = null
  selectedTable.value = null
  tableData.value = []

  try {
    const response = await $fetch(`/api/metabase/tables/${selectedDatabaseId.value}`)
    const metadata = response as any

    // Metabase returns tables in the 'tables' property
    tables.value = metadata.tables || []

    // Check if we have a table from URL params
    const tableParam = route.query.table as string

    if (tableParam && tables.value.length > 0 && shouldAutoLoad.value) {
      // Try to find table by name or display_name
      const table = tables.value.find(t =>
        (t.display_name || t.name) === tableParam ||
        t.name === tableParam
      )

      if (table) {
        selectedTable.value = table.display_name || table.name
        // Load data automatically after table is selected
        await nextTick()
        await loadTableData()
      }

      // Reset auto-load flag
      shouldAutoLoad.value = false
    }
  } catch (err: any) {
    error.value = `Error al cargar tablas: ${err.message || 'Error desconocido'}`
    console.error('Error loading tables:', err)
  } finally {
    loadingTables.value = false
  }
}

async function loadTableData() {
  if (!selectedDatabaseId.value || !selectedTableId.value) return

  loadingData.value = true
  error.value = null

  try {
    const response = await $fetch('/api/metabase/query', {
      method: 'POST',
      body: {
        databaseId: selectedDatabaseId.value,
        tableId: selectedTableId.value,
        query: {
          limit: selectedLimit.value
        }
      }
    })

    // Metabase returns data in a specific format
    const result = response as any

    if (result.data && result.data.rows && result.data.cols) {
      // Transform Metabase response to array of objects
      const columns = result.data.cols.map((col: any) => col.name)
      console.log('📊 Columns extracted:', columns)

      tableData.value = result.data.rows.map((row: any[]) => {
        const obj: any = {}
        columns.forEach((col: string, index: number) => {
          obj[col] = row[index]
        })
        return obj
      })

      console.log('📊 Table data transformed:', tableData.value.length, 'rows')
      console.log('📊 First row:', tableData.value[0])

      // Initialize visible columns
      visibleColumns.value = columns
      console.log('📊 Visible columns set:', visibleColumns.value)
    } else {
      console.log('❌ No data structure found:', result)
      tableData.value = []
    }
  } catch (err: any) {
    error.value = `Error al cargar datos: ${err.message || 'Error desconocido'}`
    console.error('Error loading table data:', err)
  } finally {
    loadingData.value = false
  }
}

function toggleColumn(columnKey: string) {
  const index = visibleColumns.value.indexOf(columnKey)
  if (index > -1) {
    visibleColumns.value.splice(index, 1)
  } else {
    visibleColumns.value.push(columnKey)
  }
}

// Watchers
watch(selectedDatabase, (newDb) => {
  loadTables()

  // Update URL query params when database changes
  if (newDb && !shouldAutoLoad.value) {
    router.push({
      query: {
        ...route.query,
        db: newDb,
        table: undefined // Clear table when db changes
      }
    })
  }
})

watch(selectedTable, (newTable) => {
  // Update URL query params when table changes
  if (newTable && !shouldAutoLoad.value) {
    router.push({
      query: {
        ...route.query,
        table: newTable
      }
    })
  }
})

// Reset page when search changes
watch(searchQuery, () => {
  page.value = 1
})

// Reset page when data loads
watch(tableData, () => {
  page.value = 1
})

// Lifecycle
onMounted(() => {
  loadDatabases()
})
</script>
