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

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

import { useVbenForm } from '#/adapter/form';
import { codeGenerationForm } from '#/views/code-generation/config/form';

import type { CodeGenData } from '../utils/data-transformer';
import { validateData } from '../utils/data-transformer';
import {
  generateFromTableApi,
  getTableStructureApi,
  getTablesApi,
} from '../api';

const emit = defineEmits<{
  generate: [data: CodeGenData];
  back: [];
}>();

// 表单相关
const [Form, formApi] = useVbenForm(codeGenerationForm);
const formData = ref<Record<string, any>>({
  class_name: '',
  class_comment: '',
  icon: '',
  sort: 9999,
  pid: 0,
});

// 表列表
const tableList = ref<any[]>([]);
const tableLoading = ref(false);
const searchKeyword = ref('');
const selectedTable = ref<string>('');

// 表结构数据
const tableStructure = ref<CodeGenData | null>(null);
const structureLoading = ref(false);

// 过滤后的表列表
const filteredTableList = computed(() => {
  if (!searchKeyword.value) {
    return tableList.value;
  }
  return tableList.value.filter(
    (table) =>
      table.name.toLowerCase().includes(searchKeyword.value.toLowerCase()) ||
      (table.comment && table.comment.toLowerCase().includes(searchKeyword.value.toLowerCase())),
  );
});

// 加载表列表
const loadTableList = async () => {
  tableLoading.value = true;
  try {
    const res = await getTablesApi();
    tableList.value = res || [];
  } catch (error: any) {
    message.error(error.message || '加载表列表失败');
    tableList.value = [];
  } finally {
    tableLoading.value = false;
  }
};

// 选择表
const handleSelectTable = async (tableName: string) => {
  if (!tableName) {
    selectedTable.value = '';
    tableStructure.value = null;
    formApi.resetFields();
    return;
  }

  selectedTable.value = tableName;
  structureLoading.value = true;

  try {
    // 获取表结构
    const structureRes = await getTableStructureApi(tableName);
    const fields = structureRes || [];

    // 生成类名（从表名转换）
    const prefix = 'nl_';
    let className = tableName.replace(prefix, '');
    className = className
      .split('_')
      .map((word: string) => word.charAt(0).toUpperCase() + word.slice(1))
      .join('');

    // 获取表注释作为中文名称
    const tableInfo = tableList.value.find((t) => t.name === tableName);
    const classComment = tableInfo?.comment || tableName;

    // 构建代码生成数据
    tableStructure.value = {
      class_name: className,
      class_comment: classComment,
      icon: '',
      sort: 9999,
      pid: 0,
      field: fields,
    };

    // 更新表单数据
    formData.value = {
      class_name: className,
      class_comment: classComment,
      icon: '',
      sort: 9999,
      pid: 0,
    };
    formApi.setValues(formData.value);
  } catch (error: any) {
    message.error(error.message || '获取表结构失败');
    tableStructure.value = null;
  } finally {
    structureLoading.value = false;
  }
};

// 生成代码
const handleGenerate = async () => {
  if (!selectedTable.value) {
    message.warning('请先选择数据库表');
    return;
  }

  if (!tableStructure.value) {
    message.warning('表结构数据未加载，请重试');
    return;
  }

  // 验证数据
  const validation = validateData(tableStructure.value);
  if (!validation.valid) {
    message.error(validation.message);
    return;
  }

  // 合并表单数据（用户可能修改了基础信息）
  const formValues = await formApi.getValues();
  const finalData: CodeGenData = {
    ...tableStructure.value,
    class_name: formValues.class_name || tableStructure.value.class_name,
    class_comment: formValues.class_comment || tableStructure.value.class_comment,
    icon: formValues.icon || tableStructure.value.icon,
    sort: formValues.sort ?? tableStructure.value.sort,
    pid: formValues.pid ?? tableStructure.value.pid,
  };

  emit('generate', finalData);
};

// 表列配置
const tableColumns = [
  {
    title: '表名',
    dataIndex: 'name',
    key: 'name',
  },
  {
    title: '注释',
    dataIndex: 'comment',
    key: 'comment',
  },
  {
    title: '记录数',
    dataIndex: 'rows',
    key: 'rows',
    width: 100,
  },
];

onMounted(() => {
  loadTableList();
});
</script>

