<template>
  <div class="app-container">
    <el-card>
      <div slot="header" class="clearfix">
        <span>金山文档 在线表格</span>
        <el-button style="float: right; padding: 3px 0" type="text" @click="handleRefresh" :loading="loading">刷新</el-button>
      </div>

      <el-alert v-if="!isAuthorized" title="未授权" type="warning" :closable="false" show-icon>
        <template slot="default">
          <span>请完成金山文档开放平台授权（个人云）</span>
          <el-button type="primary" size="small" style="margin-left: 10px" @click="handleAuthorize">立即授权</el-button>
        </template>
      </el-alert>

      <el-alert v-else title="已授权" type="success" :closable="false" show-icon>
        <template slot="default">
          <span>授权状态：正常</span>
        </template>
      </el-alert>

      <el-card v-if="isAuthorized && userInfo" style="margin-top: 20px">
        <div slot="header">用户信息</div>
        <el-descriptions :column="2" border>
          <el-descriptions-item label="open_id">{{ userInfo.user_id || userInfo.open_id || '-' }}</el-descriptions-item>
          <el-descriptions-item label="昵称">{{ userInfo.nickname || userInfo.name || '-' }}</el-descriptions-item>
        </el-descriptions>
      </el-card>

      <el-card v-if="isAuthorized" style="margin-top: 20px">
        <div slot="header">
          <span>文件列表（个人云扁平列表）</span>
          <el-button type="primary" size="small" style="float: right" @click="handleLoadFiles(true)">加载 / 刷新</el-button>
        </div>
        <p v-if="listHint" class="list-hint">{{ listHint }}</p>
        <el-table v-loading="fileListLoading" :data="fileList" border style="width: 100%">
          <el-table-column prop="file_name" label="文件名" min-width="200" />
          <el-table-column prop="file_token" label="file_token" min-width="260" show-overflow-tooltip />
          <el-table-column prop="file_type" label="类型" width="100" />
          <el-table-column label="操作" width="200">
            <template slot-scope="scope">
              <el-button type="success" size="mini" @click="handleEditFile(scope.row)">编辑表格</el-button>
            </template>
          </el-table-column>
        </el-table>
        <div v-if="hasMoreFiles" style="margin-top: 12px">
          <el-button type="default" size="small" :loading="fileListLoading" @click="handleLoadMore">加载更多</el-button>
        </div>
      </el-card>

      <el-dialog title="编辑表格" :visible.sync="editDialogVisible" width="80%" :close-on-click-modal="false">
        <div v-if="currentFile">
          <el-form :inline="true" class="demo-form-inline">
            <el-form-item label="工作表">
              <el-select v-model="currentSheetIdx" placeholder="请选择" @change="handleLoadSheetData">
                <el-option
                  v-for="sheet in sheetList"
                  :key="sheet.sheet_idx + '-' + sheet.name"
                  :label="sheet.name + ' (idx:' + sheet.sheet_idx + ')'"
                  :value="sheet.sheet_idx"
                />
              </el-select>
            </el-form-item>
            <el-form-item label="单元格范围">
              <el-input v-model="cellRange" placeholder="例如：A1:B10" style="width: 200px" />
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="handleLoadSheetData">读取数据</el-button>
              <el-button type="success" @click="handleUpdateCells">保存数据</el-button>
            </el-form-item>
          </el-form>

          <el-table v-loading="sheetDataLoading" :data="sheetData" border style="width: 100%; margin-top: 20px">
            <el-table-column
              v-for="(col, index) in sheetColumns"
              :key="index"
              :prop="'col' + index"
              :label="getColumnLabel(index)"
              min-width="120"
            >
              <template slot-scope="scope">
                <el-input v-model="scope.row['col' + index]" size="small" />
              </template>
            </el-table-column>
          </el-table>
        </div>
      </el-dialog>
    </el-card>
  </div>
</template>

<script>
import {
  getKdocsAuthUrl,
  getKdocsTokenStatus,
  getKdocsUserInfo,
  getKdocsFileList,
  getKdocsSheetList,
  readKdocsCells,
  updateKdocsCells
} from '@/api/jarvis/kdocs'

