<script setup lang="ts">
import { computed, ref } from 'vue';

import { $t } from '@easyflow/locales';

import { CopyDocument } from '@element-plus/icons-vue';
import { ElButton, ElCard, ElIcon, ElInput, ElMessage } from 'element-plus';

import { api } from '#/api/request';

type EndpointParam = {
  location: 'body' | 'query';
  name: string;
  note?: string;
  required?: boolean;
};

type EndpointDoc = {
  hint: string;
  method: 'GET' | 'POST';
  params: EndpointParam[];
  path: string;
};

const props = defineProps({
  knowledgeId: {
    type: String,
    required: true,
  },
  collectionType: {
    type: String,
    default: 'DOCUMENT',
  },
  manageable: {
    type: Boolean,
    default: true,
  },
});

const createLoading = ref(false);
const generatedUrl = ref('');
const generatedExpireAt = ref('');

const apiBaseUrl = computed(() => {
  const appBasePath = (import.meta.env.BASE_URL || '/').replace(/\/$/, '');
  if (typeof window === 'undefined') {
    return `${appBasePath}/public-api/knowledge-share`;
  }
  return `${window.location.origin}${appBasePath}/public-api/knowledge-share`;
});

const detailExample = computed(() => {
  return [
    `curl -X GET '${apiBaseUrl.value}/detail?knowledgeId=${props.knowledgeId}' \\`,
    "  -H 'ApiKey: 你的访问令牌'",
  ].join('\n');
});

const searchExample = computed(() => {
  return [
    `curl -G '${apiBaseUrl.value}/search' \\`,
    "  -H 'ApiKey: 你的访问令牌' \\",
    `  --data-urlencode 'knowledgeId=${props.knowledgeId}' \\`,
    "  --data-urlencode 'keyword=测试问题'",
  ].join('\n');
});

const endpointDocs = computed(() => {
  const commonEndpoints: EndpointDoc[] = [
    {
      method: 'GET',
      path: '/detail',
      hint: '获取知识库详情',
      params: [{ name: 'knowledgeId', location: 'query', required: true }],
    },
    {
      method: 'GET',
      path: '/search',
      hint: '知识检索',
      params: [
        { name: 'knowledgeId', location: 'query', required: true },
        { name: 'keyword', location: 'query', required: true },
        {
          name: 'retrievalMode',
          location: 'query',
          note: '召回方式',
        },
      ],
    },
  ];
  const typeEndpoints: EndpointDoc[] =
    props.collectionType === 'FAQ'
      ? [
          {
            method: 'GET',
            path: '/faq/page',
            hint: 'FAQ 分页',
            params: [
              { name: 'knowledgeId', location: 'query', required: true },
              { name: 'question', location: 'query', note: '问题关键字' },
              { name: 'categoryId', location: 'query', note: '分类 ID' },
              { name: 'pageNumber', location: 'query', note: '默认 1' },
              { name: 'pageSize', location: 'query', note: '默认 10' },
            ],
          },
          {
            method: 'POST',
            path: '/faq/save',
            hint: '新增 FAQ',
            params: [
              { name: 'collectionId', location: 'body', required: true },
              { name: 'question', location: 'body', required: true },
              { name: 'answerHtml', location: 'body', required: true },
              { name: 'categoryId', location: 'body', note: '分类 ID' },
            ],
          },
        ]
      : [
          {
            method: 'GET',
            path: '/document/page',
            hint: '文档分页',
            params: [
              { name: 'knowledgeId', location: 'query', required: true },
              { name: 'title', location: 'query', note: '文档标题' },
              { name: 'pageNumber', location: 'query', note: '默认 1' },
              { name: 'pageSize', location: 'query', note: '默认 10' },
            ],
          },
          {
            method: 'POST',
            path: '/document/import/commit',
            hint: '导入文档',
            params: [
              { name: 'knowledgeId', location: 'body', required: true },
              {
                name: 'previewSessionIds',
                location: 'body',
                required: true,
                note: '预览接口返回的会话 ID 数组',
              },
            ],
          },
        ];
  return [...commonEndpoints, ...typeEndpoints].map((item) => ({
    ...item,
    url: `${apiBaseUrl.value}${item.path}`,
  }));
});

const formatEndpointParam = (param: EndpointParam) => {
  const segments = [param.location, param.required ? '必填' : '可选'];
  if (param.note) {
    segments.push(param.note);
  }
  return `${param.name}（${segments.join('，')}）`;
};