<template>
  <div class="database-select">
    <!-- 顶部操作栏 -->
    <Card class="mb-4">
      <template #title>
        <div class="flex items-center gap-2">
          <Button type="text" @click="emit('back')">
            <svg
              class="mr-2 inline-block"
              width="14"
              height="14"
              viewBox="0 0 14 14"
              fill="none"
              xmlns="http://www.w3.org/2000/svg"
            >
              <path
                d="M8.75 3.5L5.25 7L8.75 10.5"
                stroke="currentColor"
                stroke-width="1.5"
                stroke-linecap="round"
                stroke-linejoin="round"
              />
            </svg>
            返回
          </Button>
          <span class="text-lg font-semibold">数据库表模式</span>
        </div>
      </template>

      <div class="mb-4">
        <Input
          v-model:value="searchKeyword"
          placeholder="搜索表名或注释..."
          allow-clear
          class="mb-4"
        >
          <template #prefix>
            <i class="fa-solid fa-search"></i>
          </template>
        </Input>

        <div class="mb-4">
          <div class="mb-2 text-sm text-gray-600 dark:text-gray-400">
            选择数据库表：
          </div>
          <Select
            v-model:value="selectedTable"
            placeholder="请选择数据库表"
            show-search
            :filter-option="false"
            style="width: 100%"
            :loading="tableLoading"
            @change="handleSelectTable"
          >
            <Select.Option
              v-for="table in filteredTableList"
              :key="table.name"
              :value="table.name"
            >
              <div class="flex items-center justify-between">
                <span>{{ table.name }}</span>
                <span class="ml-2 text-xs text-gray-400">
                  {{ table.comment || '-' }}
                </span>
              </div>
            </Select.Option>
          </Select>
        </div>

        <div v-if="selectedTable" class="rounded-lg bg-blue-50 p-3 text-sm text-blue-700 dark:bg-blue-900/20 dark:text-blue-400">
          <i class="fa-solid fa-info-circle mr-2"></i>
          已选择表：<strong>{{ selectedTable }}</strong>
          <span v-if="tableStructure">
            ，共 {{ tableStructure.field?.length || 0 }} 个字段
          </span>
        </div>
      </div>
    </Card>

    <!-- 内容区域 -->
    <div v-if="tableStructure" class="content-area mb-24 grid grid-cols-1 gap-4 lg:grid-cols-2">
      <Card title="基础信息" class="shadow-sm">
        <Form />
      </Card>

      <Card title="字段预览" class="shadow-sm">
        <div v-if="structureLoading" class="flex h-64 items-center justify-center">
          <div class="text-center">
            <i class="fa-solid fa-spinner fa-spin text-2xl text-primary mb-2"></i>
            <p class="text-sm text-gray-500 dark:text-gray-400">加载表结构中...</p>
          </div>
        </div>
        <div v-else class="max-h-[500px] overflow-auto">
          <Table
            :columns="[
              { title: '字段名', dataIndex: 'name', key: 'name' },
              { title: '类型', dataIndex: 'type', key: 'type' },
              { title: '长度', dataIndex: 'type_length', key: 'type_length' },
              { title: '注释', dataIndex: 'comment', key: 'comment' },
              { title: '必填', dataIndex: 'not_null', key: 'not_null', customRender: (text: any) => text ? '是' : '否' },
            ]"
            :data-source="tableStructure.field"
            :pagination="false"
            size="small"
          />
        </div>
        <div class="mt-4 flex items-center gap-2 text-sm text-gray-500">
          <i class="fa-solid fa-list mr-1"></i>
          <span>共 {{ tableStructure.field?.length || 0 }} 个字段</span>
        </div>
      </Card>
    </div>

    <!-- 固定底部操作栏 -->
    <div class="fixed-bottom-bar">
      <div class="fixed-bottom-bar-wrapper">
        <div class="fixed-bottom-bar-content">
          <!-- 左侧状态信息 -->
          <div class="flex items-center gap-3">
            <div
              class="flex h-10 w-10 items-center justify-center rounded-full transition-all"
              :class="
                tableStructure
                  ? 'bg-primary/10 text-primary'
                  : 'bg-gray-100 text-gray-400 dark:bg-gray-800 dark:text-gray-600'
              "
            >
              <i
                :class="tableStructure ? 'fa-solid fa-check-circle' : 'fa-solid fa-circle-info'"
              ></i>
            </div>
            <div>
              <div
                class="text-sm font-medium"
                :class="
                  tableStructure
                    ? 'text-gray-900 dark:text-gray-100'
                    : 'text-gray-500 dark:text-gray-400'
                "
              >
                <span v-if="tableStructure">
                  已加载 <span class="text-primary font-semibold">{{ tableStructure.field?.length || 0 }}</span> 个字段
                </span>
                <span v-else>请先选择数据库表</span>
              </div>
              <div class="text-xs text-gray-400 dark:text-gray-500">
                {{ tableStructure ? '数据已就绪，可以生成代码' : '等待选择表...' }}
              </div>
            </div>
          </div>

          <!-- 右侧操作按钮 -->
          <div class="flex items-center gap-2">
            <Button
              type="primary"
              size="large"
              class="action-btn-primary"
              :disabled="!tableStructure"
              @click="handleGenerate"
            >
              <i class="fa-solid fa-code mr-2"></i>生成代码
            </Button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.database-select {
  animation: fade-slide-enter 0.3s ease-out;
  padding-bottom: 120px;
}

.content-area {
  min-height: 400px;
}

/* 固定底部操作栏 */
.fixed-bottom-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 100;
  padding: 0 24px 24px;
  pointer-events: none;
}

.fixed-bottom-bar-wrapper {
  max-width: 1400px;
  margin: 0 auto;
  background: rgba(255, 255, 255, 0.98);
  backdrop-filter: blur(20px) saturate(180%);
  border: 1px solid rgba(0, 0, 0, 0.08);
  border-radius: 16px;
  box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.08), 0 0 0 1px rgba(0, 0, 0, 0.04);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  pointer-events: all;
}

.dark .fixed-bottom-bar-wrapper {
  background: rgba(31, 41, 55, 0.98);
  border-color: rgba(255, 255, 255, 0.12);
  box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.08);
}

.fixed-bottom-bar-content {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px 24px;
  gap: 24px;
}

.action-btn-primary {
  border-radius: 8px;
  font-weight: 600;
  padding: 0 24px;
  height: 44px;
  box-shadow: 0 4px 12px rgba(24, 144, 255, 0.3);
  transition: all 0.2s ease;
}

.action-btn-primary:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(24, 144, 255, 0.4);
}

@keyframes fade-slide-enter {
  from {
    opacity: 0;
    transform: translateX(-20px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}
</style>
