<template>
  <a-drawer
    :open="open"
    title="视图配置"
    :placement="drawerPlacement"
    :width="drawerWidth"
    @close="handleClose"
  >
    <a-tabs v-model:activeKey="activeTab">
      <!-- Filter tab -->
      <a-tab-pane key="filter" tab="筛选">
        <FilterBuilder
          ref="filterRef"
          :fields="fields"
          :model-value="currentFilters"
        />
        <div class="view-config-panel__actions">
          <a-button type="primary" @click="saveFilters">保存筛选</a-button>
        </div>
      </a-tab-pane>

      <!-- Sort tab -->
      <a-tab-pane key="sort" tab="排序">
        <div class="view-config-panel__sort-row">
          <a-select
            v-model:value="sortFieldId"
            placeholder="选择排序字段"
            style="width: 200px"
          >
            <a-select-option
              v-for="f in fields"
              :key="f.id"
              :value="f.id"
            >
              {{ f.name }}
            </a-select-option>
          </a-select>
          <a-select v-model:value="sortOrder" style="width: 100px">
            <a-select-option value="asc">升序</a-select-option>
            <a-select-option value="desc">降序</a-select-option>
          </a-select>
        </div>
        <div class="view-config-panel__actions">
          <a-button type="primary" @click="saveSort">保存排序</a-button>
        </div>
      </a-tab-pane>

      <!-- Hidden fields tab -->
      <a-tab-pane key="hidden" tab="隐藏字段">
        <p class="view-config-panel__hint">勾选要隐藏的字段：</p>
        <a-checkbox-group v-model:value="hiddenFieldIds">
          <div
            v-for="f in fields"
            :key="f.id"
            class="view-config-panel__field-check"
          >
            <a-checkbox :value="f.id">{{ f.name }}</a-checkbox>
          </div>
        </a-checkbox-group>
        <div class="view-config-panel__actions">
          <a-button type="primary" @click="saveHidden">保存隐藏配置</a-button>
        </div>
      </a-tab-pane>

      <!-- U5: Grouping tab -->
      <a-tab-pane key="grouping" tab="分组">
        <GroupingEditor
          v-model="groupByItems"
          :fields="fields"
        />
        <div class="view-config-panel__actions">
          <a-button type="primary" @click="saveU5Config">保存分组</a-button>
        </div>
      </a-tab-pane>

      <!-- U5: Conditional formatting tab -->
      <a-tab-pane key="conditional-format" tab="条件格式">
        <ConditionalFormatEditor
          v-model="cfRules"
          :fields="fields"
        />
        <div class="view-config-panel__actions">
          <a-button type="primary" @click="saveU5Config">保存条件格式</a-button>
        </div>
      </a-tab-pane>
    </a-tabs>
  </a-drawer>
</template>

<script setup lang="ts">
import { ref, watch, computed } from 'vue'
import {
  Drawer as ADrawer,
  Tabs as ATabs,
  Button as AButton,
  Select as ASelect,
  Checkbox as ACheckbox,
} from 'ant-design-vue'
import type { IBitableField, IBitableView } from '@/api/bitable'
import { useBitableStore } from '@/stores/bitable'
import { useResponsiveBreakpoint } from '@/composables/useResponsiveBreakpoint'
import FilterBuilder from './FilterBuilder.vue'
import GroupingEditor from './GroupingEditor.vue'
import ConditionalFormatEditor from './ConditionalFormatEditor.vue'
import type {
  GroupByItem,
  ConditionalFormatRule,
} from '@/helpers/groupingRulesUtils'

const props = defineProps<{
  open: boolean
  fields: IBitableField[]
  view: IBitableView | null
}>()

const emit = defineEmits<{
  (e: 'close'): void
}>()

const store = useBitableStore()

