<script lang="ts" setup>
/**
 * 数据库表选择对话框
 * 参考 data-source-config.vue 实现
 */
import type { ColumnInfo } from '#/api/core/database-manager';

import { onMounted, ref, watch } from 'vue';

import { Database, RefreshCw } from '@vben/icons';
import { $t } from '@vben/locales';

import {
  ElButton,
  ElDialog,
  ElIcon,
  ElMessage,
  ElScrollbar,
  ElTag,
  ElTooltip,
  ElTree,
} from 'element-plus';

import {
  getDatabaseConfigsApi,
  getDatabasesApi,
  getSchemasApi,
  getTableColumnsApi,
  getTablesApi,
} from '#/api/core/database-manager';
import { DatabaseTreeNodeIcon } from '#/components/database-tree-node-icon';
import { DatabaseTreeNodeLabel } from '#/components/database-tree-node-label';

// 树节点类型
interface TreeNode {
  id: string;
  label: string;
  type: 'connection' | 'database' | 'schema' | 'table';
  isLeaf: boolean;
  meta?: {
    database?: string;
    dbName?: string;
    dbType?: string;
    schema?: string;
    table?: string;
  };
  children?: TreeNode[];
}

// 表字段类型
interface TableField {
  name: string;
  type: string;
  comment: string;
  nullable: boolean;
  isPrimaryKey: boolean;
}

// 选中的表信息
export interface SelectedTable {
  tableName: string;
  dbName: string;
  dbType: string;
  database: string;
  schema?: string;
  fields: TableField[];
}

const props = defineProps<{
  currentTable?: string;
  visible: boolean;
}>();

const emit = defineEmits<{
  select: [table: SelectedTable];
  'update:visible': [value: boolean];
}>();

// 对话框可见性
const dialogVisible = ref(false);

watch(
  () => props.visible,
  (val) => {
    dialogVisible.value = val;
  },
);

watch(dialogVisible, (val) => {
  emit('update:visible', val);
});

// 树相关
const treeData = ref<TreeNode[]>([]);
const loading = ref(false);

// 树配置
const treeProps = {
  label: 'label',
  children: 'children',
  isLeaf: 'isLeaf',
};

// 当前选中的表节点
const selectedTableNode = ref<null | TreeNode>(null);
const previewFields = ref<TableField[]>([]);
const previewLoading = ref(false);

// 加载数据库配置（根节点）
async function loadDatabaseConfigs() {
  loading.value = true;
  try {
    const configs = await getDatabaseConfigsApi();
    treeData.value = configs.map((config) => ({
      id: `conn-${config.db_name}`,
      label: config.display_name || config.name,
      type: 'connection' as const,
      isLeaf: false,
      meta: {
        dbName: config.db_name,
        dbType: config.db_type,
        isSystem: config.is_system,
      },
    }));
  } catch (error) {
    console.error('Failed to load database configs:', error);
    ElMessage.error(
      $t('ai-platform.workflow.editor.tableSelectDialog.loadConfigFailed'),
    );
  } finally {
    loading.value = false;
  }
}

// 加载数据库列表
async function loadDatabases(dbName: string, dbType?: string) {
  try {
    const databases = await getDatabasesApi(dbName);
    return databases.map((db) => ({
      id: `db-${dbName}-${db.name}`,
      label: db.name,
      type: 'database' as const,
      isLeaf: false,
      meta: {
        dbName,
        dbType,
        database: db.name,
      },
    }));
  } catch (error) {
    console.error('Failed to load databases:', error);
    return [];
  }
}

// 加载Schema列表
async function loadSchemas(dbName: string, database: string, dbType?: string) {
  try {
    const schemas = await getSchemasApi(dbName, database);
    return schemas.map((schema) => ({
      id: `schema-${dbName}-${database}-${schema.name}`,
      label: schema.name,
      type: 'schema' as const,
      isLeaf: false,
      meta: {
        dbName,
        dbType,
        database,
        schema: schema.name,
      },
    }));
  } catch (error) {
    console.error('Failed to load schemas:', error);
    return [];
  }
}

// 加载表列表
async function loadTables(
  dbName: string,
  database: string,
  schema?: string,
  dbType?: string,
) {
  try {
    const tableList = await getTablesApi(dbName, database, schema);
    return tableList.map((table) => ({
      id: `table-${dbName}-${database}-${schema || ''}-${table.table_name}`,
      label: table.table_name,
      type: 'table' as const,
      isLeaf: true,
      meta: {
        dbName,
        dbType,
        database,
        schema: schema || table.schema_name,
        table: table.table_name,
      },
    }));
  } catch (error) {
    console.error('Failed to load tables:', error);
    return [];
  }
}

