<script lang="ts" setup>
import { reactive } from 'vue';

import { Card, Checkbox, Col, Input, Row, Select, Tree } from 'ant-design-vue';

import { DatabaseApi, QueryApi } from '#/api';
import { connectTypeOptions } from '#/api/model';

const state = reactive<{
  checkedKeys: string[];
  configId: string;
  dbTableList: DatabaseApi.DbTableItem[];
  dbTables: Record<string, any>[];
  mainTable: Record<string, any>;
}>({
  configId: '',
  dbTableList: [],
  dbTables: [],
  checkedKeys: [],
  mainTable: {},
});
const stepValidate = async () => {
  return true;
};

const handelSelect = async (
  checkedKeys: string[],
  { checked, node }: { checked: boolean; node: Record<string, any> },
) => {
  state.checkedKeys = checkedKeys;
  if (checked) {
    const table: Record<string, any> = {
      remark: node.description,
      name: node.name,
      alias: node.entityName,
      isMain: node.isMain ?? state.dbTables.length === 0,
      columns: [],
      columnKeys: [],
      connectType: node.connectType ?? 1,
      connectColumn: node.connectColumn || 'id',
      relationColumn: node.relationColumn ?? 'id',
    };

    const columns = await DatabaseApi.getColumnList(table.name, state.configId);

    table.columns = columns.map((item) => {
      return {
        name: item.columnName,
        remark: item.description,
        tableAlias: '',
        alias: item.entityName,
      };
    });
    if (table.isMain) {
      state.mainTable = { ...table };
    }
    state.dbTables.push(table);
  } else {
    const index = state.dbTables.findIndex((item) => item.name === node.name);
    if (index !== -1) {
      state.dbTables.splice(index, 1);
    }
  }
};

const handelMainChange = ({ target }: { target: any }) => {
  if (target.checked) {
    state.dbTables.map((item) => (item.isMain = item.name === target.value));
    const item = state.dbTables.find((item) => item.name === target.value);
    if (item) {
      state.mainTable = { ...item };
    }
  } else {
    state.mainTable = {} as QueryApi.Tables;
  }
};

const stepSetValues = async (data: Record<string, any>) => {
  if (state.configId !== data.configId) {
    state.configId = data.configId;
    state.dbTableList = await DatabaseApi.getList(state.configId);
  }
  state.dbTables = [];
  if (data.tables && data.columns) {
    data.tables.forEach(async (item: any) => {
      state.checkedKeys.push(item.name);

      const filter = state.dbTableList.find((row) => row.name === item.name);

      await handelSelect(state.checkedKeys, {
        checked: true,
        node: {
          description: filter ? filter.description : item.name,
          name: item.name,
          entityName: item.alias,
          isMain: item.isMain,
          connectType: item.connectType,
          connectColumn: item.connectColumn,
          relationColumn: item.relationColumn,
        },
      });

      const lastTable: any = state.dbTables[state.dbTables.length - 1];

      const columns = data.columns.filter(
        (row: any) => row.tableAlias === item.alias,
      );
      columns.forEach((column: any) => {
        lastTable.columnKeys.push(column.name);
        const filterColumn = lastTable.columns.find(
          (row: any) => row.name === column.name,
        );
        if (filterColumn) {
          filterColumn.alias = column.alias;
        }
      });
    });
  }
};

const stepGetValues = async () => {
  const tables: Record<string, any>[] = [];
  const columns: Record<string, any>[] = [];
  if (!state.mainTable.name) throw new Error('请选择主表');

  state.dbTables.forEach((table) => {
    tables.push({
      name: table.name,
      alias: table.alias,
      isMain: table.isMain,
      connectTable: state.mainTable.alias,
      connectType: table.connectType,
      connectColumn: table.connectColumn,
      relationColumn: table.relationColumn,
    });
    if (table.columnKeys.length === 0 && !state.mainTable.id)
      throw new Error(`请选择表[${table.remark}]显示的列`);

    table.columnKeys.forEach((key: any) => {
      const filterColumn = table.columns.find((row: any) => row.name === key);
      if (filterColumn) {
        columns.push({
          tableAlias: table.alias,
          name: filterColumn.name,
          alias: filterColumn.alias,
          remark: filterColumn.remark,
        });
      }
    });
  });

  if (tables.length === 0) throw new Error(`请选择表查询的表`);
  if (columns.length === 0) throw new Error(`请选择显示的例`);

  return { tables, columns };
};

defineExpose({ stepSetValues, stepValidate, stepGetValues });
</script>
<template>
  <div class="auto-h flex">
    <div class="w-1/5">
      <Tree
        v-model:checked-keys="state.checkedKeys"
        :field-names="{ key: 'name', title: 'description' }"
        :selectable="false"
        :tree-data="state.dbTableList"
        checkable
        @check="handelSelect"
      />
    </div>
    <div class="ml-4 flex w-4/5 flex-wrap">
      <Card v-for="table in state.dbTables" :key="table.name" class="w-1/2">
        <template #title>
          <div class="mb-2 mt-2">
            <div>{{ table.remark }}</div>
            <div class="mt-[8px]">
              <Input v-model:value="table.alias" placeholder="表别名" />"
            </div>
            <Row v-if="!table.isMain" class="mt-2">
              <Col :span="4">
                <Select
                  v-model:value="table.connectType"
                  :options="connectTypeOptions"
                  style="width: 100%"
                />
              </Col>
              <Col :span="10">
                <Select
                  v-model:value="table.connectColumn"
                  :field-names="{ label: 'remark', value: 'name' }"
                  :options="state.mainTable?.columns"
                  option-filter-prop="remark"
                  show-search
                  style="width: 100%"
                />
              </Col>
              <Col :span="10">
                <Select
                  v-model:value="table.relationColumn"
                  :field-names="{ label: 'remark', value: 'name' }"
                  :options="table.columns"
                  option-filter-prop="remark"
                  show-search
                  style="width: 100%"
                />
              </Col>
            </Row>
          </div>
        </template>
        <template #extra>
          <Checkbox
            v-model:checked="table.isMain"
            :value="table.name"
            class="ml-4"
            @change="handelMainChange"
          >
            主表
          </Checkbox>
        </template>
        <Checkbox.Group v-model:value="table.columnKeys" class="w-full">
          <Row>
            <Col v-for="column in table.columns" :key="column.name" :span="24">
              <Row class="mb-2">
                <Col :span="2">
                  <Checkbox :value="column.name" />
                </Col>
                <Col :span="14">
                  <Input v-model:value="column.remark" placeholder="名称" />
                </Col>
                <Col :span="8">
                  <Input v-model:value="column.alias" placeholder="表别名" />
                </Col>
              </Row>
            </Col>
          </Row>
        </Checkbox.Group>
      </Card>
    </div>
  </div>
</template>
