<template>
  <div class="api-doc-page">
    <header class="doc-nav">
      <button type="button" @click="goBack">
        <i class="el-icon-arrow-left"></i>
        返回
      </button>
      <span>元境 API 文档</span>
    </header>

    <main class="doc-container">
      <el-alert
        v-if="errorMessage"
        class="doc-alert"
        :title="errorMessage"
        type="warning"
        show-icon
        :closable="false"
      ></el-alert>

      <section class="doc-hero">
        <h1>元境 API 文档</h1>
        <p>统一展示大模型、视频、图像、音频、任务查询等接口说明。</p>
      </section>

      <section v-loading="loading" class="doc-section markdown-section">
        <div v-html="renderedMarkdown"></div>
      </section>
    </main>

    <footer class="doc-footer">© 2026 开元云科技 · API 文档中心</footer>
  </div>
</template>

<script>
export default {
  name: 'ApiDocument',
  data() {
    return {
      loading: false,
      errorMessage: '',
      markdownText: '',
      markdownUrl: 'https://token.opencomputing.cn/docs/api_doc_zh.md'
    }
  },
  computed: {
    renderedMarkdown() {
      return this.renderMarkdown(this.markdownText)
    }
  },
  created() {
    this.fetchMarkdownDocument()
  },
  methods: {
    async fetchMarkdownDocument() {
      this.loading = true
      this.errorMessage = ''
      try {
        const response = await fetch(this.markdownUrl)
        if (!response.ok) {
          throw new Error(`HTTP ${response.status}`)
        }
        this.markdownText = await response.text()
      } catch (error) {
        console.error('[API文档] 获取 Markdown 文档失败', error)
        this.errorMessage = 'API 文档加载失败，请稍后重试'
      } finally {
        this.loading = false
      }
    },
    escapeHtml(text = '') {
      return String(text)
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
    },
    renderInline(text = '') {
      return this.escapeHtml(text)
        .replace(/`([^`]+)`/g, '<code>$1</code>')
        .replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>')
    },
    renderTable(lines) {
      const rows = lines
        .filter(line => line.trim().startsWith('|'))
        .map(line => line.trim().replace(/^\||\|$/g, '').split('|').map(cell => this.renderInline(cell.trim())))
      if (!rows.length) return ''
      const header = rows[0] || []
      const bodyRows = rows.slice(2)
      return `<div class="md-table-wrap"><table><thead><tr>${header.map(cell => `<th>${cell}</th>`).join('')}</tr></thead><tbody>${bodyRows.map(row => `<tr>${row.map(cell => `<td>${cell}</td>`).join('')}</tr>`).join('')}</tbody></table></div>`
    },
    renderMarkdown(markdown = '') {
      const lines = markdown.replace(/\r\n/g, '\n').split('\n')
      const html = []
      let index = 0

      while (index < lines.length) {
        const line = lines[index]
        const trimmed = line.trim()

        if (!trimmed) {
          index += 1
          continue
        }

        if (trimmed.startsWith('```')) {
          const lang = trimmed.replace(/```/, '').trim()
          const code = []
          index += 1
          while (index < lines.length && !lines[index].trim().startsWith('```')) {
            code.push(lines[index])
            index += 1
          }
          html.push(`<pre><code class="language-${this.escapeHtml(lang)}">${this.escapeHtml(code.join('\n'))}</code></pre>`)
          index += 1
          continue
        }

        if (trimmed.startsWith('|')) {
          const tableLines = []
          while (index < lines.length && lines[index].trim().startsWith('|')) {
            tableLines.push(lines[index])
            index += 1
          }
          html.push(this.renderTable(tableLines))
          continue
        }

        if (/^---+$/.test(trimmed)) {
          html.push('<hr>')
          index += 1
          continue
        }

        const heading = trimmed.match(/^(#{1,6})\s+(.*)$/)
        if (heading) {
          const level = heading[1].length
          html.push(`<h${level}>${this.renderInline(heading[2])}</h${level}>`)
          index += 1
          continue
        }

        if (/^[-*]\s+/.test(trimmed)) {
          const items = []
          while (index < lines.length && /^[-*]\s+/.test(lines[index].trim())) {
            items.push(lines[index].trim().replace(/^[-*]\s+/, ''))
            index += 1
          }
          html.push(`<ul>${items.map(item => `<li>${this.renderInline(item)}</li>`).join('')}</ul>`)
          continue
        }

        if (/^\d+\.\s+/.test(trimmed)) {
          const items = []
          while (index < lines.length && /^\d+\.\s+/.test(lines[index].trim())) {
            items.push(lines[index].trim().replace(/^\d+\.\s+/, ''))
            index += 1
          }
          html.push(`<ol>${items.map(item => `<li>${this.renderInline(item)}</li>`).join('')}</ol>`)
          continue
        }

        html.push(`<p>${this.renderInline(trimmed)}</p>`)
        index += 1
      }

      return html.join('')
    },
    goBack() {
      this.$router.back()
    }
  }
}
</script>

