<template>
  <div>
    <el-card style="margin: 8px">
      <el-form :inline="true" :model="selectForm" class="demo-form-inline" label-width="120px">
        <el-form-item label="数据源名称">
          <el-input v-model="selectForm.dataSourceName" clearable />
        </el-form-item>
        <el-form-item label="请求地址">
          <el-input v-model="selectForm.requestUrl" clearable />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="queryList">查询</el-button>
        </el-form-item>
      </el-form>
    </el-card>
    <el-card style="margin: 8px">
      <el-button plain type="primary" icon="Plus" @click="constructionData">新增接口</el-button>
      <el-button plain type="primary" icon="Plus" @click="addSQL">新增SQL</el-button>
      <!--      <el-button plain type="success" icon="Edit" @click="editData">修改</el-button>-->
      <!--      <el-button plain type="danger" icon="Delete" @click="delData">删除</el-button>-->
    </el-card>
    <el-card style="margin: 8px">
      <el-table :data="tableData" style="width: 100%" v-loading="loading">
        <el-table-column prop="dataSourceName" label="数据源名称" align="center" />
        <el-table-column prop="requestMethod" label="请求方式" align="center" />
        <el-table-column prop="requestUrl" label="请求地址" align="center" />
        <el-table-column label="操作" width="300" align="center">
          <template #default="scope">
            <el-button text type="primary" size="small" @click="editDataSource(scope.row)">修改
            </el-button>
            <el-button size="small" type="danger" text @click="delDataSource(scope.row)">删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination class="pagination" v-model:current-page="selectForm.pageNum"
                     v-model:page-size="selectForm.pageSize" :page-sizes="[10, 20, 50, 100]"
                     layout="total, sizes, prev, pager, next, jumper" v-if="total > 0" :total="total"
                     @size-change="pageChange"
                     @current-change="pageChange" />
    </el-card>

    <el-dialog v-model="constructionDataFormVisible" draggable width="800">
      <template #header>
        <div style="width: 100%">
          <span>{{ constructionDataForm.dataSourceId ? '修改' : '构造' }}数据源</span>
          <div style="text-align:right;display: inline-block;width: calc(100% - 100px)">
            <span>简易模式</span>
            <el-switch v-model="isEasy" />
          </div>
        </div>
      </template>
      <el-form :model="constructionDataForm">
        <el-form-item label="数据名称" prop="dataSourceName">
          <el-input v-model="constructionDataForm.dataSourceName" />
        </el-form-item>
        <el-form-item label="请求地址" prop="requestUrl">
          <el-input v-model="constructionDataForm.requestUrl">
            <template #prepend>
              <el-select v-model="constructionDataForm.requestMethod" style="width: 100px">
                <el-option label="get" value="get" />
                <el-option label="post" value="post" />
                <el-option label="socket" value="socket" />
              </el-select>
            </template>
          </el-input>
        </el-form-item>
        <el-form-item label="请求数据" v-if="isEasy">
          <el-table :data="paramsTableData" style="width: 100%">
            <el-table-column label="字段名称" min-width="120">
              <template #default="scope">
                <el-input v-model="scope.row.name" style="width: 100%" />
              </template>
            </el-table-column>
            <el-table-column label="备注" min-width="120">
              <template #default="scope">
                <el-input v-model="scope.row.remark" style="width: 100%" />
              </template>
            </el-table-column>
            <el-table-column label="测试数据" min-width="120">
              <template #default="scope">
                <el-input v-model="scope.row.test" style="width: 100%" />
              </template>
            </el-table-column>
            <el-table-column label="操作" min-width="120">
              <template #default="scope">
                <el-button link size="small" type="primary" @click="paramsTableData.splice(scope.$index, 1)">
                  删除
                </el-button>
              </template>
            </el-table-column>
          </el-table>
          <el-button style="width: 100%" @click="paramsTableData.push({})">
            添加字段
          </el-button>
        </el-form-item>
        <el-form-item label="输出数据">
          <el-table :data="constructionDataForm.designDataFieldList" style="width: 100%">
            <el-table-column label="字段名称" min-width="120">
              <template #default="scope">
                <el-input v-model="scope.row.fieldOne" style="width: 100%" />
              </template>
            </el-table-column>
            <el-table-column v-if="!isEasy" label="字段层级" min-width="120">
              <template #default="scope">
                <el-input v-model="scope.row.fieldTwo" style="width: 100%" />
              </template>
            </el-table-column>
            <el-table-column label="备注" min-width="120">
              <template #default="scope">
                <el-input v-model="scope.row.remark" style="width: 100%" />
              </template>
            </el-table-column>
            <el-table-column label="操作" min-width="120">
              <template #default="scope">
                <el-button link size="small" type="primary"
                           @click="constructionDataForm.designDataFieldList.splice(scope.$index, 1)">
                  删除
                </el-button>
              </template>
            </el-table-column>
          </el-table>
          <el-button style="width: 100%" @click="constructionDataForm.designDataFieldList.push({})">
            添加字段
          </el-button>
          <el-button v-if="isEasy" style="width: 100%;margin: 12px 0 0 0" @click="findTier">
            查找
          </el-button>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="constructionDataFormVisible = false">关闭</el-button>
          <el-button type="primary" @click="createData">
            {{ constructionDataForm.dataSourceId ? '确定' : '创建' }}
          </el-button>
        </div>
      </template>
    </el-dialog>
    <el-dialog v-model="addSQLFormVisible" draggable width="800">
      <template #header>
        <div style="width: 100%">
          <span>{{ addSQLForm.dataSourceId ? '修改' : '构造' }}数据源</span>
        </div>
      </template>
      <el-form :model="addSQLForm" label-width="auto">
        <el-form-item label="数据名称" prop="dataSourceName">
          <el-input v-model="addSQLForm.dataSourceName" />
        </el-form-item>
        <el-form-item label="数据库" prop="db">
          <el-select @change="selectDb" v-model="addSQLForm.db" placeholder="选择数据库" style="width: 240px">
            <el-option v-for="item in dbList" :key="item.value" :label="`${item.linkName}(${item.host}:${item.port})`"
                       :value="item.linkId" />
          </el-select>
        </el-form-item>
        <el-form-item label="是否分页" prop="dataSourceName">
          <el-switch v-model="addSQLForm.isPage" />
        </el-form-item>
        <el-form-item label="输入数据">
          <el-table :data="addSQLForm.testList" style="width: 100%">
            <el-table-column label="字段名称" min-width="120">
              <template #default="scope">
                <el-input v-model="scope.row.fieldOne" style="width: 100%" />
              </template>
            </el-table-column>
            <el-table-column label="测试数据" min-width="120">
              <template #default="scope">
                <el-input v-model="scope.row.fieldTwo" style="width: 100%" />
              </template>
            </el-table-column>
          </el-table>
          <el-button style="width: 100%" @click="addSQLForm.testList.push({})">
            添加字段
          </el-button>
        </el-form-item>
        <el-form-item label="SQL" prop="SQL">
          <el-input v-model="addSQLForm.SQL" style="width: 100%" :rows="2" type="textarea" placeholder="" />
        </el-form-item>
        <!--        <el-form-item label="关键字">-->
        <!--          <el-tag type="success" style="margin-right: 8px;margin-bottom: 8px;" v-for="i in keyword"-->
        <!--                  @click="addSQLInput(i)">{{ i }}-->
        <!--          </el-tag>-->
        <!--        </el-form-item>-->
        <!--        <el-form-item label="表">-->
        <!--          <el-select @change="selectTable" v-model="addSQLForm.table" placeholder="选择表" style="width: 240px">-->
        <!--            <el-option-->
        <!--              v-for="item in tableList"-->
        <!--              :key="item.value"-->
        <!--              :label="item.tableName"-->
        <!--              :value="item.tableName"-->
        <!--            />-->
        <!--          </el-select>-->
        <!--        </el-form-item>-->
        <!--        <el-form-item label="字段">-->
        <!--          <el-tag type="primary" style="margin-right: 8px;margin-bottom: 8px;" @click="addSQLInput(addSQLForm.table)">-->
        <!--            {{ addSQLForm.table }}-->
        <!--          </el-tag>-->
        <!--          <el-tag type="success" style="margin-right: 8px;margin-bottom: 8px;" v-for="i in fieldList"-->
        <!--                  @click="addSQLInput(i.columnName)">{{ i.columnName-->
        <!--            }}-->
        <!--          </el-tag>-->
        <!--        </el-form-item>-->

        <el-form-item label="输出数据">
          <el-table :data="addSQLForm.designDataFieldList" style="width: 100%">
            <el-table-column label="字段名称" min-width="120">
              <template #default="scope">
                <el-input v-model="scope.row.fieldOne" style="width: 100%" />
              </template>
            </el-table-column>
            <el-table-column label="字段层级" min-width="120">
              <template #default="scope">
                <el-input v-model="scope.row.fieldTwo" style="width: 100%" />
              </template>
            </el-table-column>
            <el-table-column label="备注" min-width="120">
              <template #default="scope">
                <el-input v-model="scope.row.remark" style="width: 100%" />
              </template>
            </el-table-column>
            <el-table-column label="操作" min-width="120">
              <template #default="scope">
                <el-button link size="small" type="primary"
                           @click="addSQLForm.designDataFieldList.splice(scope.$index, 1)">
                  删除
                </el-button>
              </template>
            </el-table-column>
          </el-table>
          <el-button style="width: 100%" @click="addSQLForm.designDataFieldList.push({})">
            添加字段
          </el-button>
          <el-button style="width: 100%;margin: 12px 0 0 0" @click="sqlFindTier">
            查找
          </el-button>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="addSQLFormVisible = false">关闭</el-button>
          <el-button type="primary" @click="createSQL">
            {{ addSQLForm.dataSourceId ? '确定' : '创建' }}
          </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
