<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue'
import { useUiStore } from '../../stores/ui'
import { configApi } from '../../services/configApi'
import ConfirmModal from '../ui/ConfirmModal.vue'

const props = defineProps<{
  connectionId: string
  connectionName: string
}>()

const emit = defineEmits<{
  close: []
  registered: []
}>()

const ui = useUiStore()

interface RemoteTable {
  schema: string
  table: string
  row_count: number | null
  already_registered: boolean
  is_synced: boolean
}

const loading = ref(false)
const registering = ref(false)
const tables = ref<RemoteTable[]>([])
const schemas = ref<string[]>([])
const totalFound = ref(0)
const truncated = ref(false)

const schemaFilter = ref('')
const tableSearch = ref('')
const selected = ref<Set<string>>(new Set())

// Debounce for search
let searchTimeout: ReturnType<typeof setTimeout> | null = null

// Confirmation modal
const confirmAction = ref<{
  title: string
  message: string
  detail?: string
  variant: 'warning' | 'danger' | 'info'
  onConfirm: () => void
} | null>(null)

function showConfirm(opts: typeof confirmAction.value) {
  confirmAction.value = opts
}

function onConfirmApproved() {
  const action = confirmAction.value
  confirmAction.value = null
  if (action?.onConfirm) action.onConfirm()
}

function tableKey(t: RemoteTable) {
  return `${t.schema}||${t.table}`
}

const selectableTables = computed(() =>
  tables.value.filter(t => !t.already_registered)
)

const selectedCount = computed(() => selected.value.size)

const allSelectableSelected = computed(() =>
  selectableTables.value.length > 0 && selectableTables.value.every(t => selected.value.has(tableKey(t)))
)

function toggleSelectAll() {
  if (allSelectableSelected.value) {
    selected.value.clear()
  } else {
    const newSet = new Set<string>()
    for (const t of selectableTables.value) {
      newSet.add(tableKey(t))
    }
    selected.value = newSet
  }
}

function toggleSelect(t: RemoteTable) {
  const key = tableKey(t)
  const newSet = new Set(selected.value)
  if (newSet.has(key)) {
    newSet.delete(key)
  } else {
    newSet.add(key)
  }
  selected.value = newSet
}

function requestBrowse() {
  showConfirm({
    title: 'Browse Remote Database Tables',
    message: `This will query INFORMATION_SCHEMA on "${props.connectionName}" to list available tables.`,
    detail: 'Read-only query: SELECT from INFORMATION_SCHEMA.TABLES\nNo data will be read — only table names and row counts.',
    variant: 'warning',
    onConfirm: () => doBrowse(),
  })
}

async function doBrowse() {
  loading.value = true
  try {
    const { data } = await configApi.browseRemoteTables(props.connectionId, {
      schema: schemaFilter.value || undefined,
      table: tableSearch.value || undefined,
      limit: 500,
    })
    tables.value = data.tables
    schemas.value = data.schemas
    totalFound.value = data.total_found
    truncated.value = data.truncated
    selected.value = new Set()
  } catch (e: any) {
    ui.showToast(e.response?.data?.detail || 'Browse failed', 'error')
  } finally {
    loading.value = false
  }
}

function onSearchInput() {
  if (searchTimeout) clearTimeout(searchTimeout)
  searchTimeout = setTimeout(() => {
    if (tables.value.length > 0 || schemaFilter.value || tableSearch.value) {
      requestFilteredBrowse()
    }
  }, 300)
}

function requestFilteredBrowse() {
  // Subsequent searches after initial confirm don't need re-confirmation
  doBrowse()
}

function requestRegister() {
  const selections: { schema: string; table: string }[] = Array.from(selected.value).map(key => {
    const parts = key.split('||')
    return { schema: parts[0]!, table: parts[1]! }
  })
  showConfirm({
    title: 'Register Selected Tables',
    message: `Register ${selections.length} table(s) from "${props.connectionName}"?`,
    detail: `This will:\n- Query INFORMATION_SCHEMA.COLUMNS for each selected table\n- Save table/column metadata to internal config\n\nNo data will be copied. Use "Sync" in the Tables tab to copy data later.\n\nTables:\n${selections.map(s => `  ${s.schema}.${s.table}`).join('\n')}`,
    variant: 'warning',
    onConfirm: () => doRegister(selections),
  })
}

async function doRegister(selections: { schema: string; table: string }[]) {
  registering.value = true
  try {
    const { data } = await configApi.registerSelectedTables(props.connectionId, selections)
    ui.showToast(
      `Registered ${data.tables_registered} tables, ${data.columns_registered} columns` +
      (data.errors?.length ? ` (${data.errors.length} errors)` : ''),
      data.errors?.length ? 'error' : 'success',
    )
    emit('registered')
  } catch (e: any) {
    ui.showToast(e.response?.data?.detail || 'Registration failed', 'error')
  } finally {
    registering.value = false
  }
}

