<template>
  <div id="tool-detail-top" class="tool-detail-shell">
    <header class="header-wrap is-scrolled">
      <div class="container header">
        <button type="button" class="brand detail-back-link" @click="goHome">
          <AppIcon name="arrowLeft" :size="18" />
          <span class="brand-mark" aria-hidden="true">
            <img src="/favicon.svg" alt="" width="32" height="32" />
          </span>
          <span>返回工具列表</span>
        </button>
      </div>
    </header>

    <main class="container detail-main-content">
      <section v-if="loading" class="detail-state-card">
        <p>正在加载用户手册...</p>
      </section>

      <section v-else-if="notFound" class="detail-state-card">
        <h1>手册不存在或已下线</h1>
        <p>当前链接无法找到可访问的工具详情。</p>
        <button type="button" class="btn btn-primary" @click="goHome">返回工具列表</button>
      </section>

      <section v-else-if="errorMessage" class="detail-state-card">
        <h1>加载失败</h1>
        <p>{{ errorMessage }}</p>
        <div class="detail-state-actions">
          <button type="button" class="btn btn-primary" @click="loadDetail">重新加载</button>
          <button type="button" class="btn" @click="goHome">返回工具列表</button>
        </div>
      </section>

      <template v-else-if="detail">
        <section class="detail-overview-card">
          <div class="detail-hero-section">
            <div class="detail-hero-copy">
              <p class="detail-category-label">{{ detail.category?.name || '未分类' }}</p>
              <h1>{{ detail.name }}</h1>
              <div class="detail-summary-row">
                <p class="detail-summary-text">
                  更新时间：{{ formatDate(detail.updatedAt) }} · {{ toolModeSummary(detail) }}
                </p>
                <div v-if="detail.tags?.length" class="tags detail-inline-tags">
                  <span v-for="tag in detail.tags" :key="tag" class="tag">{{ tag }}</span>
                </div>
              </div>
            </div>

            <div class="detail-hero-actions">
              <button
                type="button"
                class="btn btn-primary btn-with-icon"
                :disabled="isPrimaryActionDisabled"
                @click="triggerPrimaryAction"
              >
                <AppIcon :name="primaryActionIconName" :size="16" />
                {{ primaryActionLabel }}
              </button>
              <p v-if="launchError" class="detail-inline-error">{{ launchError }}</p>
            </div>
          </div>

          <div v-if="detail.features?.length" class="detail-summary-section">
            <div class="detail-feature-block">
              <h2 class="title-with-icon">
                <AppIcon name="sparkles" :size="18" />
                核心能力
              </h2>
              <ul class="feature-list">
                <li v-for="(feature, index) in detail.features" :key="`${detail.id}-${index}`">
                  <AppIcon name="star" :size="15" />
                  <div class="markdown markdown-inline" v-html="renderInlineMarkdown(feature)"></div>
                </li>
              </ul>
            </div>
          </div>
        </section>

        <section class="detail-manual-card">
          <div class="detail-manual-header">
            <div>
              <h2 class="title-with-icon">
                <AppIcon name="book" :size="18" />
                用户手册
              </h2>
            </div>
            <a v-if="hasManual" class="detail-back-top" href="#tool-detail-top">回到顶部</a>
          </div>
          <p v-if="!hasManual" class="detail-empty-manual">暂未提供用户手册</p>
          <div v-else class="detail-manual-layout">
            <aside v-if="outline.length" class="detail-outline">
              <p>目录</p>
              <a
                v-for="item in outline"
                :key="item.id"
                :href="`#${item.id}`"
                class="detail-outline-link"
                :class="`level-${item.level}`"
              >
                {{ item.text }}
              </a>
            </aside>
            <div
              class="detail-manual-body markdown markdown-detail"
              v-html="manualHtml"
            ></div>
          </div>
        </section>
      </template>
    </main>
  </div>
</template>