<script lang="ts" setup>
import axios from 'axios';
import request from '@/utils/request';
import { options } from './tool.js';
import {
  addDataSourceApi,
  delDataSourceApi,
  editDataSourceApi,
  getDataSourceList,
  querySql,
  querySql1
} from './api/dataSource';
import { ElMessage, ElMessageBox } from 'element-plus';
import { getDatabaseLink, getFieldList, listDatabaseLink } from '@/views/boardGenerate/api/db';

const comparisonTable = {
  starttime: '开始时间',
  time: '时间',
  value: '值'
};

const isEasy = ref(true);
const loading = ref(false);
const paramsTableData = ref([]);
const selectForm = ref({
  pageNum: 1,
  pageSize: 10
});
const total = ref(0);
const tableData = ref([]);
const constructionDataForm = ref({ designDataFieldList: [] });
const constructionDataFormVisible = ref(false);
const addSQLFormVisible = ref(false);
const addSQLForm = ref({});
const dbList = ref([]);
const tableList = ref([]);
const fieldList = ref([]);
const keyword = ref(['SELECT', 'FROM', 'WHERE', 'GROUP BY', 'HAVING', 'ORDER BY', 'LIMIT', 'TOP', 'DISTINCT', 'AS',
  'INSERT INTO', 'VALUES', 'UPDATE', 'SET', 'DELETE',
  'CREATE', 'DROP', 'ALTER', 'TRUNCATE', 'RENAME',
  'PRIMARY KEY', 'FOREIGN KEY', 'UNIQUE', 'NOT NULL', 'DEFAULT', 'AUTO_INCREMENT', 'CHECK',
  'GRANT', 'REVOKE',
  'BEGIN', 'START TRANSACTION', 'COMMIT', 'ROLLBACK', 'SAVEPOINT',
  'JOIN', 'LEFT JOIN', 'RIGHT JOIN', 'FULL JOIN', 'ON', 'IN', 'EXISTS', 'ANY', 'ALL',
  'CASE', 'WHEN', 'THEN', 'ELSE', 'IS NULL', 'IS NOT NULL', 'LIKE', 'BETWEEN',
  'UNION', 'UNION ALL', 'WITH']);
