<script setup lang="ts">
import { ref, watch } from 'vue';

import { Button, Card, message, Select } from 'ant-design-vue';

import { executeSqlQueryApi } from '../api';

defineOptions({
  name: 'SqlQuery',
});

// 接收外部传递的表名和表列表
const props = defineProps<{
  tableName?: string;
  tableList?: any[];
}>();

const sqlText = ref('');
const queryResult = ref<any[]>([]);
const queryColumns = ref<string[]>([]);
const loading = ref(false);
const queryHistory = ref<string[]>([]);
const selectedTableSelect = ref<string | undefined>(undefined);

// 验证SQL是否为SELECT语句
const validateSql = (sql: string): boolean => {
  const trimmedSql = sql.trim().toUpperCase();

  // 检查是否以SELECT开头
  if (!trimmedSql.startsWith('SELECT')) {
    return false;
  }

  // 禁止的危险关键字
  const dangerousKeywords = [
    'DROP', 'DELETE', 'UPDATE', 'INSERT', 'ALTER', 'CREATE', 'TRUNCATE',
    'REPLACE', 'GRANT', 'REVOKE', 'EXEC', 'EXECUTE', 'CALL', 'PROCEDURE',
  ];

  for (const keyword of dangerousKeywords) {
    if (trimmedSql.includes(keyword)) {
      return false;
    }
  }

  return true;
};

// 执行SQL查询
const handleExecute = async () => {
  if (!sqlText.value.trim()) {
    message.warning('请输入SQL语句');
    return;
  }

  if (!validateSql(sqlText.value)) {
    message.error('仅支持SELECT查询语句，且不能包含危险关键字');
    return;
  }

  loading.value = true;
  try {
    const res = await executeSqlQueryApi({
      sql: sqlText.value,
    });

    // 直接判断 res 是否为数组
    if (Array.isArray(res)) {
      queryResult.value = res;

      if (res.length > 0) {
        // 动态获取列名
        const firstRow = res[0];
        queryColumns.value = Object.keys(firstRow);

        message.success(`查询成功，返回 ${res.length} 条记录`);
      } else {
        queryColumns.value = [];
        message.info('查询成功，但未返回数据');
      }

      // 添加到历史记录
      if (!queryHistory.value.includes(sqlText.value)) {
        queryHistory.value.unshift(sqlText.value);
        if (queryHistory.value.length > 10) {
          queryHistory.value = queryHistory.value.slice(0, 10);
        }
      }
    } else {
      console.error('数据格式错误，期望数组，实际返回:', res);
      queryResult.value = [];
      queryColumns.value = [];
      message.warning('查询返回了非数组格式的数据');
    }
  } catch (error: any) {
    console.error('SQL执行错误:', error);
    message.error(error.message || '查询失败');
    queryResult.value = [];
    queryColumns.value = [];
  } finally {
    loading.value = false;
  }
};

// 监听 tableName 变化，设置默认值（从详情页进入时）
watch(
  () => props.tableName,
  (newVal) => {
    if (newVal) {
      selectedTableSelect.value = newVal;
      // 自动生成查询语句
      sqlText.value = `SELECT * FROM ${newVal} LIMIT 20;`;
      // 自动执行查询
      handleExecute();
    }
  },
  { immediate: true }
);

// 处理下拉框切换表名
const handleTableSelectChange = (value: string) => {
  selectedTableSelect.value = value;
  if (value) {
    sqlText.value = `SELECT * FROM ${value} LIMIT 20;`;
    handleExecute();
  }
};

// 清空SQL
const handleClear = () => {
  sqlText.value = '';
  queryResult.value = [];
  queryColumns.value = [];
  selectedTableSelect.value = undefined;
};

// 选择历史记录
const handleSelectHistory = (sql: string) => {
  sqlText.value = sql;
};
</script>

