---
import { createMarkdownProcessor } from '@astrojs/markdown-remark';
import BaseLayout from '../../layouts/BaseLayout.astro';
import TerminalWindow from '../../components/ui/TerminalWindow.astro';
import CommandPrompt from '../../components/ui/CommandPrompt.astro';
import ResponsiveImage from '../../components/ui/ResponsiveImage.astro';
import TableOfContents from '../../components/TableOfContents.astro';
import RelatedPosts from '../../components/RelatedPosts.astro';
import ReadingProgress from '../../components/ReadingProgress.astro';
import Lightbox from '../../components/Lightbox.astro';
import CodeCopyButton from '../../components/CodeCopyButton.astro';
import Comments from '../../components/Comments.astro';
import ParagraphComments from '../../components/ParagraphComments.astro';
import { apiClient, DEFAULT_SITE_SETTINGS } from '../../lib/api/client';
import { formatReadTime, getI18n } from '../../lib/i18n';
import type { PopularPostHighlight } from '../../lib/types';
import {
  getAccentVars,
  getCategoryTheme,
  getPostTypeColor,
  getPostTypeTheme,
  getTagTheme,
  resolveFileRef,
} from '../../lib/utils';

export const prerender = false;

const { slug } = Astro.params;

let post = null;
let siteSettings = DEFAULT_SITE_SETTINGS;
let homeData: Awaited<ReturnType<typeof apiClient.getHomePageData>> | null = null;

const [postResult, siteSettingsResult, homeDataResult] = await Promise.allSettled([
  apiClient.getPostBySlug(slug ?? ''),
  apiClient.getSiteSettings(),
  apiClient.getHomePageData(),
]);

if (postResult.status === 'fulfilled') {
  post = postResult.value;
} else {
  console.error('API Error:', postResult.reason);
}

if (siteSettingsResult.status === 'fulfilled') {
  siteSettings = siteSettingsResult.value;
} else {
  console.error('Site settings API Error:', siteSettingsResult.reason);
}

if (homeDataResult.status === 'fulfilled') {
  homeData = homeDataResult.value;
  if (siteSettingsResult.status !== 'fulfilled') {
    siteSettings = homeData.siteSettings;
  }
} else {
  console.error('Home data API Error:', homeDataResult.reason);
}

if (!post) {
  return new Response(null, { status: 404 });
}

if (slug && post.slug !== slug) {
  return Astro.redirect(`/articles/${post.slug}`, 301);
}

