<script lang="ts" setup>
import { inject, onMounted, ref } from "vue"
import { LocalConfigWrapperKey } from "../ts/class/LocalConfigWrapper"
import { ElMessage } from "element-plus"
import { fetchYata, purge, YataApiDataWrap } from "../ts/func/module/fetchYata"
import { LoggerKey } from "../ts/class/Logger"
import toThousands from "../ts/func/utils/toThousands"
import { Download, QuestionFilled, Refresh, Search } from "@element-plus/icons-vue"
import { timePastFormat } from "../ts/func/utils/timePastFormat"
import { convertToCSV } from "../ts/func/utils/convert2Csv"

const isMiniProfOn = ref<boolean>(false)
const isProfOn = ref<boolean>(false)
const apikey = ref<string>('')
const targetId = ref<string>('')
const tableData = ref<Partial<YataApiDataWrap>[]>([])
const isLoading = ref(false)
const idKey: { [key: string]: number } = {}
const buildType = { Offensive: '攻击型', Defensive: '防御型', Balanced: '平衡型' }

const localConfigWrapper = inject(LocalConfigWrapperKey)
const logger = inject(LoggerKey)

const saveApikey = () => {
  if (!apikey.value) {
    ElMessage({
      message: 'apikey保存时输入为空',
      type: 'error',
      showClose: true
    })
    throw new TypeError('apikey保存时输入为空')
  }
  localStorage.setItem('APIKey', apikey.value)
  ElMessage.success({
    message: 'APIKey设置成功',
    showClose: true
  })
}
const onMiniProfSwitchChange = () => localConfigWrapper.config.isBSEstMiniProfOn = isMiniProfOn.value
const onProfSwitchChange = () => localConfigWrapper.config.isBSEstProfOn = isProfOn.value
const doRequest = async () => {
  if (!apikey.value) {
    ElMessage.warning({
      message: '未设置APIKey',
      showClose: true
    })
    return
  }
  isLoading.value = true
  for (let i = 0; i < tableData.value.length; i++) {
    const item = tableData.value[i]
    if (!item.total) {
      let est: YataApiDataWrap
      try {
        est = await fetchYata(parseInt(item.id), apikey.value)
      } catch (e) {
        ElMessage.error({
          message: e.message,
          showClose: true
        })
        logger.error(e.stack)
        continue
      }
      item.total = est.total
      item.score = est.score
      item.type = est.type
      item.skewness = est.skewness
      item.timestamp = est.timestamp
      item.version = est.version
      item.isCache = est.isCache
    }
  }
  isLoading.value = false
}
/**
 * 查询列表中添加新的id
 * @param _id
 */
const add = (_id: string) => {
  const id = parseInt(_id)
  if (id) {
    // 重复id判断
    if (!idKey[_id]) {
      tableData.value.push({ id: _id })
      idKey[_id] = 1
      targetId.value = ''
    } else {
      ElMessage.warning({
        message: '重复的id',
        showClose: true
      })
    }
  } else {
    ElMessage.error({
      message: 'id有误',
      showClose: true
    })
  }
}

/**
 * 清空查询列表和唯一id表
 */
const emptyList = () => {
  tableData.value = []
  const keys = Object.keys(idKey)
  for (let i = 0; i < keys.length; i++) {
    const key = keys[i]
    idKey[key] = 0
  }
}

const purgeCache = () => {
  purge()
  ElMessage.warning({
    message: '本地缓存已清除',
    showClose: true
  })
}

const exportCsv = () => {
  const exportList: any[] = [{
    id: "ID", total: "BS", score: "评分", type: "风格", skewness: "偏差", timestamp: "时间戳"
  }]
  for (let i = 0; i < tableData.value.length; i++) {
    const item = tableData.value[i]
    const newItem = {
      id: item.id ?? '-1',
      total: item.total ?? null,
      score: item.score ?? null,
      type: buildType[item.type] ?? null,
      skewness: item.skewness ?? null,
      timestamp: item.timestamp ?? null,
      // isCache: item.isCache ?? null,
      // version: item.version ?? null
    }
    exportList.push(newItem)
  }
  const csvContent = convertToCSV(exportList)
  let url: string
  let isBlob = false
  const UTF8 = "\uFEFF"
  if (window.Blob && window.URL && window.URL.createObjectURL) {
    const csvData = new window.Blob([UTF8 + csvContent], {
      type: 'text/csv'
    })
    url = window.URL.createObjectURL(csvData)
    isBlob = true
  } else {
    url = window.encodeURI(csvContent)
  }
  window.location.href = isBlob ? url : 'data:text/csv;charset=utf-8,' + UTF8 + url
}