<script setup>
import { computed, ref, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import AppIcon from '../components/AppIcon.vue';
import {
  fetchToolDetailBySlug,
  getApiErrorMessage,
  launchTool,
  notifyToolInteraction,
  resolveActionUrl,
} from '../api';
import { renderInlineMarkdown, renderMarkdown } from '../utils/markdown';
import { extractMarkdownOutline, injectOutlineAnchors } from '../utils/markdown-outline';

const CLIENT_VERSION = 'web-1.0.0';

const route = useRoute();
const router = useRouter();

const loading = ref(false);
const notFound = ref(false);
const errorMessage = ref('');
const launchError = ref('');
const detail = ref(null);
const launching = ref(false);

const hasManual = computed(() => Boolean(detail.value?.description?.trim()));
const outline = computed(() => (hasManual.value ? extractMarkdownOutline(detail.value.description) : []));
const primaryActionIconName = computed(() => accessModeIconName(detail.value?.accessMode));
const manualHtml = computed(() => {
  if (!hasManual.value) {
    return '';
  }

  return injectOutlineAnchors(renderMarkdown(detail.value.description), outline.value);
});

const primaryActionLabel = computed(() => {
  if (!detail.value) {
    return '';
  }
  if (launching.value) {
    return '处理中...';
  }
  if (detail.value.accessMode === 'web') {
    return '打开网页';
  }
  if (!detail.value.downloadReady) {
    return '暂无可下载资源';
  }
  return '下载';
});

const isPrimaryActionDisabled = computed(() => {
  if (!detail.value || launching.value) {
    return true;
  }
  return detail.value.accessMode === 'download' && !detail.value.downloadReady;
});

function formatNumber(value) {
  const numeric = Number(value);
  return new Intl.NumberFormat('zh-CN').format(Number.isFinite(numeric) ? numeric : 0);
}

function formatDate(dateText) {
  if (!dateText) {
    return '-';
  }
  const date = new Date(dateText);
  if (Number.isNaN(date.getTime())) {
    return '-';
  }
  return new Intl.DateTimeFormat('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
  }).format(date);
}

function formatFileSize(bytes) {
  const size = Number(bytes);
  if (!Number.isFinite(size) || size <= 0) {
    return '-';
  }

  const units = ['B', 'KB', 'MB', 'GB'];
  let value = size;
  let unitIndex = 0;
  while (value >= 1024 && unitIndex < units.length - 1) {
    value /= 1024;
    unitIndex += 1;
  }

  return `${value.toFixed(value >= 100 ? 0 : 1)} ${units[unitIndex]}`;
}

function toolModeSummary(tool) {
  if (tool.accessMode === 'download') {
    return `下载 ${formatNumber(tool.downloadCount)}`;
  }
  return `访问 ${formatNumber(tool.openCount)}`;
}

function accessModeIconName(accessMode) {
  return accessMode === 'download' ? 'download' : 'externalLink';
}

function goHome() {
  router.push({ name: 'public-home' });
}

function isNotFoundError(error) {
  return Number(error?.response?.status) === 404;
}

// Keep route-driven state in one loader so direct visits and in-app navigation behave the same.
async function loadDetail() {
  const slug = String(route.params.slug ?? '').trim();
  loading.value = true;
  notFound.value = false;
  errorMessage.value = '';
  launchError.value = '';
  detail.value = null;

  if (!slug) {
    loading.value = false;
    notFound.value = true;
    return;
  }

  try {
    detail.value = await fetchToolDetailBySlug(slug);
  } catch (error) {
    if (isNotFoundError(error)) {
      notFound.value = true;
    } else {
      errorMessage.value = getApiErrorMessage(error);
    }
  } finally {
    loading.value = false;
  }
}

async function triggerPrimaryAction() {
  if (!detail.value || isPrimaryActionDisabled.value) {
    return;
  }

  launching.value = true;
  launchError.value = '';

  try {
    const result = await launchTool(detail.value.id, {
      channel: 'official',
      clientVersion: CLIENT_VERSION,
    });
    const isWebLaunch = result?.mode === 'web';
    const isDownloadLaunch = result?.mode === 'download';

    if (isWebLaunch || isDownloadLaunch) {
      notifyToolInteraction(detail.value.id, {
        action: isWebLaunch ? 'open' : 'download',
        channel: 'official',
        clientVersion: CLIENT_VERSION,
      });
    }

    const actionUrl = resolveActionUrl(result?.actionUrl);
    if (!actionUrl) {
      throw new Error('未获取到可执行地址');
    }

    if ((isWebLaunch || isDownloadLaunch) && result.openIn === 'same_tab') {
      window.location.assign(actionUrl);
      return;
    }

    const page = window.open(actionUrl, '_blank', 'noopener,noreferrer');
    if (!page) {
      window.location.assign(actionUrl);
    }
  } catch (error) {
    launchError.value = getApiErrorMessage(error);
  } finally {
    launching.value = false;
  }
}

watch(
  () => route.params.slug,
  () => {
    loadDetail();
  },
  { immediate: true },
);
</script>