// U1 step 7: ViewConfigPanel becomes a bottom drawer on mobile.
// ponytail: only the placement + width differ; the rest of the UI is shared.
// Ceiling: the drawer height on mobile is unbounded — long rule lists may
// scroll past the fold. Acceptable for v1; upgrade path: a max-height + scroll.
const { isMobile } = useResponsiveBreakpoint()
const drawerPlacement = computed(() => (isMobile.value ? 'bottom' : 'right'))
const drawerWidth = computed(() => (isMobile.value ? '100%' : 520))

const activeTab = ref('filter')
const filterRef = ref<InstanceType<typeof FilterBuilder> | null>(null)

// Current config from view
const currentFilters = computed(() => {
  const filters = props.view?.config?.filters as unknown
  if (!Array.isArray(filters)) return []
  return filters as { field_id: string; op: string; value: string | number | undefined }[]
})

const sortFieldId = ref<string>(
  (props.view?.config?.sort as { field?: string })?.field ?? '',
)
const sortOrder = ref<string>(
  (props.view?.config?.sort as { order?: string })?.order ?? 'asc',
)
const hiddenFieldIds = ref<string[]>(
  (props.view?.config?.hidden_fields as string[]) ?? [],
)

// U5: group_by + conditional_formatting local working copies.
const groupByItems = ref<GroupByItem[]>(extractGroupBy(props.view))
const cfRules = ref<ConditionalFormatRule[]>(extractConditionalFormat(props.view))

function extractGroupBy(view: IBitableView | null): GroupByItem[] {
  const raw = view?.config?.group_by
  if (!Array.isArray(raw)) return []
  return raw as GroupByItem[]
}

function extractConditionalFormat(view: IBitableView | null): ConditionalFormatRule[] {
  const raw = view?.config?.conditional_formatting
  if (!Array.isArray(raw)) return []
  return raw as ConditionalFormatRule[]
}

// Reset when view changes (covers initial load + view-switch reloads)
watch(
  () => props.view?.id,
  () => {
    sortFieldId.value = (props.view?.config?.sort as { field?: string })?.field ?? ''
    sortOrder.value = (props.view?.config?.sort as { order?: string })?.order ?? 'asc'
    hiddenFieldIds.value = (props.view?.config?.hidden_fields as string[]) ?? []
    groupByItems.value = extractGroupBy(props.view)
    cfRules.value = extractConditionalFormat(props.view)
  },
)

function handleClose(): void {
  emit('close')
}

async function saveFilters(): Promise<void> {
  if (!props.view) return
  const conditions = filterRef.value?.getConditions() ?? []
  const config = {
    ...props.view.config,
    filters: conditions,
  }
  await store.updateView(props.view.id, { config })
}

async function saveSort(): Promise<void> {
  if (!props.view) return
  const config = {
    ...props.view.config,
    sort: { field: sortFieldId.value, order: sortOrder.value },
  }
  await store.updateView(props.view.id, { config })
}

async function saveHidden(): Promise<void> {
  if (!props.view) return
  const config = {
    ...props.view.config,
    hidden_fields: hiddenFieldIds.value,
  }
  await store.updateView(props.view.id, { config })
}

// U5: save group_by + conditional_formatting through the new
// updateViewConfig action (which calls the same PATCH /views endpoint;
// the route layer validates the U5 sub-keys and 422s on invalid input).
// Both tabs' save buttons call this — saving either tab persists both U5
// keys together (matches the existing merge-then-PATCH behavior).
async function saveU5Config(): Promise<void> {
  if (!props.view) return
  await store.updateViewConfig(props.view.id, {
    group_by: groupByItems.value,
    conditional_formatting: cfRules.value,
  })
}
</script>

<style scoped>
.view-config-panel__sort-row {
  display: flex;
  gap: 8px;
  margin-bottom: 16px;
}

.view-config-panel__actions {
  margin-top: 16px;
}

.view-config-panel__hint {
  color: var(--text-secondary, #8c8c8c);
  margin-bottom: 12px;
}

.view-config-panel__field-check {
  margin-bottom: 8px;
}
</style>