onMounted(() => {
  // APIKey
  const key = localStorage.getItem('APIKey')
  if (!key) {
    ElMessage.error({
      message: '尚未配置APIKey',
      showClose: true
    })
  } else {
    apikey.value = key
  }

  // 获取配置
  isMiniProfOn.value = localConfigWrapper.config.isBSEstMiniProfOn
  isProfOn.value = localConfigWrapper.config.isBSEstProfOn
})
</script>

<template>
  <el-space :fill="true">
    <el-card shadow="never">
      <template #header>设置</template>
      <el-form label-width="auto" @submit.prevent>
        <el-form-item label="MINI资料卡中显示">
          <el-switch v-model="isMiniProfOn" @change="onMiniProfSwitchChange"/>
        </el-form-item>
        <el-form-item label="个人资料中显示">
          <el-switch v-model="isProfOn" @change="onProfSwitchChange"/>
        </el-form-item>
        <el-form-item label="API KEY">
          <el-input v-model="apikey">
            <template #append>
              <el-button :loading="isLoading" @click="saveApikey">保存</el-button>
            </template>
          </el-input>
        </el-form-item>
        <el-form-item>
          <el-popconfirm cancel-button-text="取消" confirm-button-text="确定" title="确定操作" @confirm="purgeCache">
            <template #reference>
              <el-button type="danger">清空缓存</el-button>
            </template>
          </el-popconfirm>
        </el-form-item>
      </el-form>
    </el-card>
    <el-card shadow="never">
      <template #header>使用</template>
      <p class="mt-4">BS估算功能使用了
        <el-link href="https://yata.yt/api/v1/" target="_blank">yata</el-link>
        神经网络模型接口，需要提供torn apikey (上面输入)
      </p>
      <p class="mt-4">本插件缓存机制：1天</p>
      <el-form label-width="auto" @submit="add(targetId)" @submit.prevent>
        <el-form-item label="目标数字ID">
          <el-input v-model="targetId" clearable/>
        </el-form-item>
        <el-form-item>
          <el-button :loading="isLoading" type="primary" @click="add(targetId)">添加</el-button>
        </el-form-item>
      </el-form>
    </el-card>
    <el-card shadow="never">
      <template #header>结果</template>
      <el-button-group>
        <el-button :icon="Search" :loading="isLoading" type="primary" @click="doRequest">估算</el-button>
        <el-button :icon="Refresh" :loading="isLoading" @click="emptyList">清空</el-button>
        <el-button :icon="Download" :loading="isLoading" @click="exportCsv">导出CSV</el-button>
      </el-button-group>
      <el-row>
        <el-col :span="23">
          <el-table :data="tableData" empty-text=" ">
            <el-table-column label="ID" prop="id"/>
            <el-table-column label="BS">
              <template #default="scope">
                {{ toThousands(scope.row.total) }}
              </template>
            </el-table-column>
            <el-table-column label="评分" prop="score"/>
            <el-table-column label="风格">
              <template #default="scope">
                {{ buildType[scope.row.type] }}
              </template>
            </el-table-column>
            <el-table-column>
              <template #header>
                <el-tooltip content="越低越准" effect="light" placement="top">
                  <span>偏差<el-icon><QuestionFilled/></el-icon></span>
                </el-tooltip>
              </template>
              <template #default="scope">
                {{ scope.row.skewness }}%
              </template>
            </el-table-column>
            <el-table-column label="时间">
              <template #default="scope">
                {{ timePastFormat(Date.now() - scope.row.timestamp * 1000) }}
              </template>
            </el-table-column>
          </el-table>
        </el-col>
      </el-row>
    </el-card>
  </el-space>
</template>

<style scoped>

</style>
