<template>
  <div class="app-container">
    <el-card v-loading="loading" shadow="never">
      <div slot="header" class="page-header">
        <span>OSS云存储配置</span>
        <el-form :inline="true" size="small" class="tenant-form">
          <el-form-item label="选择租户">
            <el-select
              ref="tenantSelect"
              v-model="selectedTenantId"
              placeholder="请输入租户名称搜索"
              filterable
              remote
              clearable
              :remote-method="handleTenantSearch"
              :loading="tenantSelectLoading"
              style="width: 280px"
              @visible-change="handleTenantDropdownVisible"
              @clear="handleTenantSelectClear"
              @change="loadConfig"
            >
              <el-option
                v-for="item in tenantList"
                :key="item.id"
                :label="formatTenantLabel(item)"
                :value="item.id"
              />
              <el-option v-if="hasMoreTenants" key="tenant-load-more" disabled class="tenant-load-more-option">
                <div class="load-more" @click.stop="loadMoreTenants">
                  <span>加载更多</span>
                  <i v-if="tenantLoadingMore" class="el-icon-loading" />
                </div>
              </el-option>
            </el-select>
          </el-form-item>
        </el-form>
      </div>

      <el-alert
        v-if="!selectedTenantId"
        title="当前为系统默认配置（主库），保存后将更新全局配置；选择租户后可单独配置该租户 OSS 参数"
        type="info"
        :closable="false"
        show-icon
        class="tenant-tip"
      />

      <el-alert
        v-if="selectedTenantId && tenantConfigEmpty"
        title="该租户尚未保存过此配置，可直接填写后保存；如需参考系统默认配置，可点击下方按钮加载（不会自动保存）。"
        type="warning"
        :closable="false"
        show-icon
        class="tenant-tip"
      >
        <el-button type="text" size="small" :loading="fallbackLoading" @click="loadGlobalConfigAsFallback">
          加载系统默认配置
        </el-button>
      </el-alert>

      <el-form ref="form" :model="form" label-width="200px">
        <el-form-item label="类型" prop="type">
          <el-radio-group v-model="form.type">
            <el-radio :label="1">七牛云</el-radio>
            <el-radio :label="2">阿里云</el-radio>
            <el-radio :label="3">腾讯云</el-radio>
            <el-radio :label="4">华为云</el-radio>
          </el-radio-group>
        </el-form-item>

        <!-- 七牛云 -->
        <template v-if="form.type === 1">
          <el-card shadow="never" class="section-card">
            <div slot="header"><span>七牛云配置</span></div>
            <el-form-item label="七牛绑定的域名" prop="qiniuDomain">
              <el-input v-model="form.qiniuDomain" placeholder="请输入七牛绑定的域名"></el-input>
            </el-form-item>
            <el-form-item label="七牛路径前缀" prop="qiniuPrefix">
              <el-input v-model="form.qiniuPrefix" placeholder="请输入七牛路径前缀"></el-input>
            </el-form-item>
            <el-form-item label="七牛ACCESS_KEY" prop="qiniuAccessKey">
              <el-input v-model="form.qiniuAccessKey" placeholder="请输入七牛ACCESS_KEY"></el-input>
            </el-form-item>
            <el-form-item label="七牛SecretKey" prop="qiniuSecretKey">
              <el-input v-model="form.qiniuSecretKey" placeholder="请输入七牛SecretKey"></el-input>
            </el-form-item>
            <el-form-item label="七牛空间名" prop="qiniuBucketName">
              <el-input v-model="form.qiniuBucketName" placeholder="请输入七牛空间名"></el-input>
            </el-form-item>
          </el-card>
        </template>

        <!-- 阿里云 -->
        <template v-if="form.type === 2">
          <el-card shadow="never" class="section-card">
            <div slot="header"><span>阿里云配置</span></div>
            <el-form-item label="阿里云绑定的域名" prop="aliyunDomain">
              <el-input v-model="form.aliyunDomain" placeholder="请输入阿里云绑定的域名"></el-input>
            </el-form-item>
            <el-form-item label="阿里云路径前缀" prop="aliyunPrefix">
              <el-input v-model="form.aliyunPrefix" placeholder="请输入阿里云路径前缀"></el-input>
            </el-form-item>
            <el-form-item label="阿里云EndPoint" prop="aliyunEndPoint">
              <el-input v-model="form.aliyunEndPoint" placeholder="请输入阿里云EndPoint"></el-input>
            </el-form-item>
            <el-form-item label="阿里云AccessKeyId" prop="aliyunAccessKeyId">
              <el-input v-model="form.aliyunAccessKeyId" placeholder="请输入阿里云AccessKeyId"></el-input>
            </el-form-item>
            <el-form-item label="阿里云AccessKeySecret" prop="aliyunAccessKeySecret">
              <el-input v-model="form.aliyunAccessKeySecret" placeholder="请输入阿里云AccessKeySecret"></el-input>
            </el-form-item>
            <el-form-item label="阿里云BucketName" prop="aliyunBucketName">
              <el-input v-model="form.aliyunBucketName" placeholder="请输入阿里云BucketName"></el-input>
            </el-form-item>
          </el-card>
        </template>

        <!-- 腾讯云 -->
        <template v-if="form.type === 3">
          <el-card shadow="never" class="section-card">
            <div slot="header"><span>腾讯云配置</span></div>
            <el-form-item label="腾讯云绑定的域名" prop="qcloudDomain">
              <el-input v-model="form.qcloudDomain" placeholder="请输入腾讯云绑定的域名"></el-input>
            </el-form-item>
            <el-form-item label="腾讯云前缀" prop="qcloudPrefix">
              <el-input v-model="form.qcloudPrefix" placeholder="请输入腾讯云前缀"></el-input>
            </el-form-item>
            <el-form-item label="腾讯云SecretId" prop="qcloudSecretId">
              <el-input v-model="form.qcloudSecretId" placeholder="请输入腾讯云SecretId"></el-input>
            </el-form-item>
            <el-form-item label="腾讯云SecretKey" prop="qcloudSecretKey">
              <el-input v-model="form.qcloudSecretKey" placeholder="请输入腾讯云SecretKey"></el-input>
            </el-form-item>
            <el-form-item label="腾讯云BucketName" prop="qcloudBucketName">
              <el-input v-model="form.qcloudBucketName" placeholder="请输入腾讯云BucketName"></el-input>
            </el-form-item>
            <el-form-item label="所属地区" prop="qcloudRegion">
              <el-input v-model="form.qcloudRegion" placeholder="请输入所属地区"></el-input>
            </el-form-item>
          </el-card>
        </template>

        <!-- 华为云 -->
        <template v-if="form.type === 4">
          <el-card shadow="never" class="section-card">
            <div slot="header"><span>华为云配置</span></div>
            <el-form-item label="华为云绑定的域名" prop="huaweiDomain">
              <el-input v-model="form.huaweiDomain" placeholder="请输入华为云绑定的域名"></el-input>
            </el-form-item>
            <el-form-item label="华为云Endpoint" prop="huaweiEndpoint">
              <el-input v-model="form.huaweiEndpoint" placeholder="请输入华为云Endpoint"></el-input>
            </el-form-item>
            <el-form-item label="华为云AK" prop="huaweiAK">
              <el-input v-model="form.huaweiAK" placeholder="请输入华为云AK"></el-input>
            </el-form-item>
            <el-form-item label="华为云SK" prop="huaweiSK">
              <el-input v-model="form.huaweiSK" placeholder="请输入华为云SK"></el-input>
            </el-form-item>
            <el-form-item label="华为云BucketName" prop="huaweiBucketName">
              <el-input v-model="form.huaweiBucketName" placeholder="请输入华为云BucketName"></el-input>
            </el-form-item>
          </el-card>
        </template>
      </el-form>

      <div style="text-align: center; margin-top: 20px; padding-bottom: 20px;">
        <el-button type="primary" size="medium" @click="submitForm" :loading="submitLoading">保存配置</el-button>
      </div>
    </el-card>
  </div>
