<script setup lang="ts">
import type { TreeNode } from './composables/use-connection-tree';

import { nextTick, onBeforeUnmount, onMounted, ref } from 'vue';

import {
  ResizableHandle,
  ResizablePanel,
  ResizablePanelGroup,
} from '@easyflow-core/shadcn-ui';

import { ElEmpty, ElMessage, ElMessageBox } from 'element-plus';

import ConnectionTree from './components/ConnectionTree.vue';
import SourceFormDrawer from './components/SourceFormDrawer.vue';
import TableDetailView from './components/TableDetailView.vue';
import TableListView from './components/TableListView.vue';
import { useConnectionTree } from './composables/use-connection-tree';
import { useDatacenterSources } from './composables/use-datacenter-sources';
import { useDatacenterTables } from './composables/use-datacenter-tables';

const sourceFormRef = ref<InstanceType<typeof SourceFormDrawer>>();
const sourceFormVisible = ref(false);
const workspaceRef = ref<HTMLElement>();
const workspaceHeight = ref('100%');

const {
  sources,
  selectedSourceId,
  selectedSource,
  loading,
  saving,
  testing,
  importExcelSource,
  loadSources,
  removeSource,
  saveSource,
  testConnection,
  markSourceRuntimeUnavailable,
  clearSourceRuntimeUnavailable,
} = useDatacenterSources();

const {
  sourceTables,
  managedTables,
  schema,
  previewRows,
  jobs,
  sourceUnavailable,
  selectedCatalogId,
  selectedTableId,
  selectedTable,
  previewLoading,
  loadTableRuntime,
  syncSourceContext,
  batchRegisterTables,
  batchRemoveTables,
  saveDescriptions,
} = useDatacenterTables(selectedSourceId, {
  markSourceRuntimeUnavailable,
  clearSourceRuntimeUnavailable,
});

async function reloadAll(options?: {
  focus?: 'source' | 'table';
  resetTable?: boolean;
}) {
  await loadSources();
  if (selectedSourceId.value === null) {
    selectedCatalogId.value = null;
    selectedTableId.value = null;
    selectedNodeKey.value = '';
    viewMode.value = 'empty';
    await syncSourceContext();
    return;
  }
  if (options?.resetTable) {
    selectedTableId.value = null;
  }
  await syncSourceContext();
  if (options?.focus === 'table' && selectedTable.value) {
    selectedNodeKey.value = `table-${selectedTable.value.id}`;
    viewMode.value = 'detail';
    return;
  }
  selectedNodeKey.value = `source-${selectedSourceId.value}`;
  viewMode.value = 'list';
}

// 视图状态：empty | list | detail
const selectedNodeKey = ref('');
const viewMode = ref<'detail' | 'empty' | 'list'>('empty');

const { treeData, parseNodeKey } = useConnectionTree(sources);

async function handleNodeSelect(node: TreeNode) {
  selectedNodeKey.value = node.id;

  switch (node.type) {
    case 'source': {
      const { id } = parseNodeKey(node.id);
      if (id !== selectedSourceId.value) {
        selectedSourceId.value = id;
        selectedCatalogId.value = null;
        selectedTableId.value = null;
        await syncSourceContext();
      }
      viewMode.value = 'list';

      break;
    }
    case 'table': {
      const { id } = parseNodeKey(node.id);
      selectedTableId.value = id;
      await loadTableRuntime();
      viewMode.value = 'detail';

      break;
    }
    // No default
  }
}

async function handleBatchRegister(rows: any[]) {
  await batchRegisterTables(rows);
}

async function handleBatchRemove(rows: any[]) {
  const removedIds = rows.map((row) => row?.id).filter(Boolean);
  await batchRemoveTables(rows);
  if (
    selectedTableId.value !== null &&
    removedIds.includes(selectedTableId.value)
  ) {
    viewMode.value = 'list';
  }
}

async function handleSaveTableDescription(
  tableId: number | string,
  tableDesc: string,
) {
  await saveDescriptions({
    tableId,
    tableDesc,
    fields: [],
  });
}

function handleSelectTable(row: any) {
  selectedTableId.value = row.id;
  selectedNodeKey.value = `table-${row.id}`;
  viewMode.value = 'detail';
  loadTableRuntime();
}

function handleBackToList() {
  viewMode.value = 'list';
  if (selectedSource.value) {
    selectedNodeKey.value = `source-${selectedSource.value.id}`;
  }
}

function openCreate() {
  sourceFormRef.value?.open();
  sourceFormVisible.value = true;
}

function openEdit(node: TreeNode) {
  if (node.type !== 'source') return;
  sourceFormRef.value?.open(node.meta);
  sourceFormVisible.value = true;
}