const getList = async () => {
  loading.value = true;
  getDataSourceList(selectForm.value)
    .then((res) => {
      console.log(res);
      tableData.value = res.rows;
      total.value = res.total;
    })
    .finally(() => {
      loading.value = false;
    });
};
const queryList = async () => {
  selectForm.value.pageNum = 1;
  await getList();
};
const pageChange = () => {
  getList();
};
const constructionData = () => {
  paramsTableData.value = [];
  constructionDataForm.value = { designDataFieldList: [] };
  constructionDataFormVisible.value = true;
};
const addSQL = () => {
  addSQLFormVisible.value = true;
  addSQLForm.value = {
    designDataFieldList: [],
    testList: []
  };
  getDbList();
};
const getDbList = () => {
  listDatabaseLink().then(e => {
    dbList.value = e.rows;
  });
};
const selectDb = (e) => {
  getDatabaseLink(e).then((res) => {
    tableList.value = res.data;
  });
};
const selectTable = () => {
  getFieldList(addSQLForm.value.db, addSQLForm.value.table).then((res) => {
    fieldList.value = res.data;
  });
};
const addSQLInput = (data) => {
  addSQLForm.value.SQL = (addSQLForm.value.SQL || '') + `${data} `;
};

const testSql = () => {
  querySql(addSQLForm.value.SQL, addSQLForm.value.db).then((res) => {
    console.log(res);
  });
};

