---
import Layout from "../layouts/Layout.astro";
import HeroSection from "../components/HeroSection.astro";
---

<Layout home>
  <Fragment slot="head">
    <title th:text="${site.title}"></title>
  </Fragment>

  <HeroSection />

  <div
    class="wi-home-content"
    th:classappend="${theme.config?.hero?.hero_enabled != false} ? 'wi-home-content--with-hero'"
    th:attr="data-i18n-all-loaded=#{common.allLoaded},data-i18n-loading=#{common.loading},data-i18n-words=#{common.words},data-i18n-read-time=#{common.readTime},data-i18n-views=#{common.views}"
  >
  <section
    class="wi-home-pinned"
    th:if="${posts != null and !#lists.isEmpty(posts.items)}"
  >
    <div class="wi-container">
      <div class="wi-section__header">
        <h2 class="wi-section__title" th:text="${theme.config?.home?.home_pinned_title ?: #messages.msg('hero.pinned')}">置顶</h2>
      </div>
      <div class="wi-pinned">
        <a
          th:each="post : ${posts.items}"
          th:if="${post.spec.pinned}"
          th:href="@{${post.status.permalink}}"
          class="wi-pinned__card"
        >
          <div
            class="wi-pinned__cover"
            th:if="${!#strings.isEmpty(post.spec.cover)}"
          >
            <img th:src="${post.spec.cover}" th:alt="${post.spec.title}" class="wi-pinned__image" loading="lazy" decoding="async" />
          </div>
          <div class="wi-pinned__body">
            <div class="wi-pinned__meta">
              <span
                class="wi-pinned__category"
                th:if="${!#lists.isEmpty(post.categories)}"
                th:text="${post.categories[0].spec.displayName}"
              ></span>
              <time
                class="wi-pinned__date"
                th:text="${#dates.format(post.spec.publishTime, 'yyyy-MM-dd')}"
              ></time>
            </div>
            <h3
              class="wi-pinned__title"
              th:text="${post.spec.title}"
            ></h3>
            <p
              class="wi-pinned__excerpt"
              th:if="${post.status.excerpt}"
              th:text="${post.status.excerpt}"
            ></p>
          </div>
        </a>
      </div>
    </div>
  </section>

  <section class="wi-home-posts" id="wi-home-posts">
    <div class="wi-container">
      <div class="wi-section__header">
        <h2 class="wi-section__title" th:text="${theme.config?.home?.home_posts_title ?: #messages.msg('hero.posts')}">文章</h2>
      </div>
      <div class="wi-flow" id="wi-post-grid">
        <article
          th:each="post : ${posts.items}"
          th:if="${!post.spec.pinned}"
          class="wi-flow__card"
          th:classappend="${!#strings.isEmpty(post.spec.cover)} ? 'wi-flow__card--with-cover' : ''"
        >
          <a
            class="wi-flow__stretched-link"
            th:href="@{${post.status.permalink}}"
            tabindex="-1"
            aria-hidden="true"
          ></a>
          <div class="wi-flow__body">
            <div class="wi-flow__meta">
              <th:block th:if="${(theme.config?.home?.home_card_show_category ?: true) and !#lists.isEmpty(post.categories)}">
                <span class="wi-flow__categories">
                  <a
                    th:each="cat : ${post.categories}"
                    th:href="@{${cat.status.permalink}}"
                    th:text="${cat.spec.displayName}"
                    class="wi-flow__category-link"
                  ></a>
                </span>
              </th:block>
              <time
                class="wi-flow__date"
                th:text="${#dates.format(post.spec.publishTime, 'yyyy-MM-dd')}"
              ></time>
            </div>
            <a
              th:href="@{${post.status.permalink}}"
              class="wi-flow__title-link"
            >
              <h3
                class="wi-flow__title"
                th:text="${post.spec.title}"
              ></h3>
            </a>
            <p
              class="wi-flow__excerpt"
              th:if="${post.status.excerpt}"
              th:text="${post.status.excerpt}"
              th:style="'-webkit-line-clamp:' + (${theme.config?.home?.home_excerpt_lines ?: 3})"
            ></p>
            <div class="wi-flow__footer">
              <th:block th:if="${(theme.config?.home?.home_card_show_tags ?: true) and post.tags != null and !#lists.isEmpty(post.tags)}">
                <div class="wi-flow__tags">
                  <a
                    th:each="tag : ${post.tags}"
                    th:href="@{${tag.status.permalink}}"
                    th:text="${tag.spec.displayName}"
                    class="wi-flow__tag-link"
                  ></a>
                </div>
              </th:block>
              <div class="wi-flow__stats">
                <span
                  class="wi-flow__stat"
                  th:if="${theme.config?.home?.home_card_show_visit ?: true}"
                >
                  <th:block th:text="${post.stats?.visit ?: 0}"></th:block> <th:block th:text="#{common.views}">阅读</th:block>
                </span>
              </div>
            </div>
          </div>
          <div
            class="wi-flow__cover"
            th:if="${!#strings.isEmpty(post.spec.cover)}"
          >
            <img th:src="${post.spec.cover}" th:alt="${post.spec.title}" class="wi-flow__image" loading="lazy" decoding="async" />
          </div>
        </article>
      </div>

      <nav
        th:if="${posts.totalPages gt 1 and theme.config?.home?.home_post_loading != 'infinite_scroll'}"
        class="wi-pagination"
        id="wi-post-pagination"
        aria-label="Pagination"
      >
        <a
          th:if="${posts.hasPrevious()}"
          th:href="@{${posts.prevUrl}}"
          class="wi-pagination__prev"
          th:text="${theme.config?.home?.home_label_newer ?: #messages.msg('common.newer')}"
        >&larr; 较新</a>
        <span
          class="wi-pagination__info"
          th:text="|${posts.page} / ${posts.totalPages}|"
        ></span>
        <a
          th:if="${posts.hasNext()}"
          th:href="@{${posts.nextUrl}}"
          class="wi-pagination__next"
          th:text="${theme.config?.home?.home_label_older ?: #messages.msg('common.older')}"
        >较旧 &rarr;</a>
      </nav>

      <div
        th:if="${posts.hasNext() and theme.config?.home?.home_post_loading == 'infinite_scroll'}"
        id="wi-infinite-scroll-sentinel"
        th:attr="data-next-url=${posts.nextUrl}, data-all-loaded-text=${theme.config?.home?.home_label_all_loaded ?: #messages.msg('common.allLoaded')}"
      >
        <div class="wi-infinite-scroll__loader">
          <div class="wi-infinite-scroll__spinner"></div>
          <span th:text="${theme.config?.home?.home_label_loading ?: #messages.msg('common.loading')}">加载中...</span>
        </div>
      </div>

      <div
        th:if="${!posts.hasNext() and posts.totalPages gt 1 and theme.config?.home?.home_post_loading == 'infinite_scroll'}"
        class="wi-infinite-scroll__end"
      >
        <span th:text="${theme.config?.home?.home_label_all_loaded ?: #messages.msg('common.allLoaded')}">已加载全部文章</span>
      </div>
    </div>
  </section>
  </div>