<template>
  <div class="sql-query h-full flex flex-col">
    <Card title="SQL查询" class="mb-4 flex-shrink-0">
      <div class="mb-4 space-y-3">
        <!-- 顶部工具栏：选择表 -->
        <div class="flex items-center gap-4">
          <div class="flex items-center gap-2 flex-1">
            <span class="text-sm font-medium text-gray-700 dark:text-gray-300">快捷查询表:</span>
            <Select
              v-model:value="selectedTableSelect"
              show-search
              placeholder="选择数据表自动生成查询..."
              class="w-64"
              :options="props.tableList?.map(t => ({ label: t.name + (t.comment ? ` (${t.comment})` : ''), value: t.name }))"
              @change="handleTableSelectChange"
              :filter-option="(input, option) => (option?.label ?? '').toLowerCase().includes(input.toLowerCase())"
            />
          </div>

          <div v-if="queryHistory.length > 0" class="flex items-center gap-2">
            <span class="text-sm text-gray-500">历史记录：</span>
            <select
              class="rounded border border-gray-300 px-2 py-1 text-sm dark:border-gray-600 dark:bg-gray-800 outline-none focus:border-primary max-w-[200px]"
              @change="(e: any) => handleSelectHistory(e.target.value)"
            >
              <option value="">选择历史记录</option>
              <option v-for="(sql, index) in queryHistory" :key="index" :value="sql">
                {{ sql.substring(0, 30) }}{{ sql.length > 30 ? '...' : '' }}
              </option>
            </select>
          </div>
        </div>

        <textarea
          v-model="sqlText"
          class="w-full rounded border border-gray-300 p-3 font-mono text-sm dark:border-gray-600 dark:bg-gray-800 focus:ring-2 focus:ring-primary/50 focus:border-primary outline-none transition-all"
          rows="5"
          placeholder="请输入SELECT查询语句，例如：SELECT * FROM nl_admin LIMIT 10;"
        />
      </div>

      <div class="flex items-center justify-between">
        <div class="flex items-center gap-2">
          <Button type="primary" :loading="loading" @click="handleExecute">
            <i class="fa-solid fa-play mr-2"></i>执行查询
          </Button>
          <Button @click="handleClear">
            <i class="fa-solid fa-eraser mr-2"></i>清空
          </Button>
        </div>
      </div>
    </Card>

    <!-- 自定义表格区域 -->
    <Card
      v-if="queryResult.length > 0 || loading"
      title="查询结果"
      class="flex-1 overflow-hidden flex flex-col"
      :body-style="{ padding: 0, flex: 1, overflow: 'hidden', display: 'flex', flexDirection: 'column' }"
    >
      <div class="flex-1 overflow-auto">
        <table class="w-full border-collapse text-left text-sm whitespace-nowrap">
          <thead class="bg-gray-50 dark:bg-gray-800 sticky top-0 z-10 shadow-sm">
          <tr>
            <!-- 序号列 -->
            <th class="px-4 py-3 font-semibold text-gray-700 dark:text-gray-200 border-b border-r border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800 w-16 text-center">
              #
            </th>
            <!-- 动态列头 -->
            <th
              v-for="col in queryColumns"
              :key="col"
              class="px-4 py-3 font-semibold text-gray-700 dark:text-gray-200 border-b border-gray-200 dark:border-gray-700"
            >
              {{ col }}
            </th>
          </tr>
          </thead>
          <tbody class="divide-y divide-gray-200 dark:divide-gray-700 bg-white dark:bg-gray-900">
          <tr
            v-for="(row, rowIndex) in queryResult"
            :key="rowIndex"
            class="hover:bg-blue-50/50 dark:hover:bg-blue-900/10 transition-colors"
          >
            <!-- 序号 -->
            <td class="px-4 py-3 text-gray-500 border-r border-gray-100 dark:border-gray-800 text-center font-mono text-xs bg-gray-50/30">
              {{ rowIndex + 1 }}
            </td>
            <!-- 数据单元格 -->
            <td
              v-for="col in queryColumns"
              :key="col"
              class="px-4 py-3 text-gray-600 dark:text-gray-300"
            >
              <div class="max-w-xs truncate" :title="String(row[col])">
                {{ row[col] !== null ? row[col] : '(NULL)' }}
              </div>
            </td>
          </tr>
          </tbody>
        </table>
      </div>
      <!-- 底部统计栏 -->
      <div class="border-t border-gray-200 dark:border-gray-700 p-2 bg-gray-50 dark:bg-gray-800 text-xs text-gray-500 text-right">
        共显示 {{ queryResult.length }} 条记录
      </div>
    </Card>
  </div>
</template>

<style scoped>
/* 滚动条美化 */
.overflow-auto {
  scrollbar-width: thin;
  scrollbar-color: rgba(156, 163, 175, 0.5) transparent;
}
.overflow-auto::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}
.overflow-auto::-webkit-scrollbar-track {
  background: transparent;
}
.overflow-auto::-webkit-scrollbar-thumb {
  background-color: rgba(156, 163, 175, 0.5);
  border-radius: 3px;
}
.overflow-auto::-webkit-scrollbar-corner {
  background: transparent;
}
</style>
