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

import { Delete, EditPen, Search } from '@element-plus/icons-vue';
import {
  ElButton,
  ElEmpty,
  ElIcon,
  ElInput,
  ElTable,
  ElTableColumn,
  ElTag,
} from 'element-plus';

const props = defineProps<{
  managedTables: any[];
  saveTableDescription: (
    tableId: number | string,
    tableDesc: string,
  ) => Promise<any>;
  sourceLabel: string;
  sourceTables: any[];
  sourceUnavailable?: boolean;
}>();

const emit = defineEmits<{
  registerTables: [rows: any[]];
  removeTables: [rows: any[]];
  selectTable: [row: any];
}>();

const tableKeyword = ref('');
const selectedRows = ref<any[]>([]);
const editingTableId = ref<null | number | string>(null);
const editingTableDesc = ref('');
const savingTableId = ref<null | number | string>(null);

const managedTableMap = computed(
  () => new Map(props.managedTables.map((item) => [item.tableName, item])),
);

function compareTableName(a?: string, b?: string) {
  return String(a || '').localeCompare(String(b || ''), 'en', {
    numeric: true,
    sensitivity: 'base',
  });
}

const tableRows = computed(() => {
  const keyword = tableKeyword.value.trim().toLowerCase();
  return props.sourceTables
    .filter((item) => {
      if (!keyword) return true;
      return item.tableName?.toLowerCase().includes(keyword);
    })
    .map((item) => {
      const managedTable = managedTableMap.value.get(item.tableName) || null;
      return {
        ...item,
        managedTable,
        managedTableId: managedTable?.id || null,
        managedStatus: managedTable ? 'MANAGED' : 'UNMANAGED',
      };
    })
    .sort((a, b) => {
      const managedDiff =
        Number(Boolean(b.managedTable)) - Number(Boolean(a.managedTable));
      if (managedDiff !== 0) {
        return managedDiff;
      }
      return compareTableName(a.tableName, b.tableName);
    });
});

const selectedManagedRows = computed(() =>
  selectedRows.value.map((row) => row.managedTable).filter(Boolean),
);

const selectedPendingRows = computed(() =>
  selectedRows.value.filter((row) => !row.managedTable),
);

const canBatchRegister = computed(() => selectedPendingRows.value.length > 0);
const canBatchRemove = computed(() => selectedManagedRows.value.length > 0);

function handleSelectionChange(rows: any[]) {
  selectedRows.value = rows;
}

function handleBatchRegister() {
  emit('registerTables', selectedPendingRows.value);
}

function handleBatchRemove() {
  emit('removeTables', selectedManagedRows.value);
}

function handleOpenDetail(row: any) {
  if (row.managedTable) {
    emit('selectTable', row.managedTable);
  }
}

function startEdit(row: any) {
  if (!row?.managedTable) return;
  editingTableId.value = row.managedTable.id;
  editingTableDesc.value = row.managedTable.tableDesc || '';
}

function cancelEdit() {
  editingTableId.value = null;
  editingTableDesc.value = '';
}

async function handleSaveTableDescription(row: any) {
  if (!row?.managedTable || savingTableId.value) return;
  savingTableId.value = row.managedTable.id;
  try {
    await props.saveTableDescription(
      row.managedTable.id,
      editingTableDesc.value,
    );
    cancelEdit();
  } finally {
    savingTableId.value = null;
  }
}
</script>

