<template>
  <div class="bitable-file-detail-view">
    <!-- Top bar -->
    <div class="bitable-file-detail-view__topbar">
      <div class="bitable-file-detail-view__topbar-left">
        <a-button type="text" :icon="h(ArrowLeftOutlined)" @click="goBack" />
        <span class="bitable-file-detail-view__icon">{{ store.currentFile?.icon ?? '📋' }}</span>
        <span class="bitable-file-detail-view__title">
          {{ store.currentFile?.name ?? '加载中…' }}
        </span>
      </div>
      <div class="bitable-file-detail-view__topbar-right">
        <a-tag v-if="store.recalcPendingCount > 0" color="processing">
          <LoadingOutlined /> 计算中 ({{ store.recalcPendingCount }})
        </a-tag>
        <a-button
          v-if="store.currentTable"
          size="small"
          :icon="h(SettingOutlined)"
          @click="fieldPanelOpen = true"
        >
          字段管理
        </a-button>
        <a-button size="small" :icon="h(ReloadOutlined)" @click="handleRefresh">
          刷新
        </a-button>
      </div>
    </div>

    <!-- Body: left sidebar + right grid -->
    <div class="bitable-file-detail-view__body">
      <aside class="bitable-file-detail-view__sidebar">
        <TableViewList
          :tables="store.tables"
          :active-id="store.currentTable?.id ?? null"
          :file-id="fileId"
          :loading="store.isLoading"
          @select="handleSelectTable"
          @create="handleCreateTable"
        />
      </aside>

      <main class="bitable-file-detail-view__main">
        <div v-if="!store.currentTable" class="bitable-file-detail-view__placeholder">
          <TableOutlined style="font-size: 48px; color: var(--text-placeholder)" />
          <p>请选择左侧的数据表，或点击 + 新建数据表</p>
        </div>

        <template v-else>
          <div class="bitable-file-detail-view__grid-header">
            <h3 class="bitable-file-detail-view__table-name">
              {{ store.currentTable.name }}
            </h3>
            <span class="bitable-file-detail-view__field-count">
              {{ store.fields.length }} 个字段 · {{ store.records.length }} 条记录
            </span>
          </div>

          <!-- View switcher -->
          <ViewSwitcher
            :views="store.views"
            :active-view-id="store.currentView?.id ?? null"
            @switch="handleSwitchView"
            @create="handleCreateView"
            @config="viewConfigOpen = true"
          />

          <div class="bitable-file-detail-view__grid-container">
            <BitableGrid
              :fields="visibleFields"
              :records="store.records"
              :loading="store.isLoading"
              height="100%"
              @edit-cell="handleEditCell"
              @add-field="handleAddFieldFromGrid"
              @config-field="handleConfigField"
              @hide-field="handleHideField"
              @delete-field="handleDeleteField"
            />
          </div>

          <!-- Load more (cursor pagination) -->
          <div v-if="store.nextCursor" class="bitable-file-detail-view__load-more">
            <a-button @click="store.loadMoreRecords()">加载更多</a-button>
          </div>
        </template>
      </main>
    </div>

    <!-- Table create modal -->
    <TableCreateModal
      :open="createModalOpen"
      :file-id="fileId"
      @success="handleTableCreated"
      @cancel="createModalOpen = false"
    />

    <!-- Field management panel -->
    <FieldManagePanel
      :open="fieldPanelOpen"
      :fields="store.fields"
      @close="fieldPanelOpen = false"
    />

    <!-- View config panel -->
    <ViewConfigPanel
      :open="viewConfigOpen"
      :fields="store.fields"
      :view="store.currentView"
      @close="viewConfigOpen = false"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, computed, h, onMounted, onUnmounted, watch } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { Modal as AModal } from 'ant-design-vue'
import {
  ArrowLeftOutlined,
  ReloadOutlined,
  LoadingOutlined,
  TableOutlined,
  SettingOutlined,
} from '@ant-design/icons-vue'
import { useBitableStore } from '@/stores/bitable'
import type { IBitableField } from '@/api/bitable'
import TableViewList from '@/components/bitable/TableViewList.vue'
import BitableGrid from '@/components/bitable/BitableGrid.vue'
import TableCreateModal from '@/components/bitable/TableCreateModal.vue'
import FieldManagePanel from '@/components/bitable/FieldManagePanel.vue'
import ViewSwitcher from '@/components/bitable/ViewSwitcher.vue'
import ViewConfigPanel from '@/components/bitable/ViewConfigPanel.vue'

const router = useRouter()
const route = useRoute()
const store = useBitableStore()

const createModalOpen = ref(false)
const fieldPanelOpen = ref(false)
const viewConfigOpen = ref(false)

const fileId = computed(() => (route.params.fileId as string) ?? '')
const tableId = computed(() => (route.params.tableId as string) ?? '')