const createSQL = () => {
  let params = {
    ...addSQLForm.value,
    dataSourceName: addSQLForm.value.dataSourceName,
    activeFlag: '1',
    responseType: '2',
    designDataFieldList: addSQLForm.value.designDataFieldList.map(e => {
      return {
        fieldType: '2',
        activeFlag: '1',
        dataSourceId: addSQLForm.value.dataSourceId,
        fieldOne: e.fieldOne,
        fieldTwo: e.fieldTwo
      };
    }),
    requestUrl: 'system/databaseLink/querySql',
    requestMethod: 'querySql',
    fieldOne: addSQLForm.value.db,
    fieldTwo: addSQLForm.value.SQL,
    fieldThree: addSQLForm.value.isPage
  };
  delete params.SQL;

  if (addSQLForm.value.dataSourceId) {
    editDataSourceApi(params).then(() => {
      addSQLFormVisible.value = false;
      ElMessage({
        type: 'success',
        message: '修改成功'
      });
      getList();
    });
  } else {
    addDataSourceApi(params).then(() => {
      addSQLFormVisible.value = false;
      ElMessage({
        type: 'success',
        message: '创建成功'
      });
      getList();
    });
  }
  // let nowData = JSON.parse(localStorage.getItem('DATANODE') || '[]');
  // nowData.push(constructionDataForm.value);
  // localStorage.setItem('DATANODE', JSON.stringify(nowData));
};

const editData = () => {
  paramsTableData.value = [];
  constructionDataForm.value = { designDataFieldList: [] };
  constructionDataFormVisible.value = true;
};
const delData = () => {
  paramsTableData.value = [];
  constructionDataForm.value = { designDataFieldList: [] };
  constructionDataFormVisible.value = true;
};
const editDataSource = (e) => {
  if (e.responseType === '1' || !e.responseType) {
    constructionDataFormVisible.value = true;
    constructionDataForm.value = e;
  }
  if (e.responseType === '2') {
    addSQLFormVisible.value = true;
    addSQLForm.value = {
      ...e,
      db: parseFloat(e.fieldOne),
      SQL: e.fieldTwo,
      isPage: e.fieldThree === 'true'
    };

    getDbList();
  }
};
const delDataSource = (e) => {
  ElMessageBox.confirm(
    '要删除这条数据源吗?',
    'Warning',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    }
  )
    .then(() => {
      delDataSourceApi(e.dataSourceId).then(() => {
        ElMessage({
          type: 'success',
          message: '删除成功'
        });
        getList();
      });
    })
    .catch(() => {
      ElMessage({
        type: 'info',
        message: '已取消'
      });
    });
};
const createData = () => {
  if (!constructionDataForm.value.designDataFieldList) {
    constructionDataForm.value.designDataFieldList = [];
  }
  let params = JSON.parse(JSON.stringify(constructionDataForm.value));
  params.activeFlag = '1';
  params.responseType = '1';
  params.designDataFieldList = params.designDataFieldList.map(e => {
    return {
      fieldType: '2',
      activeFlag: '1',
      dataSourceId: params.dataSourceId,
      fieldOne: e.fieldOne,
      fieldTwo: e.fieldTwo
    };
  });
  if (constructionDataForm.value.dataSourceId) {
    editDataSourceApi(params).then(() => {
      constructionDataFormVisible.value = false;
      ElMessage({
        type: 'success',
        message: '修改成功'
      });
      getList();
    });
  } else {
    addDataSourceApi(params).then(() => {
      constructionDataFormVisible.value = false;
      ElMessage({
        type: 'success',
        message: '创建成功'
      });
      getList();
    });
  }
  // let nowData = JSON.parse(localStorage.getItem('DATANODE') || '[]');
  // nowData.push(constructionDataForm.value);
  // localStorage.setItem('DATANODE', JSON.stringify(nowData));
};
const findTier = () => {
  constructionDataForm.value.designDataFieldList = [];
  let params = {};
  (paramsTableData.value || []).forEach((item) => {
    params[item.name] = item.test;
  });
  (options.isD ? request : axios.request)({
    method: constructionDataForm.value.requestMethod,
    url: constructionDataForm.value.requestUrl,
    params: constructionDataForm.value.requestMethod === 'get' ? params : '',
    data: constructionDataForm.value.requestMethod === 'post' ? params : ''
  }).then(res => {
    let data = (options.isD ? res : res.data);
    if (data?.data) {
      Object.keys(data.data?.[0]).forEach(key => {
        constructionDataForm.value.designDataFieldList.push({
          fieldOne: key,
          remark: comparisonTable[key],
          fieldTwo: `data,map%${key}`
        });
      });
      constructionDataForm.value.designDataFieldList.push({
        fieldOne: 'data',
        remark: '',
        fieldTwo: `data`
      });
    } else if (data?.rows) {
      console.log(data?.rows);
      Object.keys(data.rows?.[0]).forEach(key => {
        constructionDataForm.value.designDataFieldList.push({
          fieldOne: key,
          remark: comparisonTable[key],
          fieldTwo: `rows,map%${key}`
        });
      });
      constructionDataForm.value.designDataFieldList.push({
        fieldOne: 'rows',
        remark: '',
        fieldTwo: `rows`
      });
    } else {
      let exclude = ['code'];
      Object.keys(data).forEach(key => {
        if (!exclude.includes(key.toLowerCase())) {
          if (typeof data[key] === 'string' || typeof data[key] === 'string') {
            constructionDataForm.value.designDataFieldList.push({
              fieldOne: key,
              remark: comparisonTable[key],
              fieldTwo: `${key}`
            });
          }
        }
      });
    }
  });
};