<template>
  <div class="table-list-view">
    <div class="view-header">
      <h3 class="view-title">{{ sourceLabel }}</h3>
    </div>

    <div class="view-toolbar">
      <div class="table-search-row">
        <ElInput v-model="tableKeyword" placeholder="搜索表" clearable>
          <template #prefix>
            <ElIcon><Search /></ElIcon>
          </template>
        </ElInput>
      </div>

      <div class="batch-actions">
        <span v-if="selectedRows.length > 0" class="selection-text">
          已选 {{ selectedRows.length }} 项
        </span>
        <ElButton
          size="small"
          :disabled="!canBatchRegister"
          @click="handleBatchRegister"
        >
          批量接入
        </ElButton>
        <ElButton
          size="small"
          :disabled="!canBatchRemove"
          @click="handleBatchRemove"
        >
          批量去除
        </ElButton>
      </div>
    </div>

    <div class="table-scroll-region">
      <ElEmpty
        v-if="sourceTables.length === 0"
        description="当前连接下还没有可浏览的表"
      />
      <ElEmpty v-else-if="tableRows.length === 0" description="没有匹配的表" />
      <ElTable
        v-else
        :data="tableRows"
        height="100%"
        size="small"
        row-key="tableName"
        class="flat-table"
        @selection-change="handleSelectionChange"
      >
        <ElTableColumn type="selection" width="52" />
        <ElTableColumn
          label="名称"
          min-width="360"
          class-name="table-name-column"
        >
          <template #default="{ row }">
            <div class="name-cell">
              <span class="table-name-text">{{ row.tableName }}</span>
              <template v-if="row.managedTable">
                <template v-if="editingTableId === row.managedTable.id">
                  <ElInput
                    v-model="editingTableDesc"
                    size="small"
                    clearable
                    maxlength="200"
                    class="description-input"
                  />
                  <div class="inline-actions">
                    <ElButton
                      link
                      type="primary"
                      size="small"
                      :loading="savingTableId === row.managedTable.id"
                      @click="handleSaveTableDescription(row)"
                    >
                      保存
                    </ElButton>
                    <ElButton
                      link
                      size="small"
                      :disabled="savingTableId === row.managedTable.id"
                      @click="cancelEdit"
                    >
                      取消
                    </ElButton>
                  </div>
                </template>
                <template v-else>
                  <span class="description-inline">{{
                    row.managedTable.tableDesc || ''
                  }}</span>
                  <ElButton
                    class="icon-action icon-action--edit"
                    link
                    size="small"
                    @click="startEdit(row)"
                  >
                    <ElIcon><EditPen /></ElIcon>
                  </ElButton>
                </template>
              </template>
            </div>
          </template>
        </ElTableColumn>
        <ElTableColumn label="状态" width="100">
          <template #default="{ row }">
            <ElTag
              size="small"
              effect="plain"
              :type="row.managedTable ? 'primary' : 'info'"
            >
              {{ row.managedTable ? '已接入' : '未接入' }}
            </ElTag>
          </template>
        </ElTableColumn>
        <ElTableColumn label="操作" width="180" fixed="right">
          <template #default="{ row }">
            <div class="row-actions">
              <ElButton
                v-if="row.managedTable"
                link
                type="primary"
                size="small"
                @click="handleOpenDetail(row)"
              >
                查看
              </ElButton>
              <ElButton
                v-if="row.managedTable"
                class="icon-action icon-action--danger"
                link
                size="small"
                @click="emit('removeTables', [row.managedTable])"
              >
                <ElIcon><Delete /></ElIcon>
              </ElButton>
              <ElButton
                v-else
                link
                type="primary"
                size="small"
                @click="emit('registerTables', [row])"
              >
                接入
              </ElButton>
            </div>
          </template>
        </ElTableColumn>
      </ElTable>
    </div>
  </div>
</template>

<style scoped>
.table-list-view {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: 0 0 0 12px;
  background: transparent;
}

.view-header {
  display: flex;
  gap: 16px;
  align-items: center;
  justify-content: space-between;
  padding: 0 0 4px;
  margin-bottom: 10px;
}

.view-title {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: hsl(var(--text-strong));
}

.view-toolbar {
  display: flex;
  gap: 12px;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}

.table-search-row {
  width: min(320px, 100%);
}

.table-search-row :deep(.el-input__wrapper) {
  min-height: 36px;
}

.batch-actions {
  display: flex;
  gap: 8px;
  align-items: center;
}

.selection-text {
  font-size: 13px;
  color: hsl(var(--text-muted));
}

.table-scroll-region {
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

.flat-table {
  --el-table-bg-color: transparent;
  --el-table-tr-bg-color: transparent;
  --el-table-header-bg-color: hsl(var(--surface-subtle) / 72%);
  --el-table-border-color: hsl(var(--table-row-border) / 70%);
  --el-table-current-row-bg-color: hsl(var(--table-row-hover));
  --el-fill-color-blank: transparent;

  height: 100%;
  overflow: hidden;
  border-radius: 0;
}

.flat-table :deep(.table-name-column .cell) {
  font-size: 14px;
  font-weight: 400;
  color: hsl(var(--text-strong));
}

.name-cell {
  display: flex;
  gap: 8px;
  align-items: center;
  min-width: 0;
}

.table-name-text {
  flex-shrink: 0;
  color: hsl(var(--text-strong));
}

.description-inline {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  color: hsl(var(--text-muted));
  white-space: nowrap;
}

.description-input {
  width: min(320px, 100%);
}

.row-actions {
  display: flex;
  gap: 4px;
  align-items: center;
}

.inline-actions {
  display: flex;
  flex-shrink: 0;
  gap: 4px;
  align-items: center;
}

.icon-action {
  min-width: auto;
  padding: 0 2px;
}

.icon-action :deep(.el-icon) {
  font-size: 15px;
}

.icon-action--edit {
  color: hsl(var(--primary));
}

.icon-action--danger {
  color: hsl(var(--destructive));
}
</style>