function formatRowCount(n: number | null) {
  if (n == null) return '—'
  return n.toLocaleString()
}

onMounted(() => {
  requestBrowse()
})

watch(schemaFilter, () => onSearchInput())
</script>

<template>
  <div class="card mt-4 border-primary-500/30">
    <div class="flex items-center justify-between mb-3">
      <h3 class="font-medium text-sm">Browse Tables: {{ connectionName }}</h3>
      <button @click="emit('close')" class="text-dark-400 hover:text-dark-200 text-sm">Close</button>
    </div>

    <!-- Filters -->
    <div class="flex gap-3 mb-3">
      <select v-model="schemaFilter" class="input-field w-48 text-sm">
        <option value="">All schemas</option>
        <option v-for="s in schemas" :key="s" :value="s">{{ s }}</option>
      </select>
      <input
        v-model="tableSearch"
        @input="onSearchInput"
        placeholder="Search table name..."
        class="input-field flex-1 text-sm"
      />
      <button
        v-if="selectableTables.length > 0"
        @click="toggleSelectAll"
        class="btn-secondary text-xs whitespace-nowrap"
      >
        {{ allSelectableSelected ? 'Deselect All' : 'Select All' }}
      </button>
    </div>

    <!-- Loading -->
    <div v-if="loading" class="text-center py-8 text-dark-400 text-sm">Loading tables...</div>

    <!-- Table list -->
    <div v-else-if="tables.length > 0" class="border border-dark-600 rounded overflow-hidden">
      <div class="max-h-80 overflow-y-auto">
        <table class="w-full text-sm">
          <thead class="bg-dark-800 sticky top-0">
            <tr>
              <th class="w-10 px-3 py-2 text-left"></th>
              <th class="px-3 py-2 text-left text-dark-400 font-medium">Schema</th>
              <th class="px-3 py-2 text-left text-dark-400 font-medium">Table</th>
              <th class="px-3 py-2 text-right text-dark-400 font-medium">Rows</th>
              <th class="px-3 py-2 text-left text-dark-400 font-medium">Status</th>
            </tr>
          </thead>
          <tbody>
            <tr
              v-for="t in tables"
              :key="tableKey(t)"
              :class="[
                'border-t border-dark-700 transition-colors',
                t.already_registered ? 'opacity-60' : 'hover:bg-dark-750 cursor-pointer'
              ]"
              @click="!t.already_registered && toggleSelect(t)"
            >
              <td class="px-3 py-1.5">
                <input
                  v-if="!t.already_registered"
                  type="checkbox"
                  :checked="selected.has(tableKey(t))"
                  @click.stop="toggleSelect(t)"
                  class="accent-primary-500"
                />
              </td>
              <td class="px-3 py-1.5 text-dark-400 font-mono text-xs">{{ t.schema }}</td>
              <td class="px-3 py-1.5 font-medium">{{ t.table }}</td>
              <td class="px-3 py-1.5 text-right text-dark-400 tabular-nums">{{ formatRowCount(t.row_count) }}</td>
              <td class="px-3 py-1.5">
                <span v-if="t.is_synced" class="text-green-400 text-xs">Synced</span>
                <span v-else-if="t.already_registered" class="text-dark-400 text-xs">Registered</span>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>

    <!-- Empty state -->
    <div v-else class="text-center py-8 text-dark-500 text-sm">
      No tables found. Try adjusting filters.
    </div>

    <!-- Footer -->
    <div class="flex items-center justify-between mt-3">
      <div class="text-xs text-dark-500">
        <span v-if="truncated" class="text-yellow-500">
          Showing {{ tables.length }} of {{ totalFound.toLocaleString() }} tables. Use filters to narrow results.
        </span>
        <span v-else-if="tables.length > 0">
          {{ totalFound.toLocaleString() }} table(s)
        </span>
      </div>
      <div class="flex items-center gap-3">
        <span v-if="selectedCount > 0" class="text-xs text-dark-300">{{ selectedCount }} selected</span>
        <button
          @click="requestRegister"
          :disabled="selectedCount === 0 || registering"
          class="btn-primary text-sm"
        >
          {{ registering ? 'Registering...' : 'Register Selected' }}
        </button>
        <button @click="emit('close')" class="btn-secondary text-sm">Cancel</button>
      </div>
    </div>

    <!-- Confirmation modal -->
    <ConfirmModal
      v-if="confirmAction"
      :title="confirmAction.title"
      :message="confirmAction.message"
      :detail="confirmAction.detail"
      :variant="confirmAction.variant"
      @confirm="onConfirmApproved"
      @cancel="confirmAction = null"
    />
  </div>
</template>