// 懒加载子节点
async function loadNode(node: any, resolve: any) {
  if (node.level === 0) {
    resolve(treeData.value);
    return;
  }

  const nodeData = node.data as TreeNode;
  const { type, meta } = nodeData;

  if (!meta) {
    resolve([]);
    return;
  }

  try {
    if (type === 'connection' && meta.dbName) {
      const nodes = await loadDatabases(meta.dbName, meta.dbType);
      resolve(nodes);
      return;
    }

    if (type === 'database' && meta.dbName && meta.database) {
      const dbType = meta.dbType?.toLowerCase();
      if (dbType === 'postgresql' || dbType === 'sqlserver') {
        const nodes = await loadSchemas(
          meta.dbName,
          meta.database,
          meta.dbType,
        );
        resolve(nodes);
      } else {
        const nodes = await loadTables(
          meta.dbName,
          meta.database,
          undefined,
          meta.dbType,
        );
        resolve(nodes);
      }
      return;
    }

    if (type === 'schema' && meta.dbName && meta.database) {
      const nodes = await loadTables(
        meta.dbName,
        meta.database,
        meta.schema,
        meta.dbType,
      );
      resolve(nodes);
      return;
    }

    resolve([]);
  } catch (error) {
    console.error('Failed to load node:', error);
    resolve([]);
  }
}

// 节点点击 - 预览表字段
async function handleNodeClick(data: TreeNode) {
  if (data.type === 'table' && data.meta) {
    selectedTableNode.value = data;
    previewLoading.value = true;

    try {
      const columns = await getTableColumnsApi(
        data.meta.dbName!,
        data.meta.table!,
        data.meta.database,
        data.meta.schema,
      );
      previewFields.value = columns.map((col: ColumnInfo) => ({
        name: col.column_name,
        type: col.data_type,
        comment: col.description || '',
        nullable: col.is_nullable,
        isPrimaryKey: col.is_primary_key,
      }));
    } catch (error) {
      console.error('Failed to load columns:', error);
      previewFields.value = [];
    } finally {
      previewLoading.value = false;
    }
  }
}

// 双击选中表
async function handleNodeDblClick(data: TreeNode) {
  if (data.type === 'table' && data.meta) {
    await selectTable(data);
  }
}

// 选中表
async function selectTable(node: TreeNode) {
  if (node.type !== 'table' || !node.meta) return;

  // 如果还没加载字段，先加载
  let fields = previewFields.value;
  if (selectedTableNode.value?.id !== node.id || fields.length === 0) {
    try {
      const columns = await getTableColumnsApi(
        node.meta.dbName!,
        node.meta.table!,
        node.meta.database,
        node.meta.schema,
      );
      fields = columns.map((col: ColumnInfo) => ({
        name: col.column_name,
        type: col.data_type,
        comment: col.description || '',
        nullable: col.is_nullable,
        isPrimaryKey: col.is_primary_key,
      }));
    } catch (error) {
      console.error('Failed to load columns:', error);
      fields = [];
    }
  }

  emit('select', {
    tableName: node.meta.table!,
    dbName: node.meta.dbName!,
    dbType: node.meta.dbType || '',
    database: node.meta.database || '',
    schema: node.meta.schema,
    fields,
  });

  dialogVisible.value = false;
}

// 确认选择
function handleConfirm() {
  if (selectedTableNode.value) {
    selectTable(selectedTableNode.value);
  } else {
    ElMessage.warning(
      $t('ai-platform.workflow.editor.tableSelectDialog.selectTableFirst'),
    );
  }
}

// 刷新树
async function refreshTree() {
  await loadDatabaseConfigs();
  ElMessage.success(
    $t('ai-platform.workflow.editor.tableSelectDialog.refreshSuccess'),
  );
}

// 初始化
onMounted(() => {
  loadDatabaseConfigs();
});
</script>