</template>

<script>
import { getConfigByKey, updateConfigByKey } from '@/api/system/config'
import { listAdminTenantList } from '@/api/admin/sysCompany'

function defaultOssForm() {
  return {
    type: 1,
    qiniuDomain: '',
    qiniuPrefix: '',
    qiniuAccessKey: '',
    qiniuSecretKey: '',
    qiniuBucketName: '',
    aliyunDomain: '',
    aliyunPrefix: '',
    aliyunEndPoint: '',
    aliyunAccessKeyId: '',
    aliyunAccessKeySecret: '',
    aliyunBucketName: '',
    qcloudDomain: '',
    qcloudPrefix: '',
    qcloudSecretId: '',
    qcloudSecretKey: '',
    qcloudBucketName: '',
    qcloudRegion: '',
    huaweiDomain: '',
    huaweiEndpoint: '',
    huaweiAK: '',
    huaweiSK: '',
    huaweiBucketName: ''
  }
}

function mergeOssForm(parsed) {
  return { ...defaultOssForm(), ...(parsed || {}) }
}

export default {
  name: 'AdminOssConfig',
  data() {
    return {
      loading: false,
      submitLoading: false,
      configId: null,
      configKey: 'sys.oss.cloudStorage',
      selectedTenantId: null,
      tenantConfigEmpty: false,
      fallbackLoading: false,
      tenantList: [],
      tenantTotal: 0,
      hasMoreTenants: false,
      tenantSelectLoading: false,
      tenantLoadingMore: false,
      tenantQueryParams: {
        pageNum: 1,
        pageSize: 20,
        tenantName: '',
        status: 1
      },
      form: defaultOssForm(),
      tenantSearchTimer: null,
      tenantSelectInputEl: null,
      tenantSelectInputHandler: null
    }
  },
  mounted() {
    this.loadConfig()
  },
  beforeDestroy() {
    this.unbindTenantSelectInputListener()
  },
  methods: {
    formatTenantLabel(item) {
      if (item.tenantCode) {
        return `${item.tenantName}（${item.tenantCode}）`
      }
      return item.tenantName
    },
    handleTenantSearch(query) {
      if (query === undefined) return
      this.tenantQueryParams.tenantName = (query || '').trim()
      this.tenantQueryParams.pageNum = 1
      this.fetchTenantList()
    },
    handleTenantSelectClear() {
      this.handleTenantSearch('')
    },
    getTenantSelectInputEl() {
      const root = this.$refs.tenantSelect && this.$refs.tenantSelect.$el
      return root ? root.querySelector('input.el-input__inner') : null
    },
    bindTenantSelectInputListener() {
      this.unbindTenantSelectInputListener()
      const input = this.getTenantSelectInputEl()
      if (!input) return
      this.tenantSelectInputEl = input
      this.tenantSelectInputHandler = () => {
        const val = (input.value || '').trim()
        if (!val && this.tenantQueryParams.tenantName) {
          if (this.tenantSearchTimer) clearTimeout(this.tenantSearchTimer)
          this.tenantSearchTimer = setTimeout(() => {
            this.handleTenantSearch('')
          }, 150)
        }
      }
      input.addEventListener('input', this.tenantSelectInputHandler)
    },
    unbindTenantSelectInputListener() {
      if (this.tenantSearchTimer) {
        clearTimeout(this.tenantSearchTimer)
        this.tenantSearchTimer = null
      }
      if (this.tenantSelectInputEl && this.tenantSelectInputHandler) {
        this.tenantSelectInputEl.removeEventListener('input', this.tenantSelectInputHandler)
      }
      this.tenantSelectInputEl = null
      this.tenantSelectInputHandler = null
    },
    syncTenantSearchFromInput() {
      const input = this.getTenantSelectInputEl()
      const inputVal = input ? (input.value || '').trim() : ''
      if (!inputVal && this.tenantQueryParams.tenantName) {
        this.handleTenantSearch('')
      }
    },
    handleTenantDropdownVisible(visible) {
      if (visible) {
        if (this.tenantList.length === 0) {
          this.handleTenantSearch('')
        }
        this.$nextTick(() => {
          this.syncTenantSearchFromInput()
          this.bindTenantSelectInputListener()
        })
      } else {
        this.unbindTenantSelectInputListener()
      }
    },
    fetchTenantList(isLoadMore = false) {
      if (!isLoadMore) {
        this.tenantSelectLoading = true
      } else {
        this.tenantLoadingMore = true
      }
      listAdminTenantList(this.tenantQueryParams).then(response => {
        const rows = response.rows || []
        if (isLoadMore) {
          const existIds = new Set(this.tenantList.map(t => t.id))
          const append = rows.filter(r => !existIds.has(r.id))
          this.tenantList = this.tenantList.concat(append)
        } else {
          this.tenantList = rows
        }
        this.tenantTotal = response.total || 0
        this.hasMoreTenants = this.tenantList.length < this.tenantTotal
      }).finally(() => {
        this.tenantSelectLoading = false
        this.tenantLoadingMore = false
      })
    },
    loadMoreTenants() {
      if (this.tenantLoadingMore || !this.hasMoreTenants) return
      this.tenantQueryParams.pageNum += 1
      this.fetchTenantList(true)
    },
    loadConfig() {
      this.loading = true
      this.tenantConfigEmpty = false
      const tenantId = this.selectedTenantId || undefined
      getConfigByKey(this.configKey, tenantId).then(response => {
        const data = response.data
        if (data) {
          this.configId = data.configId != null ? data.configId : null
          const configValue = data.configValue
          if (configValue !== null && configValue !== undefined && configValue !== '' && configValue !== 'null') {
            try {
              this.form = mergeOssForm(JSON.parse(configValue))
              this.tenantConfigEmpty = false
            } catch (e) {
              this.form = defaultOssForm()
              this.tenantConfigEmpty = !!this.selectedTenantId
            }
          } else {
            this.form = defaultOssForm()
            this.tenantConfigEmpty = !!this.selectedTenantId
          }
        } else {
          this.configId = null
          this.form = defaultOssForm()
          this.tenantConfigEmpty = !!this.selectedTenantId
        }
      }).finally(() => {
        this.loading = false
      })
    },
    loadGlobalConfigAsFallback() {
      this.fallbackLoading = true
      getConfigByKey(this.configKey).then(response => {
        if (!response.data || !response.data.configValue) {
          this.msgWarning('系统默认配置为空')
          return
        }
        try {
          this.form = mergeOssForm(JSON.parse(response.data.configValue))
          this.msgSuccess('已加载系统默认配置，保存时将写入当前租户')
        } catch (e) {
          this.msgWarning('系统默认配置解析失败')
        }
      }).finally(() => {
        this.fallbackLoading = false
      })
    },
    submitForm() {
      this.$refs['form'].validate(valid => {
        if (!valid) return
        this.submitLoading = true
        const param = {
          configId: (this.configId != null && this.configId !== '') ? Number(this.configId) : null,
          configName: 'OSS云存储配置',
          configKey: this.configKey,
          configValue: JSON.stringify(this.form),
          tenantId: this.selectedTenantId ? String(this.selectedTenantId) : null
        }
        updateConfigByKey(param).then(response => {
          if (response.code === 200) {
            this.msgSuccess('修改成功')
            this.loadConfig()
          }
        }).finally(() => {
          this.submitLoading = false
        })
      })
    }
  }
}
</script>

<style scoped>
.section-card {
  margin-bottom: 20px;
}

.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
}

.tenant-form {
  margin-bottom: 0;
}

.tenant-form >>> .el-form-item {
  margin-bottom: 0;
}

.tenant-tip {
  margin-bottom: 16px;
}

.tenant-load-more-option {
  text-align: center;
  padding: 8px 0;
}

.load-more {
  color: #409eff;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
}

.load-more:hover {
  color: #66b1ff;
}
</style>
