<template>
  <div class="db">
    <v-card class="db-box d-flex flex-column" elevation="5" v-loading="loadingUpload">
      <v-banner single-line>
        <div class="d-flex align-center">
          <div class="pa-2 title">文件解析</div>
          <v-spacer></v-spacer>
          <UploadBtn
            text
            color="primary"
            accept=".sql,.docx,.xls,.xlsx,.pdf"
            @change="handleChangeFile"
          >
            <v-icon left>mdi-import</v-icon>
            导入文件
          </UploadBtn>
        </div>
      </v-banner>
      <div v-if="fileType" style="height: 100%;">
        <ParseData
          v-if="!showSourcePreview"
          :items="items"
          :origin="origin"
          :select="select"
          @select="handleSelect"
          @viewSource="handleViewSource"
        ></ParseData>
        <!-- 文件预览 -->
        <SourceFilePreview
          v-else
          :file="file"
          :file-type="fileType"
          :file-url="itemData?.url"
          @viewParsedData="handleViewParsedData"
        ></SourceFilePreview>
      </div>
      <NonePage v-else />
    </v-card>

    <v-card class="db-box d-flex flex-column" elevation="5">
      <div>
        <v-tabs v-model="tab">
          <v-tab>元数据设置</v-tab>
          <v-tab>基础信息配置</v-tab>
        </v-tabs>
      </div>
      <v-divider></v-divider>
      <v-tabs-items v-model="tab">
        <v-tab-item>
          <edit-selected
            style="position: relative;height: 100%;"
            ref="selected"
            v-model="selectModel"
            v-loading="loading"
          >
          </edit-selected>
        </v-tab-item>
        <v-tab-item>
          <div class="pa-3 d-flex align-center justify-center flex-column">
            <edit-base ref="base" style="max-width: 500px;" :names="names" :item-data="itemData"></edit-base>
            <v-btn
              class="buttons"
              rounded
              color="primary"
              :disabled="loading"
              @click="handleSubmit"
            >
              <v-icon left>mdi-send-variant</v-icon>
              保存
            </v-btn>
          </div>
        </v-tab-item>
      </v-tabs-items>
    </v-card>

    <v-overlay :value="overlay" z-index="9">
      <div class="d-flex flex-column align-center justify-center" style="width: 300px;">
        <div class="mb-3">正在提交</div>
        <v-progress-linear
          color="primary"
          indeterminate
          rounded
          height="6"
        ></v-progress-linear>
      </div>
    </v-overlay>
  </div>
</template>

<script>
import EditSelected from './editSelected'
import UploadBtn from '@/components/UploadBtn'
import EditBase from './editBase'
import ParseData from './parseData.vue'
import SourceFilePreview from './SourceFilePreview.vue'
import NonePage from '@/components/Common/empty.vue'