const typeColor = getPostTypeColor(post.type || 'article');
const typeTheme = getPostTypeTheme(post.type || 'article');
const categoryTheme = getCategoryTheme(post.category);
const contentText = post.content || post.description || '';
const wordCount = contentText.length;
const readTimeMinutes = Math.ceil(wordCount / 300);
const { locale, t } = getI18n(Astro);
const articleMarkdown = contentText.replace(/^#\s+.+\r?\n+/, '');
const paragraphCommentsEnabled = siteSettings.comments.paragraphsEnabled;

const markdownProcessor = await createMarkdownProcessor();
const renderedContent = await markdownProcessor.render(articleMarkdown);
const siteBaseUrl = siteSettings.siteUrl || new URL(Astro.request.url).origin;
const canonicalUrl = post.canonicalUrl || new URL(`/articles/${post.slug}`, siteBaseUrl).toString();
const ogImage = post.ogImage || `/og/${post.slug}.svg`;
const noindex = Boolean(post.noindex || post.visibility === 'unlisted');
const publishedAt = post.publishAt || `${post.date}T00:00:00Z`;
const hotRelatedPosts = (homeData?.popularPosts ?? [])
  .filter((item): item is PopularPostHighlight & { post: NonNullable<PopularPostHighlight['post']> } => Boolean(item.post))
  .filter((item) => item.slug !== post.slug)
  .map((item) => {
    const sharedTags = item.post.tags.filter((tag) => post.tags.includes(tag));
    const sameCategory = item.post.category === post.category;
    const sameType = item.post.type === post.type;
    const relevance = (sameCategory ? 4 : 0) + sharedTags.length * 3 + (sameType ? 1 : 0);
    const popularityScore =
      item.pageViews + item.readCompletes * 2 + item.avgProgressPercent / 20;

    return {
      ...item,
      sharedTags,
      sameCategory,
      relevance,
      popularityScore,
      finalScore: relevance * 100 + popularityScore,
    };
  })
  .filter((item) => item.relevance > 0)
  .sort((left, right) => {
    return (
      right.finalScore - left.finalScore ||
      right.pageViews - left.pageViews ||
      right.readCompletes - left.readCompletes
    );
  })
  .slice(0, 3);
const articleJsonLd = {
  '@context': 'https://schema.org',
  '@type': 'Article',
  headline: post.title,
  description: post.description,
  image: [new URL(ogImage, siteBaseUrl).toString()],
  mainEntityOfPage: canonicalUrl,
  url: canonicalUrl,
  datePublished: publishedAt,
  dateModified: publishedAt,
  author: {
    '@type': 'Person',
    name: siteSettings.ownerName,
  },
  publisher: {
    '@type': 'Organization',
    name: siteSettings.siteName,
    logo: siteSettings.ownerAvatarUrl
      ? {
          '@type': 'ImageObject',
          url: siteSettings.ownerAvatarUrl,
        }
      : undefined,
  },
  articleSection: post.category,
  keywords: post.tags,
  inLanguage: locale,
  isAccessibleForFree: true,
  wordCount,
  timeRequired: `PT${Math.max(readTimeMinutes, 1)}M`,
};
const breadcrumbJsonLd = {
  '@context': 'https://schema.org',
  '@type': 'BreadcrumbList',
  itemListElement: [
    {
      '@type': 'ListItem',
      position: 1,
      name: siteSettings.siteName,
      item: siteBaseUrl,
    },
    {
      '@type': 'ListItem',
      position: 2,
      name: 'Articles',
      item: new URL('/articles', siteBaseUrl).toString(),
    },
    {
      '@type': 'ListItem',
      position: 3,
      name: post.title,
      item: canonicalUrl,
    },
  ],
};
---

<BaseLayout
  title={post.title}
  description={post.description}
  siteSettings={siteSettings}
  canonical={canonicalUrl}
  noindex={noindex}
  ogImage={ogImage}
  ogType="article"
  twitterCard="summary_large_image"
  jsonLd={[articleJsonLd, breadcrumbJsonLd]}
>
  <ReadingProgress />
  <Lightbox />
  <CodeCopyButton />

  <div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 py-8" data-article-slug={post.slug}>
    <div class="flex flex-col gap-8 lg:flex-row">
      <div class="min-w-0 flex-1">
        <TerminalWindow title={`~/content/posts/${post.slug}.md`} class="w-full">
          <div class="px-4 pb-2">
            <div class="terminal-panel ml-4 mt-4 space-y-5">
              <div class="flex flex-wrap items-start justify-between gap-4">
                <div class="space-y-4">
                  <a href="/articles" class="terminal-link-arrow">
                    <i class="fas fa-arrow-left"></i>
                    <span>{t('article.backToArticles')}</span>
                  </a>

                  <div class="flex flex-wrap items-center gap-2">
                    <span class="terminal-kicker">
                      <i class="fas fa-file-code"></i>
                      {t('article.documentSession')}
                    </span>
                    <span class="terminal-chip terminal-chip--accent" style={getAccentVars(typeTheme)}>
                      <span class="h-2.5 w-2.5 rounded-full" style={`background-color: ${typeColor}`}></span>
                      {post.type === 'article' ? t('common.article') : t('common.tweet')}
                    </span>
                    <span class="terminal-chip terminal-chip--accent" style={getAccentVars(categoryTheme)}>
                      <i class="fas fa-folder-tree"></i>
                      {post.category}
                    </span>
                  </div>
                </div>

                <div class="flex flex-wrap gap-2">
                  <span class="terminal-stat-pill">
                    <i class="far fa-calendar text-[var(--primary)]"></i>
                    {post.date}
                  </span>
                  <span class="terminal-stat-pill">
                    <i class="far fa-clock text-[var(--primary)]"></i>
                    {formatReadTime(locale, readTimeMinutes, t)}
                  </span>
                  <span class="terminal-stat-pill">
                    <i class="fas fa-font text-[var(--primary)]"></i>
                    {t('common.characters', { count: wordCount })}
                  </span>
                </div>
              </div>

              <div class="space-y-3">
                <h1 class="text-3xl font-bold tracking-tight text-[var(--title-color)] sm:text-4xl">{post.title}</h1>
                <p class="max-w-3xl text-base leading-8 text-[var(--text-secondary)]">{post.description}</p>
              </div>

              {post.tags?.length > 0 && (
                <div class="flex flex-wrap gap-2">
                  {post.tags.map(tag => (
                    <a
                      href={`/tags?tag=${encodeURIComponent(tag)}`}
                      class="terminal-filter"
                      style={getAccentVars(getTagTheme(tag))}
                    >
                      <i class="fas fa-hashtag"></i>
                      <span>{tag}</span>
                    </a>
                  ))}
                </div>
              )}
            </div>
          </div>

          <div class="px-4 pb-2">
            <CommandPrompt command={`bat --style=plain ${post.slug}.md`} />

            <div class="ml-4 mt-4 space-y-6">
              {post.image && (
                <div class="terminal-panel-muted overflow-hidden">
                  <ResponsiveImage
                    src={resolveFileRef(post.image)}
                    alt={post.title}
                    pictureClass="block"
                    imgClass="w-full h-auto rounded-xl border border-[var(--border-color)] cursor-zoom-in"
                    widths={[640, 960, 1280, 1600, 1920]}
                    sizes="(min-width: 1280px) 60rem, 100vw"
                    loading="eager"
                    fetchpriority="high"
                    lightbox={true}
                  />
                </div>
              )}

              {post.images && post.images.length > 0 && (
                <div class="grid gap-4 sm:grid-cols-2 xl:grid-cols-3">
                  {post.images.map((image, index) => (
                    <div class="terminal-panel-muted overflow-hidden">
                      <ResponsiveImage
                        src={resolveFileRef(image)}
                        alt={`${post.title} 图片 ${index + 1}`}
                        pictureClass="block h-full w-full"
                        imgClass="h-full w-full rounded-xl border border-[var(--border-color)] object-cover cursor-zoom-in"
                        widths={[480, 720, 960, 1280]}
                        sizes="(min-width: 1280px) 30vw, (min-width: 640px) 45vw, 100vw"
                        lightbox={true}
                      />
                    </div>
                  ))}
                </div>
              )}

              {paragraphCommentsEnabled && (
                <ParagraphComments postSlug={post.slug} class="mb-4" siteSettings={siteSettings} />
              )}

              <div class="terminal-document article-content" set:html={renderedContent.code}></div>
            </div>
          </div>

          <div class="px-4 py-6">
            <div class="terminal-panel-muted ml-4 mt-4 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
              <span class="text-sm text-[var(--text-secondary)]">
                file://content/posts/{post.slug}.md
              </span>
              <div class="flex flex-wrap gap-2">
                <a href="/articles" class="terminal-action-button">
                  <i class="fas fa-list"></i>
                  <span>{t('common.backToIndex')}</span>
                </a>
                <button
                  class="terminal-action-button terminal-action-button-primary"
                  onclick={`navigator.clipboard.writeText(window.location.href)`}
                >
                  <i class="fas fa-link"></i>
                  <span>{t('common.copyPermalink')}</span>
                </button>
              </div>
            </div>
          </div>
        </TerminalWindow>

        <RelatedPosts
          currentSlug={post.slug}
          currentCategory={post.category}
          currentTags={post.tags}
        />

        {hotRelatedPosts.length > 0 && (
          <section class="terminal-panel mt-8">
            <div class="space-y-5">
              <div class="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
                <div class="space-y-3">
                  <span class="terminal-kicker">
                    <i class="fas fa-fire"></i>
                    {t('relatedPosts.hotKicker')}
                  </span>
                  <div class="terminal-section-title">
                    <span class="terminal-section-icon">
                      <i class="fas fa-chart-line"></i>
                    </span>
                    <div>
                      <h3 class="text-xl font-semibold text-[var(--title-color)]">{t('relatedPosts.hotTitle')}</h3>
                      <p class="text-sm text-[var(--text-secondary)]">
                        {t('relatedPosts.hotDescription')}
                      </p>
                    </div>
                  </div>
                </div>

                <span class="terminal-stat-pill">
                  <i class="fas fa-signal text-[var(--primary)]"></i>
                  {t('relatedPosts.linked', { count: hotRelatedPosts.length })}
                </span>
              </div>

              <div class="grid gap-4 md:grid-cols-3">
                {hotRelatedPosts.map((item) => (
                  <a
                    href={`/articles/${item.slug}`}
                    class="terminal-panel-muted terminal-panel-accent terminal-interactive-card group flex h-full flex-col gap-4 p-4"
                    style={getAccentVars(getPostTypeTheme(item.post.type))}
                  >
                    {item.post.image ? (
                      <div class="overflow-hidden rounded-xl border border-[var(--border-color)]">
                        <ResponsiveImage
                          src={resolveFileRef(item.post.image)}
                          alt={item.post.title}
                          pictureClass="block"
                          imgClass="aspect-[16/9] w-full object-cover transition-transform duration-300 group-hover:scale-[1.03]"
                          widths={[320, 480, 640, 960]}
                          sizes="(min-width: 1280px) 18rem, (min-width: 768px) 30vw, 100vw"
                        />
                      </div>
                    ) : null}

                    <div class="space-y-3">
                      <div class="flex flex-wrap items-center gap-2">
                        <span class="terminal-chip terminal-chip--accent px-2.5 py-1 text-xs" style={getAccentVars(getPostTypeTheme(item.post.type))}>
                          {item.post.type === 'article' ? t('common.article') : t('common.tweet')}
                        </span>
                        <span class="terminal-chip terminal-chip--accent px-2.5 py-1 text-xs" style={getAccentVars(getCategoryTheme(item.post.category))}>
                          <i class="fas fa-folder-tree text-[11px]"></i>
                          {item.post.category}
                        </span>
                      </div>

                      <h4 class="text-base font-semibold text-[var(--title-color)] group-hover:text-[var(--primary)]">
                        {item.post.title}
                      </h4>
                      <p class="text-sm leading-7 text-[var(--text-secondary)]">{item.post.description}</p>
                    </div>

                    <div class="mt-auto flex flex-wrap gap-2 pt-1">
                      <span class="terminal-stat-pill px-2.5 py-1 text-xs">
                        <i class="fas fa-eye text-[var(--primary)]"></i>
                        {t('home.views')}: {item.pageViews}
                      </span>
                      <span class="terminal-stat-pill px-2.5 py-1 text-xs">
                        <i class="fas fa-check-double text-[var(--primary)]"></i>
                        {t('home.completes')}: {item.readCompletes}
                      </span>
                      <span class="terminal-stat-pill px-2.5 py-1 text-xs">
                        <i class="fas fa-chart-line text-[var(--primary)]"></i>
                        {t('home.avgProgress')}: {Math.round(item.avgProgressPercent)}%
                      </span>
                    </div>

                    {item.sharedTags.length > 0 && (
                      <div class="flex flex-wrap gap-2">
                        {item.sharedTags.slice(0, 3).map((tag) => (
                          <span class="terminal-chip terminal-chip--accent px-2.5 py-1 text-xs" style={getAccentVars(getTagTheme(tag))}>
                            <i class="fas fa-hashtag text-[11px]"></i>
                            {tag}
                          </span>
                        ))}
                      </div>
                    )}
                  </a>
                ))}
              </div>
            </div>
          </section>
        )}

        <section class="mt-8">
          <Comments postSlug={post.slug} class="terminal-panel" siteSettings={siteSettings} />
        </section>
      </div>

      <TableOfContents />
    </div>
  </div>
</BaseLayout>

<script is:inline define:vars={{ postSlug: post.slug }}>
  (() => {
    const endpoint = '/api/analytics/content';
    const sessionStorageKey = `termi:content-session:${postSlug}`;
    const startedAt = Date.now();
    let sentPageView = false;
    let lastReportedProgress = 0;

    function ensureSessionId() {
      try {
        const existing = window.sessionStorage.getItem(sessionStorageKey);
        if (existing) return existing;
        const nextId = crypto.randomUUID();
        window.sessionStorage.setItem(sessionStorageKey, nextId);
        return nextId;
      } catch {
        return `${Date.now()}-${Math.random().toString(36).slice(2)}`;
      }
    }

    function getProgressPercent() {
      const doc = document.documentElement;
      const scrollTop = window.scrollY || doc.scrollTop || 0;
      const scrollHeight = Math.max(doc.scrollHeight - window.innerHeight, 1);
      return Math.max(0, Math.min(100, Math.round((scrollTop / scrollHeight) * 100)));
    }

    function sendEvent(eventType, extras = {}, useBeacon = false) {
      const payload = JSON.stringify({
        event_type: eventType,
        path: window.location.pathname,
        post_slug: postSlug,
        session_id: ensureSessionId(),
        referrer: document.referrer || undefined,
        ...extras,
      });

      if (useBeacon && navigator.sendBeacon) {
        navigator.sendBeacon(endpoint, new Blob([payload], { type: 'application/json' }));
        return;
      }

      fetch(endpoint, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: payload,
        keepalive: true,
      }).catch(() => undefined);
    }

    function reportProgress(forceComplete = false) {
      const progress = forceComplete ? 100 : getProgressPercent();
      const durationMs = Date.now() - startedAt;
      const eventType = forceComplete || progress >= 95 ? 'read_complete' : 'read_progress';

      if (!forceComplete && progress <= lastReportedProgress + 9) {
        return;
      }

      lastReportedProgress = Math.max(lastReportedProgress, progress);
      sendEvent(
        eventType,
        {
          progress_percent: progress,
          duration_ms: durationMs,
          metadata: {
            viewportHeight: window.innerHeight,
          },
        },
        eventType === 'read_complete',
      );
    }

    if (!sentPageView) {
      sentPageView = true;
      sendEvent('page_view', {
        metadata: {
          title: document.title,
        },
      });
    }

    window.addEventListener('scroll', () => {
      reportProgress(false);
    }, { passive: true });

    document.addEventListener('visibilitychange', () => {
      if (document.visibilityState === 'hidden') {
        reportProgress(getProgressPercent() >= 95);
      }
    });

    window.addEventListener('pagehide', () => {
      reportProgress(getProgressPercent() >= 95);
    });
  })();
</script>