const createShare = async () => {
  if (!props.manageable) {
    ElMessage.warning($t('documentCollection.managePermissionHint'));
    return;
  }
  createLoading.value = true;
  try {
    const res = await api.post('/api/v1/knowledgeShare/url/create', {
      knowledgeId: props.knowledgeId,
    });
    if (res.errorCode === 0) {
      generatedUrl.value = res.data?.shareUrl || '';
      generatedExpireAt.value = res.data?.expiresAt || '';
      ElMessage.success('已创建分享链接');
    }
  } finally {
    createLoading.value = false;
  }
};

const copyGeneratedUrl = async () => {
  if (!generatedUrl.value) {
    ElMessage.warning('请先生成分享链接');
    return;
  }
  await navigator.clipboard.writeText(generatedUrl.value);
  ElMessage.success('已复制分享链接');
};

const copyApiExample = async (content: string) => {
  await navigator.clipboard.writeText(content);
  ElMessage.success('已复制调用示例');
};

const copyEndpointUrl = async (url: string) => {
  await navigator.clipboard.writeText(url);
  ElMessage.success('已复制接口地址');
};
</script>

<template>
  <div class="share-management">
    <ElCard shadow="never" class="share-card">
      <template #header>
        <div class="share-card__header">
          <div>
            <div class="share-card__title">当前分享链接</div>
            <div class="share-card__desc">
              默认有效期 30 分钟。重新生成后旧链接立即失效。
            </div>
          </div>
          <ElButton
            type="primary"
            :loading="createLoading"
            :disabled="!props.manageable"
            @click="createShare"
          >
            {{ generatedUrl ? '重新生成链接' : '生成分享链接' }}
          </ElButton>
        </div>
      </template>

      <div v-if="generatedUrl" class="share-result">
        <div class="share-result__row">
          <ElInput v-model="generatedUrl" readonly />
          <ElButton
            text
            circle
            :icon="CopyDocument"
            aria-label="复制分享链接"
            title="复制分享链接"
            @click="copyGeneratedUrl"
          />
        </div>
        <div class="share-result__meta">过期时间：{{ generatedExpireAt }}</div>
      </div>
      <div v-else class="share-empty">暂未生成分享链接</div>
    </ElCard>

    <ElCard shadow="never" class="share-card">
      <template #header>
        <div class="share-card__header share-card__header--stack">
          <div>
            <div class="share-card__title">API 调用方式</div>
            <div class="share-card__desc">
              使用已开通知识库分享授权的访问令牌，通过 `ApiKey` 请求头调用。
            </div>
          </div>
        </div>
      </template>

      <div class="api-doc">
        <div class="api-doc__meta">
          <div class="api-doc__item">
            <span class="api-doc__label">接口前缀</span>
            <code class="api-doc__value">{{ apiBaseUrl }}</code>
          </div>
          <div class="api-doc__item">
            <span class="api-doc__label">请求头</span>
            <code class="api-doc__value">ApiKey: 你的访问令牌</code>
          </div>
          <div class="api-doc__item">
            <span class="api-doc__label">当前知识库 ID</span>
            <code class="api-doc__value">{{ props.knowledgeId }}</code>
          </div>
        </div>

        <div class="api-doc__section">
          <div class="api-doc__section-title">常用接口</div>
          <div class="api-doc__endpoint-list">
            <div
              v-for="endpoint in endpointDocs"
              :key="endpoint.path"
              class="api-doc__endpoint"
            >
              <div class="api-doc__endpoint-main">
                <span class="api-doc__method">{{ endpoint.method }}</span>
                <code>{{ endpoint.path }}</code>
                <span class="api-doc__hint">{{ endpoint.hint }}</span>
                <ElButton
                  text
                  circle
                  :icon="CopyDocument"
                  class="api-doc__copy"
                  :aria-label="`复制 ${endpoint.path}`"
                  :title="`复制 ${endpoint.url}`"
                  @click="copyEndpointUrl(endpoint.url)"
                />
              </div>
              <div class="api-doc__endpoint-params">
                <span class="api-doc__params-label">参数</span>
                <span
                  v-for="param in endpoint.params"
                  :key="`${endpoint.path}-${param.name}`"
                  class="api-doc__param"
                >
                  {{ formatEndpointParam(param) }}
                </span>
              </div>
            </div>
          </div>
        </div>

        <div class="api-doc__section">
          <div class="api-doc__section-title">详情示例</div>
          <div class="api-doc__code-wrap">
            <button
              type="button"
              class="api-doc__code-copy"
              title="复制详情示例"
              aria-label="复制详情示例"
              @click="copyApiExample(detailExample)"
            >
              <ElIcon><CopyDocument /></ElIcon>
            </button>
            <pre class="api-doc__code">{{ detailExample }}</pre>
          </div>
        </div>

        <div class="api-doc__section">
          <div class="api-doc__section-title">检索示例</div>
          <div class="api-doc__code-wrap">
            <button
              type="button"
              class="api-doc__code-copy"
              title="复制检索示例"
              aria-label="复制检索示例"
              @click="copyApiExample(searchExample)"
            >
              <ElIcon><CopyDocument /></ElIcon>
            </button>
            <pre class="api-doc__code">{{ searchExample }}</pre>
          </div>
        </div>
      </div>
    </ElCard>
  </div>