import { api } from '@/api/dataGovernance'
export default {
  name: 'database-connect',
  components: {
    UploadBtn,
    EditSelected,
    EditBase,
    ParseData,
    SourceFilePreview,
    NonePage
  },
  props: {
    itemData: {
      type: Object,
      default: () => ({})
    }
  },
  data () {
    return {
      items: {},
      origin: {},
      tab: 0,
      names: {},
      fileType: null,
      loading: false,
      loadingUpload: false,
      select: null,
      overlay: false,
      selectModel: null,
      file: null,
      showSourcePreview: false // 是否显示源文件预览
    }
  },
  created () {
    if (!Object.keys(this.itemData).length) {
      return
    }
    this.fileType = this.itemData.type
    this.selectModel = this.itemData.parsed_data.map(e => {
      return {
        map: e,
        text: e.name_zh
      }
    })
    this.select = this.itemData.name_zh
    this.names = {
      name_zh: this.itemData.name_zh,
      name_en: this.itemData.name_en
    }
    // 有url时，下载文件
    if (this.itemData?.url) {
      this.getFile(this.itemData.url)
    }
  },
  methods: {
    // 文件下载，用于编辑时下载文件
    async getFile (url) {
      try {
        const { data } = await api.downloadFile({ url })
        // 从 URL 中提取文件名
        const fileName = url.split('/').pop() || 'file'
        // 根据文件类型设置 MIME 类型
        const mimeTypes = {
          pdf: 'application/pdf',
          docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
          xls: 'application/vnd.ms-excel',
          xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
          sql: 'text/plain'
          // txt: 'text/plain'
        }
        const mimeType = mimeTypes[this.fileType] || 'application/octet-stream'
        this.file = new File([data], fileName, { type: mimeType })

        // 编辑需要展示解析数据时调用
        // await this.handleChangeFile(this.file)
      } catch (error) {
        this.$snackbar.error(error)
      }
    },
    handleViewSource () {
      this.showSourcePreview = true
    },
    handleViewParsedData () {
      this.showSourcePreview = false
    },
    // 文件解析处理
    async handleChangeFile (file) {
      if (!file) {
        return
      }

      // 获取文件扩展名
      const fileName = file.name || ''
      const fileExt = fileName.split('.').pop()?.toLowerCase()

      // 验证文件类型
      const allowedTypes = ['sql', 'docx', 'xls', 'xlsx', 'pdf']
      if (!fileExt || !allowedTypes.includes(fileExt)) {
        this.$snackbar.warning('只支持上传 sql、docx、xls、xlsx、pdf 类型的文件')
        return
      }

      this.file = file
      this.fileType = fileExt

      this.loadingUpload = true
      const query = new FormData()
      query.append('file', file)
      try {
        const { data } = await api.parseDDLFile(query)
        this.items = data.reduce((res, item) => {
          const { columns, exist, table_info: tableInfo } = item
          const key = tableInfo.name_zh || tableInfo.name_en
          res[key] = {
            exist,
            table_info: tableInfo,
            meta: columns.map(e => {
              return {
                text: e.name_zh,
                map: e
              }
            })
          }
          return res
        }, {})
        this.origin = { ...this.items }
      } catch (error) {
        this.$snackbar.error(error)
      } finally {
        this.loadingUpload = false
      }
    },
    // 使用该数据源
    handleSelect (item, key) {
      this.select = key
      this.selectModel = item.meta
      this.names = {
        name_zh: item.table_info?.name_zh,
        name_en: item.table_info?.name_en
      }
    },

    async handleSubmit () {
      if (!this.selectModel || !this.selectModel.length) {
        this.$snackbar.error('请先选择数据资源')
        return
      }
      try {
        const obj = this.$refs.base.getValue()
        if (!obj) {
          return
        }

        const params = {
          ...obj,
          type: this.fileType
        }
        // 有id时，更新
        if (this.itemData.id) {
          params.id = this.itemData.id
        }
        // 上传文件
        if (this.file) {
          const { data } = await api.uploadFile({ file: this.file })
          params.url = data.url // 文件上传路径
        }

        // 如果有解析数据，添加 parsed_data
        if (this.selectModel && this.selectModel.length) {
          params.parsed_data = this.selectModel.map(e => {
            return e.map
          })
        }

        this.overlay = true
        const submitApi = this.itemData.id ? api.updateBusinessDomain : api.saveBusinessDomain
        await submitApi(params)
        this.$snackbar.success('保存成功')
        this.$emit('close')
      } catch (error) {
        this.$snackbar.error(error?.message || error)
      } finally {
        this.overlay = false
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.db {
  width: 100%;
  height: 100%;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-gap: 15px;
  &-box {
    height: 100%;
    overflow: hidden;
  }
}
.title {
  color: #1976D2;
  font-weight: 600;
}
::v-deep .v-tabs-items {
  height: 0;
  flex: 1;
  .v-window-item {
    overflow: auto;
    height: 100%;
  }
  .v-window__container {
    height: 100%;
  }
}
::v-deep .v-banner--single-line .v-banner__wrapper {
  padding: 0 8px 0 0;
}
</style>