// Filter out hidden fields based on current view config
const visibleFields = computed(() => {
  const hiddenIds = (store.currentView?.config?.hidden_fields as string[]) ?? []
  if (hiddenIds.length === 0) return store.fields
  return store.fields.filter((f) => !hiddenIds.includes(f.id))
})

onMounted(async () => {
  if (!fileId.value) return
  await store.selectFile(fileId.value)
  if (tableId.value) {
    await store.selectTable(tableId.value)
  }
})

onUnmounted(() => {
  store.stopPolling()
})

// React to fileId changes (navigating between files reuses this component instance)
watch(
  () => fileId.value,
  async (newId, oldId) => {
    if (newId && newId !== oldId) {
      store.stopPolling()
      await store.selectFile(newId)
      if (tableId.value) {
        await store.selectTable(tableId.value)
      }
    }
  },
)

// React to route param changes (e.g., clicking a table in sidebar updates URL)
watch(
  () => tableId.value,
  async (newId) => {
    if (newId && newId !== store.currentTable?.id) {
      await store.selectTable(newId)
    }
  },
)

function goBack(): void {
  router.push('/bitable')
}

function handleSelectTable(tableId: string): void {
  router.push(`/bitable/${fileId.value}/${tableId}`)
}

function handleCreateTable(_: string | null): void {
  createModalOpen.value = true
}

async function handleTableCreated(tableId: string): Promise<void> {
  createModalOpen.value = false
  await store.loadTablesByFile(fileId.value)
  await store.selectTable(tableId)
  router.push(`/bitable/${fileId.value}/${tableId}`)
}

function handleRefresh(): void {
  store.refreshRecords()
}

async function handleEditCell(payload: {
  recordId: string
  fieldId: string
  value: unknown
}): Promise<void> {
  await store.updateCell(payload.recordId, payload.fieldId, payload.value)
}

function handleSwitchView(viewId: string): void {
  store.switchView(viewId)
}

async function handleCreateView(): Promise<void> {
  // ponytail: simple prompt for view name; full create modal is overkill for v1
  let name = ''
  AModal.confirm({
    title: '新建视图',
    content: h('input', {
      class: 'ant-input',
      placeholder: '请输入视图名称',
      onInput: (e: Event) => {
        name = (e.target as HTMLInputElement).value
      },
    }),
    onOk: async () => {
      if (!name.trim()) return
      await store.createView(name.trim(), 'grid')
    },
  })
}

// U4: column header menu handlers (events from BitableGrid)
function handleAddFieldFromGrid(): void {
  // Open the field manage panel which has the add-field form
  fieldPanelOpen.value = true
}

function handleConfigField(_field: IBitableField): void {
  // ponytail: open field manage panel; future: open inline config drawer
  fieldPanelOpen.value = true
}

async function handleHideField(fieldId: string): Promise<void> {
  await store.hideField(fieldId)
}

async function handleDeleteField(field: IBitableField): Promise<void> {
  AModal.confirm({
    title: '删除字段',
    content: `确定删除字段「${field.name}」吗？该字段下的所有数据将被清除。`,
    okText: '删除',
    okType: 'danger',
    cancelText: '取消',
    onOk: async () => {
      await store.deleteField(field.id, false)
    },
  })
}
</script>

<style scoped>
.bitable-file-detail-view {
  display: flex;
  flex-direction: column;
  height: 100vh;
  width: 100vw;
  overflow: hidden;
  background: var(--bg-primary, #fff);
}

.bitable-file-detail-view__topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 16px;
  border-bottom: 1px solid var(--border-color, #f0f0f0);
  flex-shrink: 0;
}

.bitable-file-detail-view__topbar-left {
  display: flex;
  align-items: center;
  gap: 8px;
}

.bitable-file-detail-view__topbar-right {
  display: flex;
  align-items: center;
  gap: 8px;
}

.bitable-file-detail-view__icon {
  font-size: 18px;
}

.bitable-file-detail-view__title {
  font-weight: 600;
  font-size: 16px;
}

.bitable-file-detail-view__body {
  flex: 1;
  display: flex;
  overflow: hidden;
}

.bitable-file-detail-view__sidebar {
  width: 240px;
  flex-shrink: 0;
  overflow: hidden;
}

.bitable-file-detail-view__main {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-width: 0;
}

.bitable-file-detail-view__placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  gap: 16px;
  color: var(--text-placeholder, #bfbfbf);
}

.bitable-file-detail-view__grid-header {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border-color, #f0f0f0);
  flex-shrink: 0;
}

.bitable-file-detail-view__table-name {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
}

.bitable-file-detail-view__field-count {
  font-size: 12px;
  color: var(--text-secondary, #8c8c8c);
}

.bitable-file-detail-view__grid-container {
  flex: 1;
  overflow: hidden;
  padding: 0;
}

.bitable-file-detail-view__load-more {
  display: flex;
  justify-content: center;
  padding: 8px;
  border-top: 1px solid var(--border-color, #f0f0f0);
  flex-shrink: 0;
}
</style>