export default {
  name: 'KdocsCloud',
  data() {
    return {
      loading: false,
      isAuthorized: false,
      userInfo: null,
      userId: 'default_user',
      fileList: [],
      fileListLoading: false,
      listHint: '',
      hasMoreFiles: false,
      nextOffset: null,
      nextFilter: null,
      editDialogVisible: false,
      currentFile: null,
      currentSheetIdx: 0,
      sheetList: [],
      sheetData: [],
      sheetDataLoading: false,
      cellRange: 'A1:Z100',
      sheetColumns: []
    }
  },
  created() {
    this.checkAuthStatus()
  },
  methods: {
    async checkAuthStatus() {
      try {
        const response = await getKdocsTokenStatus(this.userId)
        if (response.code === 200) {
          this.isAuthorized = !!response.data.hasToken
          if (this.isAuthorized) {
            this.loadUserInfo()
          }
        }
      } catch (e) {
        console.error(e)
      }
    },
    async loadUserInfo() {
      try {
        const response = await getKdocsUserInfo(this.userId)
        if (response.code === 200) {
          this.userInfo = response.data
        }
      } catch (e) {
        console.error(e)
      }
    },
    async handleAuthorize() {
      try {
        const response = await getKdocsAuthUrl()
        if (response.code === 200) {
          window.open(response.data, '_blank')
          this.$message.success('请在新窗口完成授权，完成后回到本页刷新')
        }
      } catch (e) {
        this.$message.error(e.msg || e.message || '获取授权地址失败')
      }
    },
    handleRefresh() {
      this.checkAuthStatus()
      if (this.isAuthorized) {
        this.handleLoadFiles(true)
      }
    },
    /** @param {boolean} reset 是否重置游标从第一页拉取 */
    async handleLoadFiles(reset) {
      if (!this.isAuthorized) {
        this.$message.warning('请先授权')
        return
      }
      if (reset) {
        this.nextOffset = null
        this.nextFilter = null
        this.fileList = []
      }
      this.fileListLoading = true
      this.listHint = ''
      try {
        const params = {
          userId: this.userId,
          page: 1,
          pageSize: 50
        }
        if (this.nextOffset != null) {
          params.next_offset = this.nextOffset
        }
        if (this.nextFilter) {
          params.next_filter = this.nextFilter
        }
        const response = await getKdocsFileList(params)
        if (response.code === 200) {
          const chunk = response.data.files || []
          this.fileList = reset ? chunk : this.fileList.concat(chunk)
          this.nextOffset = response.data.next_offset
          this.nextFilter = response.data.next_filter || null
          this.hasMoreFiles = !!response.data.has_more
          this.listHint =
            'file_token 请使用列表中的值（来自文档 open_id）。在线表格工作表请选 sheet_type 为 et 的 sheet；数据表为 db 时需用数据表 API。'
        }
      } catch (e) {
        this.$message.error(e.msg || e.message || '加载失败')
      } finally {
        this.fileListLoading = false
      }
    },
    handleLoadMore() {
      if (!this.hasMoreFiles) return
      this.handleLoadFiles(false)
    },
    async handleEditFile(file) {
      this.currentFile = file
      this.editDialogVisible = true
      try {
        const response = await getKdocsSheetList(this.userId, file.file_token)
        if (response.code === 200) {
          this.sheetList = response.data.sheets || []
          if (this.sheetList.length > 0) {
            const first = this.sheetList[0]
            this.currentSheetIdx = first.sheet_idx != null ? first.sheet_idx : 0
            this.handleLoadSheetData()
          } else {
            this.$message.warning('未获取到工作表列表')
          }
        }
      } catch (e) {
        this.$message.error(e.msg || e.message || '加载工作表失败')
      }
    },
    extractCellValues(payload) {
      if (!payload) return []
      if (Array.isArray(payload.values)) return payload.values
      if (payload.data && Array.isArray(payload.data.values)) return payload.data.values
      return []
    },
    async handleLoadSheetData() {
      if (!this.currentFile) return
      this.sheetDataLoading = true
      try {
        const response = await readKdocsCells({
          userId: this.userId,
          fileToken: this.currentFile.file_token,
          sheetIdx: this.currentSheetIdx,
          range: this.cellRange
        })
        if (response.code === 200) {
          this.processSheetData(this.extractCellValues(response.data))
        }
      } catch (e) {
        this.$message.error(e.msg || e.message || '读取失败')
      } finally {
        this.sheetDataLoading = false
      }
    },
    processSheetData(values) {
      if (!values || values.length === 0) {
        this.sheetData = []
        this.sheetColumns = []
        return
      }
      const maxCols = Math.max(...values.map(row => (row ? row.length : 0)))
      this.sheetColumns = Array.from({ length: maxCols }, (_, i) => i)
      this.sheetData = values.map(row => {
        const rowData = {}
        const r = row || []
        r.forEach((cell, index) => {
          rowData['col' + index] = cell !== null && cell !== undefined ? String(cell) : ''
        })
        for (let i = r.length; i < maxCols; i++) {
          rowData['col' + i] = ''
        }
        return rowData
      })
    },
    getColumnLabel(index) {
      let label = ''
      let num = index
      while (num >= 0) {
        label = String.fromCharCode(65 + (num % 26)) + label
        num = Math.floor(num / 26) - 1
      }
      return label
    },
    async handleUpdateCells() {
      if (!this.currentFile) return
      const values = this.sheetData.map(row => {
        return this.sheetColumns.map(colIndex => {
          const v = row['col' + colIndex]
          return v !== undefined ? v : ''
        })
      })
      try {
        const response = await updateKdocsCells({
          userId: this.userId,
          fileToken: this.currentFile.file_token,
          sheetIdx: this.currentSheetIdx,
          range: this.cellRange,
          values
        })
        if (response.code === 200) {
          this.$message.success('保存成功')
        }
      } catch (e) {
        this.$message.error(e.msg || e.message || '保存失败')
      }
    }
  }
}
</script>

<style scoped>
.app-container {
  padding: 20px;
}
.list-hint {
  color: #909399;
  font-size: 13px;
  margin-bottom: 10px;
}
</style>