</Layout>

<script is:inline>
  (function () {
    var sentinel = document.getElementById("wi-infinite-scroll-sentinel");
    if (!sentinel) return;

    var grid = document.getElementById("wi-post-grid");
    var i18nEl = document.querySelector(".wi-home-content");
    var loading = false;
    var nextUrl = sentinel.getAttribute("data-next-url");
    var allLoadedText = sentinel.getAttribute("data-all-loaded-text") || (i18nEl && i18nEl.getAttribute("data-i18n-all-loaded")) || "All posts loaded";

    var observer = new IntersectionObserver(
      function (entries) {
        if (entries[0].isIntersecting && !loading && nextUrl) {
          loading = true;
          var loader = sentinel.querySelector(".wi-infinite-scroll__loader");
          if (loader) loader.style.display = "flex";

          fetch(nextUrl)
            .then(function (res) {
              if (!res.ok) throw new Error("Fetch failed");
              return res.text();
            })
            .then(function (html) {
              var parser = new DOMParser();
              var doc = parser.parseFromString(html, "text/html");

              var newCards = doc.querySelectorAll("#wi-post-grid .wi-flow__card");
              for (var i = 0; i < newCards.length; i++) {
                var card = newCards[i];
                card.style.opacity = "0";
                card.style.transform = "translateY(20px)";
                grid.appendChild(card);
                (function (c) {
                  requestAnimationFrame(function () {
                    c.style.transition = "opacity 0.4s ease, transform 0.4s ease";
                    c.style.opacity = "1";
                    c.style.transform = "translateY(0)";
                  });
                })(card);
              }

              var newSentinel = doc.getElementById("wi-infinite-scroll-sentinel");
              if (newSentinel && newSentinel.getAttribute("data-next-url")) {
                nextUrl = newSentinel.getAttribute("data-next-url");
              } else {
                nextUrl = null;
                observer.disconnect();
                sentinel.style.display = "none";
                var endMsg = document.createElement("div");
                endMsg.className = "wi-infinite-scroll__end";
                endMsg.innerHTML = "<span>" + allLoadedText + "</span>";
                sentinel.parentNode.appendChild(endMsg);
              }

              loading = false;
              if (loader) loader.style.display = "none";
            })
            .catch(function () {
              loading = false;
              if (loader) loader.style.display = "none";
            });
        }
      },
      { rootMargin: "300px" }
    );

    observer.observe(sentinel);
  })();