<style lang="less" scoped>
.api-doc-page {
  height: 100vh;
  color: #1f2d3d;
  background: #f6f8fb;
  overflow-y: auto;
  overflow-x: hidden;
}

.doc-nav {
  display: flex;
  align-items: center;
  height: 48px;
  padding: 0 28px;
  color: #667085;
  background: #ffffff;
  border-bottom: 1px solid #edf1f7;

  button {
    padding: 0;
    margin-right: 16px;
    color: #667085;
    cursor: pointer;
    background: transparent;
    border: none;
  }
}

.doc-container {
  width: 1180px;
  max-width: calc(100vw - 48px);
  margin: 28px auto 0;
}

.doc-alert {
  margin-bottom: 18px;
}

.doc-hero,
.doc-section {
  padding: 24px;
  margin-bottom: 18px;
  background: #ffffff;
  border: 1px solid #edf1f7;
  border-radius: 12px;
}

.doc-hero {
  h1 {
    margin: 0 0 10px;
    font-size: 28px;
  }

  p {
    margin: 0 0 18px;
    color: #667085;
  }
}

.quick-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;

  span {
    padding: 6px 12px;
    color: #2f6bff;
    background: #eef4ff;
    border-radius: 999px;
    font-size: 13px;
  }
}

.doc-section {
  h2 {
    margin: 0 0 16px;
    padding-left: 10px;
    color: #1f2d3d;
    font-size: 18px;
    border-left: 3px solid #2f6bff;
  }

  p {
    color: #667085;
    line-height: 1.8;
  }
}

.markdown-section {
  line-height: 1.8;

  ::v-deep h1 {
    margin: 0 0 24px;
    color: #111827;
    font-size: 30px;
    font-weight: 800;
  }

  ::v-deep h2 {
    margin: 34px 0 16px;
    padding-left: 10px;
    color: #1f2d3d;
    font-size: 22px;
    border-left: 3px solid #2f6bff;
  }

  ::v-deep h3 {
    margin: 26px 0 12px;
    color: #1f2937;
    font-size: 18px;
  }

  ::v-deep h4,
  ::v-deep h5 {
    margin: 20px 0 10px;
    color: #334155;
    font-size: 16px;
  }

  ::v-deep p,
  ::v-deep li {
    color: #475569;
    font-size: 14px;
  }

  ::v-deep ul,
  ::v-deep ol {
    padding-left: 22px;
  }

  ::v-deep hr {
    height: 1px;
    margin: 28px 0;
    background: #e5e7eb;
    border: 0;
  }

  ::v-deep code {
    padding: 2px 6px;
    color: #d6336c;
    background: #fff1f2;
    border-radius: 5px;
  }

  ::v-deep pre code {
    padding: 0;
    color: inherit;
    background: transparent;
    border-radius: 0;
  }

  ::v-deep .md-table-wrap {
    width: 100%;
    margin: 16px 0 24px;
    overflow-x: auto;
    border: 1px solid #e5e7eb;
    border-radius: 10px;
  }

  ::v-deep table {
    width: 100%;
    min-width: 680px;
    border-collapse: collapse;
    background: #fff;
  }

  ::v-deep th,
  ::v-deep td {
    padding: 10px 12px;
    color: #475569;
    font-size: 13px;
    text-align: left;
    border-bottom: 1px solid #e5e7eb;
    border-right: 1px solid #e5e7eb;
  }

  ::v-deep th {
    color: #1f2937;
    font-weight: 700;
    background: #f8fafc;
  }
}

pre {
  margin: 14px 0 24px;
  padding: 16px;
  color: #e6edf3;
  overflow-x: auto;
  background: #1f2329;
  border-radius: 8px;
  line-height: 1.7;
}

code {
  font-family: Consolas, Monaco, monospace;
  font-size: 13px;
}

.doc-footer {
  padding: 32px 0;
  color: #98a2b3;
  text-align: center;
  font-size: 12px;
}
</style>
