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

import { Button, Card, Col, Divider, Input, Row, Space, Spin, message } from 'ant-design-vue';

import { inject } from 'vue';
import type { ErpApiConfig, ErpApiParam } from '#/api/erp/api';

// 接收父组件注入的数据
const apiData = inject<ref<ErpApiConfig>>('apiData')!;
const paramsData = inject<ref<ErpApiParam[]>>('paramsData')!;

// SQL模板内容
const sqlTemplate = ref<string>('');

// 监听数据变化，同步SQL模板
watch(apiData, (newData) => {
  if (newData && newData.sqlTemplate) {
    sqlTemplate.value = newData.sqlTemplate;
  }
}, { immediate: true, deep: true });

// 监听SQL模板变化，同步回父组件
watch(sqlTemplate, (newSql) => {
  if (apiData.value) {
    apiData.value.sqlTemplate = newSql;
  }
});

// 测试参数值（用于预览）
const testParamValues = ref<Record<string, any>>({});

// 初始化测试参数值
watch(paramsData, (params) => {
  const values: Record<string, any> = {};
  params.forEach((param) => {
    // 如果参数有默认值，使用默认值；否则使用示例值
    values[param.paramName] = param.defaultValue || getExampleValue(param.paramType);
  });
  testParamValues.value = values;
}, { immediate: true, deep: true });

// 根据参数类型生成示例值
function getExampleValue(paramType: string): any {
  switch (paramType) {
    case 'String': return '示例值';
    case 'Integer': return 123;
    case 'Long': return 123456789;
    case 'Double': return 123.45;
    case 'Date': return '2026-04-30';
    case 'Boolean': return true;
    default: return '示例';
  }
}

// 参数注入后的SQL预览
const previewSql = computed(() => {
  let sql = sqlTemplate.value;

  // 替换 #{paramName} 为参数值
  const paramPattern = /#\{(\w+)\}/g;
  sql = sql.replace(paramPattern, (match, paramName) => {
    const value = testParamValues.value[paramName];
    if (value === undefined || value === null) {
      return 'NULL';
    }

    // 根据参数值类型格式化
    if (typeof value === 'string') {
      return `'${value}'`;
    } else if (typeof value === 'boolean') {
      return value ? '1' : '0';
    } else {
      return String(value);
    }
  });

  // 处理 #{param} IS NOT NULL THEN ... 逻辑
  // 移除参数为null的条件
  const conditionPattern = /AND\s+#\{(\w+)\}\s+IS\s+NOT\s+NULL\s+THEN\s+(.+?)(?=\s+AND|#|$)/g;
  sql = sql.replace(conditionPattern, (match, paramName, condition) => {
    const value = testParamValues.value[paramName];
    if (value !== undefined && value !== null) {
      // 参数有值，保留条件（替换 #{param} 为实际值）
      return `AND ${condition.replace(new RegExp(`#\\{${paramName}\\}`, 'g'), getFormattedValue(value))}`;
    } else {
      // 参数为null，移除整个条件
      return '';
    }
  });

  return sql;
});

// 格式化参数值
function getFormattedValue(value: any): string {
  if (typeof value === 'string') {
    return `'${value}'`;
  } else if (typeof value === 'boolean') {
    return value ? '1' : '0';
  } else {
    return String(value);
  }
}

// SQL语法验证
const validating = ref(false);
async function validateSql() {
  validating.value = true;
  try {
    // 简单的SQL关键字验证
    const sql = sqlTemplate.value.toUpperCase();

    // 必须包含SELECT
    if (!sql.includes('SELECT')) {
      message.error('SQL模板必须包含SELECT关键字');
      return;
    }

    // 禁止危险操作
    const dangerousKeywords = ['DROP', 'DELETE', 'TRUNCATE', 'ALTER', 'CREATE', 'GRANT', 'INSERT', 'UPDATE'];
    for (const keyword of dangerousKeywords) {
      if (sql.includes(keyword)) {
        message.error(`SQL模板不能包含危险关键字：${keyword}`);
        return;
      }
    }

    message.success('SQL语法验证通过');
  } finally {
    validating.value = false;
  }
}

// 复制SQL
function copySql() {
  navigator.clipboard.writeText(sqlTemplate.value);
  message.success('SQL模板已复制');
}

// 复制预览SQL
function copyPreviewSql() {
  navigator.clipboard.writeText(previewSql.value);
  message.success('参数注入后的SQL已复制');
}