</script>

<script is:inline>
  (function () {
    var hero = document.getElementById("wi-hero");
    var blurOverlay = document.getElementById("wi-hero-blur-overlay");
    var heroContent = document.getElementById("wi-hero-content");
    var scrollIndicator = document.getElementById("wi-hero-scroll-indicator");

    if (!hero || !blurOverlay) return;

    var maxBlur = 20;
    var triggerDistance = 300;
    var fadeStart = 200;
    var fadeEnd = 500;
    var ticking = false;

    function onScroll() {
      if (ticking) return;
      ticking = true;
      requestAnimationFrame(function () {
        ticking = false;
        var scrollY = window.scrollY || window.pageYOffset;

        var currentBlur = Math.min(scrollY / triggerDistance * maxBlur, maxBlur);
        blurOverlay.style.backdropFilter = "blur(" + currentBlur + "px)";
        blurOverlay.style.webkitBackdropFilter = "blur(" + currentBlur + "px)";

        if (heroContent) {
          var progress = Math.max(0, Math.min(1, (scrollY - fadeStart) / (fadeEnd - fadeStart)));
          heroContent.style.opacity = String(1 - progress);
          heroContent.style.transform = "translateY(" + (-20 * progress) + "px)";
        }

        if (scrollIndicator) {
          var indicatorProgress = Math.max(0, Math.min(1, (scrollY - fadeStart) / (fadeEnd - fadeStart)));
          scrollIndicator.style.opacity = String(1 - indicatorProgress);
        }
      });
    }

    window.addEventListener("scroll", onScroll, { passive: true });
    onScroll();
  })();
</script>

<script is:inline>
  (function () {
    var hero = document.getElementById("wi-hero");
    var content = document.querySelector(".wi-home-content--with-hero");
    if (!hero || !content) return;

    var isSnapping = false;
    var heroHeight = window.innerHeight;

    window.addEventListener("resize", function () {
      heroHeight = window.innerHeight;
    }, { passive: true });

    function snapTo(targetY) {
      if (isSnapping) return;
      isSnapping = true;
      window.scrollTo({ top: targetY, behavior: "smooth" });
      var timer = setTimeout(function () {
        isSnapping = false;
      }, 800);
      if ("onscrollend" in window) {
        window.addEventListener(
          "scrollend",
          function () {
            clearTimeout(timer);
            isSnapping = false;
          },
          { once: true }
        );
      }
    }

    window.addEventListener("wheel", function (e) {
      if (isSnapping) {
        e.preventDefault();
        return;
      }
      var y = window.scrollY;
      if (y < heroHeight && e.deltaY > 0) {
        e.preventDefault();
        snapTo(heroHeight);
      } else if (y > 0 && y <= heroHeight && e.deltaY < 0) {
        e.preventDefault();
        snapTo(0);
      }
    }, { passive: false });

    var touchStartY = 0;
    window.addEventListener("touchstart", function (e) {
      touchStartY = e.touches[0].clientY;
    }, { passive: true });

    window.addEventListener("touchend", function (e) {
      if (isSnapping) return;
      var diff = touchStartY - e.changedTouches[0].clientY;
      var y = window.scrollY;
      if (y < heroHeight && diff > 30) {
        snapTo(heroHeight);
      } else if (y > 0 && y <= heroHeight && diff < -30) {
        snapTo(0);
      }
    }, { passive: true });
  })();
</script>