async function handleRemoveSource(node: TreeNode) {
  if (node.type !== 'source' || !node.meta?.id) return;
  await ElMessageBox.confirm(`确认删除“${node.label}”吗？`, '删除连接', {
    type: 'warning',
    confirmButtonText: '删除',
    cancelButtonText: '取消',
    confirmButtonClass: 'el-button--danger',
  });
  const removingCurrent = selectedSourceId.value === node.meta.id;
  await removeSource(node.meta.id);
  if (removingCurrent) {
    selectedTableId.value = null;
  }
  await reloadAll({ focus: 'source', resetTable: true });
}

async function handleSaveSource(
  formData: Record<string, any>,
  excelFile?: File,
) {
  if (formData.sourceType === 'EXCEL' && !formData.id) {
    if (!excelFile) return;
    await importExcelSource(excelFile, formData.sourceName);
    ElMessage.success('Excel 已导入');
  } else {
    await saveSource(formData);
    ElMessage.success(formData.id ? '连接已更新' : '连接已创建');
  }
  sourceFormRef.value?.close();
  sourceFormVisible.value = false;
  await nextTick();
  await reloadAll({ focus: 'source', resetTable: true });
}

async function handleTestConnection(formData: Record<string, any>) {
  const result = await testConnection(formData);
  sourceFormRef.value?.setTestResult(result);
  if (formData.id) await loadSources();
}

async function loadAll() {
  loading.value = true;
  try {
    await reloadAll({ focus: 'source', resetTable: true });
  } finally {
    loading.value = false;
  }
}

function updateWorkspaceHeight() {
  const element = workspaceRef.value;
  if (!element) return;
  const top = element.getBoundingClientRect().top;
  workspaceHeight.value = `${Math.max(window.innerHeight - top, 480)}px`;
}

onMounted(async () => {
  await loadAll();
  await nextTick();
  updateWorkspaceHeight();
  window.addEventListener('resize', updateWorkspaceHeight);
});

onBeforeUnmount(() => {
  window.removeEventListener('resize', updateWorkspaceHeight);
});
</script>

<template>
  <div
    ref="workspaceRef"
    class="datacenter-workspace"
    :style="{ height: workspaceHeight }"
    v-loading="loading"
  >
    <!-- 双栏主体 -->
    <ResizablePanelGroup direction="horizontal" class="workspace-body">
      <ResizablePanel :default-size="20" :min-size="16" :max-size="30">
        <ConnectionTree
          :tree-data="treeData"
          :selected-key="selectedNodeKey"
          @create="openCreate"
          @edit="openEdit"
          @refresh="loadAll"
          @remove="handleRemoveSource"
          @select="handleNodeSelect"
        />
      </ResizablePanel>

      <ResizableHandle />

      <ResizablePanel :default-size="80" :min-size="44">
        <TableListView
          v-if="viewMode === 'list'"
          :source-tables="sourceTables"
          :managed-tables="managedTables"
          :save-table-description="handleSaveTableDescription"
          :source-label="selectedSource?.sourceName || ''"
          :source-unavailable="sourceUnavailable"
          @register-tables="handleBatchRegister"
          @remove-tables="handleBatchRemove"
          @select-table="handleSelectTable"
        />
        <TableDetailView
          v-else-if="viewMode === 'detail' && selectedTable"
          :table="selectedTable"
          :schema="schema"
          :preview-rows="previewRows"
          :jobs="jobs"
          :loading="previewLoading"
          :save-descriptions="saveDescriptions"
          :source-unavailable="sourceUnavailable"
          @back="handleBackToList"
        />
        <div v-else class="empty-state">
          <ElEmpty description="从左侧选择连接或表开始浏览" />
        </div>
      </ResizablePanel>
    </ResizablePanelGroup>

    <!-- Drawers -->
    <SourceFormDrawer
      ref="sourceFormRef"
      v-model:visible="sourceFormVisible"
      :saving="saving"
      :testing="testing"
      @save="handleSaveSource"
      @test="handleTestConnection"
    />
  </div>
</template>

<style scoped>
.datacenter-workspace {
  display: flex;
  flex-direction: column;
  width: 100%;
  min-height: 0;
  padding-top: 12px;
  margin-top: 0;
  overflow: hidden;
  background: transparent;
}

.workspace-body {
  flex: 1;
  width: 100%;
  min-height: 0;
  overflow: hidden;
  background: transparent;
}

.workspace-body :deep([data-panel-group-direction='horizontal']) {
  height: 100%;
}

.workspace-body :deep([data-panel-resize-handle-enabled]) {
  position: relative;
  width: 10px;
  background: transparent;
}

.workspace-body :deep([data-panel-resize-handle-enabled]::before) {
  position: absolute;
  top: 20px;
  bottom: 20px;
  left: 50%;
  width: 1px;
  content: '';
  background: hsl(var(--border) / 32%);
  transform: translateX(-50%);
}

.empty-state {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  background: transparent;
}
</style>