// SQL模板片段快速插入
const sqlSnippets = [
  { label: 'SELECT *', value: 'SELECT *\nFROM table_name' },
  { label: 'WHERE条件', value: 'WHERE #{param} IS NOT NULL THEN field = #{param}' },
  { label: 'ORDER BY', value: 'ORDER BY field_name ASC' },
  { label: '参数占位符', value: '#{}' },
];

function insertSnippet(snippet: string) {
  sqlTemplate.value += '\n' + snippet;
  message.success('模板片段已插入');
}
</script>

<template>
  <div class="sql-editor-container">
    <Row :gutter="16">
      <!-- 左侧：SQL模板编辑 -->
      <Col :span="12">
        <Card title="SQL模板" size="small">
          <template #extra>
            <Space>
              <Button size="small" :loading="validating" @click="validateSql">
                验证SQL
              </Button>
              <Button size="small" @click="copySql">
                复制
              </Button>
            </Space>
          </template>

          <!-- 快速插入 -->
          <div class="mb-2">
            <Space>
              <span class="text-sm text-gray-500">快速插入：</span>
              <Button
                v-for="snippet in sqlSnippets"
                :key="snippet.label"
                size="small"
                type="link"
                @click="insertSnippet(snippet.value)"
              >
                {{ snippet.label }}
              </Button>
            </Space>
          </div>

          <!-- SQL编辑器 -->
          <Input.TextArea
            v-model:value="sqlTemplate"
            :rows="15"
            placeholder="请输入SQL模板，使用 #{paramName} 作为参数占位符"
            class="sql-editor"
          />

          <Divider />

          <!-- 参数列表提示 -->
          <div class="text-sm text-gray-600">
            <strong>可用参数：</strong>
            <div v-if="paramsData.length > 0" class="mt-2">
              <Space wrap>
                <span v-for="param in paramsData" :key="param.paramName">
                  <code class="bg-gray-100 px-1 rounded">#{{ '{' + param.paramName + '}' }}</code>
                  <span class="text-gray-500">({{ param.paramType }})</span>
                </span>
              </Space>
            </div>
            <div v-else class="text-warning">
              请在"参数配置"Tab中添加参数
            </div>
          </div>
        </Card>
      </Col>

      <!-- 右侧：参数注入预览 -->
      <Col :span="12">
        <Card title="参数注入预览" size="small">
          <template #extra>
            <Space>
              <Button size="small" @click="copyPreviewSql">
                复制预览SQL
              </Button>
            </Space>
          </template>

          <!-- 参数值输入 -->
          <div v-if="paramsData.length > 0" class="mb-4">
            <div class="text-sm text-gray-600 mb-2">参数值设置：</div>
            <div class="param-inputs">
              <Row :gutter="[8, 8]">
                <Col v-for="param in paramsData" :key="param.paramName" :span="12">
                  <div class="flex items-center">
                    <span class="w-24 text-sm">{{ param.paramName }}:</span>
                    <Input
                      v-model:value="testParamValues[param.paramName]"
                      size="small"
                      :placeholder="`示例: ${getExampleValue(param.paramType)}`"
                    />
                  </div>
                </Col>
              </Row>
            </div>
          </div>

          <!-- 预览SQL -->
          <Input.TextArea
            :value="previewSql"
            :rows="15"
            readonly
            placeholder="设置参数值后，将显示参数注入后的实际SQL"
            class="sql-preview bg-gray-50"
          />

          <Divider />

          <!-- 说明 -->
          <div class="text-sm text-gray-500">
            <strong>说明：</strong>
            <ul class="mt-1 pl-4 list-disc">
              <li>左侧编辑SQL模板，使用 #{{ '{paramName}' }} 作为参数占位符</li>
              <li>右侧设置参数值，实时预览参数注入后的实际SQL</li>
              <li>#{param} IS NOT NULL THEN ... 条件会在参数为NULL时自动移除</li>
              <li>字符串类型参数会自动添加单引号</li>
            </ul>
          </div>
        </Card>
      </Col>
    </Row>
  </div>
</template>

<style scoped>
.sql-editor-container {
  padding: 16px;
}

.sql-editor,
.sql-preview {
  font-family: 'Courier New', monospace;
  font-size: 13px;
}

.text-warning {
  color: #faad14;
}
</style>