<style>
  .wi-home-content {
    position: relative;
    z-index: 1;
    background: var(--bg);
    min-height: 100vh;
    padding-bottom: 2rem;
  }

  .wi-home-content--with-hero {
    margin-top: 100vh;
    margin-top: 100dvh;
  }

  .wi-home-pinned {
    padding-block: 2rem;
    background: var(--bg);
  }

  .wi-home-pinned:not(:has(.wi-pinned__card)) {
    display: none;
  }

  .wi-section__header {
    margin-bottom: var(--space-xl);
  }

  .wi-section__title {
    font-family: var(--font-sans);
    font-size: var(--text-2xl);
    font-weight: 700;
    color: var(--ink);
    letter-spacing: var(--tracking-tight);
    display: flex;
    align-items: center;
    gap: 0.5rem;
  }

  .wi-section__title::before {
    content: '';
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--accent);
    flex-shrink: 0;
  }

  .wi-pinned {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-lg);
  }

  .wi-pinned__card {
    display: flex;
    flex-direction: column;
    border-radius: 16px;
    overflow: hidden;
    background: var(--bg-raised);
    box-shadow: var(--shadow-sm);
    text-decoration: none;
    color: inherit;
    transition:
      transform var(--duration-normal) var(--ease-out-expo),
      box-shadow var(--duration-normal) var(--ease-out-expo);
  }

  .wi-pinned__card:hover {
    transform: translateY(-4px);
    box-shadow: var(--shadow-lg);
  }

  .wi-pinned__card:first-child:nth-last-child(1) {
    grid-column: 1 / -1;
  }

  .wi-pinned__card:first-child:nth-last-child(1) .wi-pinned__cover {
    aspect-ratio: 21 / 9;
  }

  .wi-pinned__card:first-child:nth-last-child(1) .wi-pinned__title {
    font-size: var(--text-2xl);
  }

  .wi-pinned__cover {
    aspect-ratio: 16 / 10;
    overflow: hidden;
  }

  .wi-pinned__image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform var(--duration-normal) var(--ease-out-expo);
    border-radius: 0;
  }

  .wi-pinned__card:hover .wi-pinned__image {
    transform: scale(1.03);
  }

  .wi-pinned__body {
    padding: var(--space-lg);
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    flex: 1;
  }

  .wi-pinned__meta {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    flex-wrap: wrap;
  }

  .wi-pinned__category {
    font-size: var(--text-xs);
    color: var(--accent);
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
    font-weight: 600;
  }

  .wi-pinned__category::after {
    content: '·';
    margin-left: var(--space-sm);
    color: var(--ink-3);
  }

  .wi-pinned__date {
    font-size: var(--text-xs);
    color: var(--ink-3);
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
  }

  .wi-pinned__title {
    font-family: var(--font-sans);
    font-size: var(--text-xl);
    font-weight: 700;
    color: var(--ink);
    line-height: var(--leading-tight);
    letter-spacing: var(--tracking-tight);
    transition: color var(--duration-fast) var(--ease-out-quart);
  }

  .wi-pinned__card:hover .wi-pinned__title {
    color: var(--accent);
  }

  .wi-pinned__excerpt {
    font-size: var(--text-sm);
    color: var(--ink-2);
    line-height: var(--leading-relaxed);
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }

  @media (max-width: 768px) {
    .wi-pinned {
      grid-template-columns: 1fr;
    }

    .wi-pinned__card:first-child:nth-last-child(1) .wi-pinned__cover {
      aspect-ratio: 16 / 9;
    }

    .wi-pinned__card:first-child:nth-last-child(1) .wi-pinned__title {
      font-size: var(--text-xl);
    }
  }

  .wi-home-posts {
    padding-block: 2rem;
    background: var(--bg);
  }

  .wi-flow {
    display: flex;
    flex-direction: column;
    gap: var(--space-lg);
  }

  .wi-flow__card {
    display: flex;
    flex-direction: row;
    align-items: stretch;
    border-radius: 16px;
    overflow: hidden;
    background: var(--bg-raised);
    box-shadow: var(--shadow-sm);
    color: inherit;
    position: relative;
    transition:
      transform var(--duration-normal) var(--ease-out-expo),
      box-shadow var(--duration-normal) var(--ease-out-expo);
  }

  .wi-flow__stretched-link {
    position: absolute;
    inset: 0;
    z-index: 1;
  }

  .wi-flow__card:hover {
    transform: translateY(-4px);
    box-shadow: var(--shadow-lg);
  }

  .wi-flow__card--with-cover .wi-flow__body {
    flex: 1;
    min-width: 0;
  }

  .wi-flow__cover {
    width: 240px;
    flex-shrink: 0;
    overflow: hidden;
  }

  .wi-flow__image {
    width: 100%;
    height: 100%;
    display: block;
    object-fit: cover;
    transition: transform var(--duration-normal) var(--ease-out-expo);
    border-radius: 0;
  }

  .wi-flow__card:hover .wi-flow__image {
    transform: scale(1.03);
  }

  .wi-flow__body {
    padding: var(--space-lg);
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    flex: 1;
    justify-content: center;
  }

  .wi-flow__meta {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    flex-wrap: wrap;
  }

  .wi-flow__categories {
    font-size: var(--text-xs);
    letter-spacing: var(--tracking-wide);
    font-weight: 600;
  }

  .wi-flow__categories::after {
    content: '·';
    margin-left: var(--space-sm);
    margin-right: var(--space-sm);
    color: var(--ink-3);
  }

  .wi-flow__category-link {
    color: var(--accent);
    text-decoration: none;
    position: relative;
    z-index: 2;
    transition: color var(--duration-fast) var(--ease-out-quart);
  }

  .wi-flow__category-link:hover {
    color: var(--accent-hover);
    text-decoration: underline;
  }

  .wi-flow__category-link + .wi-flow__category-link::before {
    content: '、';
    color: var(--accent);
  }

  .wi-flow__date {
    font-size: var(--text-xs);
    color: var(--ink-3);
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
  }

  .wi-flow__title-link {
    text-decoration: none;
    position: relative;
    z-index: 2;
  }

  .wi-flow__title {
    font-family: var(--font-sans);
    font-size: var(--text-lg);
    font-weight: 700;
    color: var(--ink);
    line-height: var(--leading-tight);
    letter-spacing: var(--tracking-tight);
    transition: color var(--duration-fast) var(--ease-out-quart);
  }

  .wi-flow__card:hover .wi-flow__title {
    color: var(--accent);
  }

  .wi-flow__excerpt {
    font-size: var(--text-sm);
    color: var(--ink-2);
    line-height: var(--leading-relaxed);
    display: -webkit-box;
    -webkit-box-orient: vertical;
    overflow: hidden;
    margin-block-end: 0;
  }

  .wi-flow__footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-top: auto;
    padding-top: var(--space-xs);
  }

  .wi-flow__tags {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
  }

  .wi-flow__tag-link {
    font-size: 11px;
    color: var(--ink-3);
    text-decoration: none;
    padding: 2px 8px;
    border-radius: 4px;
    background: var(--bg);
    border: 1px solid var(--rule);
    position: relative;
    z-index: 2;
    transition: color var(--duration-fast) var(--ease-out-quart), border-color var(--duration-fast) var(--ease-out-quart), background var(--duration-fast) var(--ease-out-quart);
    white-space: nowrap;
  }

  .wi-flow__tag-link:hover {
    color: var(--accent);
    border-color: var(--accent);
    background: color-mix(in srgb, var(--accent) 6%, var(--bg));
  }

  .wi-flow__stats {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: var(--text-xs);
    color: var(--ink-3);
    white-space: nowrap;
  }

  .wi-flow__stat + .wi-flow__stat::before {
    content: '·';
    margin-right: 0.5rem;
    color: var(--ink-3);
  }

  .wi-pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding-top: var(--space-xl);
    margin-top: var(--space-xl);
    border-top: 1px solid var(--rule);
    font-size: var(--text-sm);
  }

  .wi-pagination__prev,
  .wi-pagination__next {
    color: var(--ink-2);
    text-decoration: none;
    transition: color var(--duration-fast) var(--ease-out-quart);
  }

  .wi-pagination__prev:hover,
  .wi-pagination__next:hover {
    color: var(--accent);
  }

  .wi-pagination__info {
    color: var(--ink-3);
  }

  .wi-infinite-scroll__loader {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-sm);
    padding: var(--space-xl) 0;
    color: var(--ink-3);
    font-size: var(--text-sm);
  }

  .wi-infinite-scroll__spinner {
    width: 18px;
    height: 18px;
    border: 2px solid var(--rule);
    border-top-color: var(--accent);
    border-radius: 50%;
    animation: wi-spin 0.6s linear infinite;
  }

  @keyframes wi-spin {
    to {
      transform: rotate(360deg);
    }
  }

  .wi-infinite-scroll__end {
    text-align: center;
    padding: var(--space-xl) 0;
    color: var(--ink-3);
    font-size: var(--text-sm);
  }

  @media (max-width: 640px) {
    .wi-flow__card {
      flex-direction: column;
    }

    .wi-flow__cover {
      width: 100%;
      aspect-ratio: 16 / 9;
    }

    .wi-flow__footer {
      flex-direction: column;
      align-items: flex-start;
      gap: 0.4rem;
    }
  }
</style>