const formulaFun = (formula) => {
  let data = formula.replace(/\$\{\s*([^}]+?)\s*\}/g, (_, key) => {
    let infos = key.split(',');
    if (infos.length === 1) {
      if (addSQLForm.value.testList.find(e => e.fieldOne === infos[0])) {
        return addSQLForm.value.testList.find(e => e.fieldOne === infos[0])?.fieldTwo || '';
      } else {
        addSQLForm.value.testList.push({
          fieldOne: infos[0],
          fieldTwo: ''
        });
        return '';
      }
    }
    if (infos.length === 2) {
      if (addSQLForm.value.testList.find(e => e.fieldOne === infos[1])) {
        return `AND ${infos[0]} = ${addSQLForm.value.testList.find(e => e.fieldOne === infos[1])?.fieldTwo || ''}`;
      } else {
        addSQLForm.value.testList.push({
          fieldOne: infos[1],
          fieldTwo: ''
        });
        return '';
      }
    }
  });
  return data;
};
const sqlFindTier = () => {
  addSQLForm.value.designDataFieldList = [];
  if (addSQLForm.value.isPage) {
    querySql1({
      sql: formulaFun(addSQLForm.value.SQL.replace(/\n/g, ' ')),
      linkId: addSQLForm.value.db,
      pageSize: 10,
      pageNum: 1
    }).then((res) => {
      let data = res.data || {};
      Object.keys(data.rows?.[0]).forEach(key => {
        addSQLForm.value.designDataFieldList.push({
          fieldOne: key,
          remark: comparisonTable[key],
          fieldTwo: `data,rows,map%${key}`
        });
      });
      addSQLForm.value.designDataFieldList.push({
        fieldOne: 'data',
        remark: '',
        fieldTwo: `data,rows`
      });
      addSQLForm.value.designDataFieldList.push({
        fieldOne: 'total',
        remark: '',
        fieldTwo: `data,total`
      });
    });
  } else {
    querySql(formulaFun(addSQLForm.value.SQL.replace(/\n/g, ' ')), addSQLForm.value.db).then((res) => {
      let data = res;
      if (data?.data) {
        Object.keys(data.data?.[0]).forEach(key => {
          addSQLForm.value.designDataFieldList.push({
            fieldOne: key,
            remark: comparisonTable[key],
            fieldTwo: `data,map%${key}`
          });
        });
        addSQLForm.value.designDataFieldList.push({
          fieldOne: 'data',
          remark: '',
          fieldTwo: `data`
        });
      } else if (data?.rows) {
        Object.keys(data.rows?.[0]).forEach(key => {
          addSQLForm.value.designDataFieldList.push({
            fieldOne: key,
            remark: comparisonTable[key],
            fieldTwo: `rows,map%${key}`
          });
        });
        addSQLForm.value.designDataFieldList.push({
          fieldOne: 'rows',
          remark: '',
          fieldTwo: `rows`
        });
      } else {
        let exclude = ['code'];
        Object.keys(data).forEach(key => {
          if (!exclude.includes(key.toLowerCase())) {
            if (typeof data[key] === 'string' || typeof data[key] === 'string') {
              addSQLForm.value.designDataFieldList.push({
                fieldOne: key,
                remark: comparisonTable[key],
                fieldTwo: `${key}`
              });
            }
          }
        });
      }
    });
  }


};
onMounted(async () => {
  await queryList();
});
</script>
<style lang="less" scoped>
.pagination {
  float: right;
  margin: 12px 0;
}
</style>