</template>

<style scoped>
.share-management {
  display: grid;
  gap: 16px;
}

.share-card {
  border-radius: 16px;
}

.share-card__header {
  display: flex;
  gap: 16px;
  align-items: center;
  justify-content: space-between;
}

.share-card__header--stack {
  align-items: flex-start;
}

.share-card__title {
  font-size: 16px;
  font-weight: 600;
}

.share-card__desc,
.share-result__meta {
  margin-top: 6px;
  font-size: 13px;
  color: var(--el-text-color-secondary);
}

.share-result {
  display: grid;
  gap: 8px;
  margin-bottom: 16px;
}

.share-result__row {
  display: flex;
  gap: 12px;
  align-items: center;
}

.share-empty {
  font-size: 13px;
  color: var(--el-text-color-secondary);
}

.api-doc {
  display: grid;
  gap: 18px;
}

.api-doc__meta {
  display: grid;
  gap: 10px;
}

.api-doc__item {
  display: flex;
  gap: 12px;
  align-items: center;
  flex-wrap: wrap;
}

.api-doc__label {
  min-width: 84px;
  font-size: 13px;
  color: var(--el-text-color-secondary);
}

.api-doc__value {
  padding: 4px 10px;
  font-size: 13px;
  color: var(--el-text-color-primary);
  background: var(--el-fill-color-light);
  border-radius: 10px;
}

.api-doc__section {
  display: grid;
  gap: 10px;
}

.api-doc__section-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--el-text-color-primary);
}

.api-doc__endpoint-list {
  display: grid;
  gap: 8px;
}

.api-doc__endpoint {
  display: grid;
  gap: 6px;
  padding: 8px 0;
}

.api-doc__endpoint-main {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
  font-size: 13px;
}

.api-doc__copy {
  flex: 0 0 auto;
}

.api-doc__method {
  min-width: 42px;
  font-weight: 600;
  color: var(--el-color-primary);
}

.api-doc__hint {
  color: var(--el-text-color-secondary);
}

.api-doc__endpoint-params {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  flex-wrap: wrap;
  font-size: 12px;
  color: var(--el-text-color-secondary);
}

.api-doc__params-label {
  flex: 0 0 auto;
  font-weight: 500;
}

.api-doc__param {
  padding: 2px 8px;
  background: var(--el-fill-color-light);
  border-radius: 999px;
}

.api-doc__code {
  margin: 0;
  padding: 14px 16px;
  overflow-x: auto;
  font-size: 12px;
  line-height: 1.7;
  color: var(--el-text-color-primary);
  white-space: pre-wrap;
  word-break: break-all;
  background: var(--el-fill-color-light);
  border-radius: 14px;
}

.api-doc__code-wrap {
  position: relative;
}

.api-doc__code-copy {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  color: var(--el-text-color-secondary);
  cursor: pointer;
  background: transparent;
  border: none;
  border-radius: 8px;
}

.api-doc__code-copy:hover {
  color: var(--el-color-primary);
  background: var(--el-fill-color);
}

.api-doc__code-copy:focus-visible {
  outline: 2px solid var(--el-color-primary-light-5);
  outline-offset: 2px;
}

.api-doc__code-wrap .api-doc__code {
  padding-top: 40px;
}
</style>