<template>
  <ElDialog
    v-model="dialogVisible"
    :title="$t('ai-platform.workflow.editor.tableSelectDialog.title')"
    width="700px"
    :close-on-click-modal="false"
    destroy-on-close
    class="table-select-dialog"
  >
    <div class="flex h-[500px] gap-3">
      <!-- 左侧：数据库树形结构 -->
      <div
        class="border-border bg-card flex h-full w-[280px] flex-col rounded-lg border"
      >
        <div
          class="border-border flex items-center justify-between border-b px-3 py-2"
        >
          <div class="flex items-center gap-2">
            <ElIcon><Database /></ElIcon>
            <span class="text-sm font-medium">{{
              $t('ai-platform.workflow.editor.tableSelectDialog.database')
            }}</span>
          </div>
          <ElTooltip
            :content="
              $t('ai-platform.workflow.editor.tableSelectDialog.refresh')
            "
          >
            <ElButton
              :icon="RefreshCw"
              link
              size="small"
              @click="refreshTree"
            />
          </ElTooltip>
        </div>

        <!-- 树形结构 -->
        <ElScrollbar class="flex-1">
          <div v-if="loading" class="flex h-32 items-center justify-center">
            <span class="text-muted-foreground text-sm">{{
              $t('ai-platform.workflow.editor.tableSelectDialog.loading')
            }}</span>
          </div>
          <ElTree
            v-else
            ref="treeRef"
            :data="treeData"
            :props="treeProps"
            :load="loadNode"
            node-key="id"
            lazy
            highlight-current
            class="p-2"
            @node-click="handleNodeClick"
            @node-dblclick="handleNodeDblClick"
          >
            <template #default="{ data }">
              <div class="flex items-center gap-2">
                <DatabaseTreeNodeIcon
                  :type="data.type"
                  :db-type="data.meta?.dbType"
                  :size="16"
                />
                <DatabaseTreeNodeLabel
                  :label="data.label"
                  :type="data.type"
                  :is-system="data.meta?.isSystem"
                  :db-name="data.meta?.dbName"
                />
                <ElTag
                  v-if="
                    data.type === 'table' && data.meta?.table === currentTable
                  "
                  size="small"
                  type="success"
                >
                  {{
                    $t('ai-platform.workflow.editor.tableSelectDialog.current')
                  }}
                </ElTag>
              </div>
            </template>
          </ElTree>
        </ElScrollbar>
      </div>

      <!-- 右侧：字段预览 -->
      <div class="border-border bg-card flex flex-1 flex-col rounded-lg border">
        <div class="border-border flex items-center gap-2 border-b px-3 py-2">
          <span class="text-sm font-medium">
            {{
              selectedTableNode
                ? $t(
                    'ai-platform.workflow.editor.tableSelectDialog.fieldList',
                    { table: selectedTableNode.label },
                  )
                : $t(
                    'ai-platform.workflow.editor.tableSelectDialog.fieldPreview',
                  )
            }}
          </span>
        </div>

        <ElScrollbar class="flex-1">
          <div
            v-if="!selectedTableNode"
            class="flex h-full items-center justify-center"
          >
            <span class="text-muted-foreground text-sm">{{
              $t('ai-platform.workflow.editor.tableSelectDialog.clickToPreview')
            }}</span>
          </div>
          <div
            v-else-if="previewLoading"
            class="flex h-32 items-center justify-center"
          >
            <span class="text-muted-foreground text-sm">{{
              $t('ai-platform.workflow.editor.tableSelectDialog.loading')
            }}</span>
          </div>
          <div v-else class="p-2">
            <div
              v-for="field in previewFields"
              :key="field.name"
              class="border-border/50 flex items-center justify-between border-b px-2 py-2 text-sm last:border-b-0"
            >
              <div class="flex items-center gap-2">
                <span
                  class="font-mono font-medium"
                  :class="{ 'text-primary': field.isPrimaryKey }"
                >
                  {{ field.name }}
                </span>
                <ElTag v-if="field.isPrimaryKey" size="small" type="warning">
                  PK
                </ElTag>
              </div>
              <span class="text-muted-foreground text-xs">{{
                field.type
              }}</span>
            </div>
            <div
              v-if="previewFields.length === 0"
              class="text-muted-foreground py-8 text-center text-sm"
            >
              {{ $t('ai-platform.workflow.editor.tableSelectDialog.noFields') }}
            </div>
          </div>
        </ElScrollbar>

        <!-- 选中的表信息 -->
        <div
          v-if="selectedTableNode?.meta"
          class="border-border bg-muted border-t px-3 py-2"
        >
          <div class="text-muted-foreground text-xs">
            <span class="font-medium">{{
              selectedTableNode.meta.database
            }}</span>
            <span v-if="selectedTableNode.meta.schema">.{{ selectedTableNode.meta.schema }}</span>
            <span class="text-primary font-medium">.{{ selectedTableNode.meta.table }}</span>
          </div>
        </div>
      </div>
    </div>

    <template #footer>
      <ElButton @click="dialogVisible = false">
        {{ $t('ai-platform.workflow.editor.tableSelectDialog.cancel') }}
      </ElButton>
      <ElButton
        type="primary"
        :disabled="!selectedTableNode"
        @click="handleConfirm"
      >
        {{ $t('ai-platform.workflow.editor.tableSelectDialog.confirmSelect') }}
      </ElButton>
    </template>
  </ElDialog>
</template>

<style scoped>
:deep(.el-tree-node__content) {
  display: flex;
  align-items: center;
  height: 28px;
  line-height: 28px;
  border-radius: 4px;
}

/* 懒加载时 loading 替换箭头位置 */
:deep(.el-tree-node__content:has(.el-tree-node__loading-icon) > .el-tree-node__expand-icon) {
  display: none;
}

:deep(.el-tree-node__loading-icon) {
  order: -1;
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  margin-right: 0;
}

:deep(.el-tree-node__expand-icon) {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  padding: 0;
}
</style>
