---
import Layout from "@layouts/Layout.astro";
import Header from "@components/Header.astro";
import Footer from "@components/Footer.astro";
import Tag from "@components/Tag.astro";
import Datetime from "@components/Datetime";
import type { CollectionEntry } from "astro:content";
import { slugifyStr } from "@utils/slugify";
import { SITE } from "@config";
import {render} from 'astro:content'

export interface Props {
  post: CollectionEntry<"blog">;
  posts: CollectionEntry<"blog">[];
}

const { post, posts } = Astro.props;

const {
  title,
  author,
  description,
  ogImage,
  canonicalURL,
  pubDatetime,
  modDatetime,
  tags,
  editPost,
} = post.data;

const { Content } = await render(post)

const ogImageUrl = typeof ogImage === "string" ? ogImage : ogImage?.src;
const ogUrl = new URL(
  ogImageUrl ?? `/posts/${slugifyStr(title)}.png`,
  Astro.url.origin
).href;

const layoutProps = {
  title: `${title} | ${SITE.title}`,
  author,
  description,
  pubDatetime,
  modDatetime,
  canonicalURL,
  ogImage: ogUrl,
  scrollSmooth: true,
};

/* ========== Prev/Next Posts ========== */

const allPosts = posts.map(({ data: { title }, id }) => ({
  id,
  title,
}));

const currentPostIndex = allPosts.findIndex(a => a.id === post.id);

const prevPost = currentPostIndex !== 0 ? allPosts[currentPostIndex - 1] : null;
const nextPost =
  currentPostIndex !== allPosts.length ? allPosts[currentPostIndex + 1] : null;
---

<Layout {...layoutProps}>
  <Header />

  <div class="mx-auto flex w-full max-w-3xl justify-start px-2">
    <button
      class="focus-outline mb-2 mt-8 flex hover:opacity-75"
      onclick="(() => (history.length === 1) ? window.location = '/' : history.back())()"
    >
      <svg xmlns="http://www.w3.org/2000/svg"
        ><path
          d="M13.293 6.293 7.586 12l5.707 5.707 1.414-1.414L10.414 12l4.293-4.293z"
        ></path>
      </svg><span>Go back</span>
    </button>
  </div>
  <main id="main-content">
    <h1 transition:name={slugifyStr(title)} class="post-title inline-block">{title}</h1>
    <Datetime
      pubDatetime={pubDatetime}
      modDatetime={modDatetime}
      size="lg"
      className="my-2"
      editPost={editPost}
      postId={post.id}
    />
    <article id="article" class="prose mx-auto mt-8 max-w-3xl">
      <Content />
    </article>

    <ul class="my-8">
      {tags.map(tag => <Tag tag={tag} />)}
    </ul>

    <div
      class="flex flex-col-reverse items-center justify-between gap-6 sm:flex-row-reverse sm:items-end sm:gap-4"
    >
      <button
        id="back-to-top"
        class="focus-outline whitespace-nowrap py-1 hover:opacity-75"
      >
        <svg xmlns="http://www.w3.org/2000/svg" class="rotate-90">
          <path
            d="M13.293 6.293 7.586 12l5.707 5.707 1.414-1.414L10.414 12l4.293-4.293z"
          ></path>
        </svg>
        <span>Back to Top</span>
      </button>

    </div>

    <hr class="my-6 border-dashed" />

    <!-- Previous/Next Post Buttons -->
    <div class="grid grid-cols-1 gap-6 sm:grid-cols-2">
      {
        prevPost && (
          <a
            href={`/posts/${prevPost.id}`}
            class="flex w-full gap-1 hover:opacity-75"
          >
            <svg
              xmlns="http://www.w3.org/2000/svg"
              width="24"
              height="24"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
              class="icon icon-tabler icons-tabler-outline icon-tabler-chevron-left flex-none"
            >
              <>
                <path stroke="none" d="M0 0h24v24H0z" fill="none" />
                <path d="M15 6l-6 6l6 6" />
              </>
            </svg>
            <div>
              <span>Previous Post</span>
              <div class="text-sm text-skin-accent/85">{prevPost.title}</div>
            </div>
          </a>
        )
      }
      {
        nextPost && (
          <a
            href={`/posts/${nextPost.id}`}
            class="flex w-full justify-end gap-1 text-right hover:opacity-75 sm:col-start-2"
          >
            <div>
              <span>Next Post</span>
              <div class="text-sm text-skin-accent/85">{nextPost.title}</div>
            </div>
            <svg
              xmlns="http://www.w3.org/2000/svg"
              width="24"
              height="24"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
              class="icon icon-tabler icons-tabler-outline icon-tabler-chevron-right flex-none"
            >
              <>
                <path stroke="none" d="M0 0h24v24H0z" fill="none" />
                <path d="M9 6l6 6l-6 6" />
              </>
            </svg>
          </a>
        )
      }
    </div>
  </main>
  <Footer />
</Layout>

<style>
  main {
    @apply mx-auto w-full max-w-3xl px-4 pb-12;
  }
  .post-title {
    @apply text-2xl font-semibold text-skin-accent;
  }
</style>

<script is:inline data-astro-rerun>
  /** Create a progress indicator
   *  at the top */
  function createProgressBar() {
    // Create the main container div
    const progressContainer = document.createElement("div");
    progressContainer.className =
      "progress-container fixed top-0 z-10 h-1 w-full bg-skin-fill";

    // Create the progress bar div
    const progressBar = document.createElement("div");
    progressBar.className = "progress-bar h-1 w-0 bg-skin-accent";
    progressBar.id = "myBar";

    // Append the progress bar to the progress container
    progressContainer.appendChild(progressBar);

    // Append the progress container to the document body or any other desired parent element
    document.body.appendChild(progressContainer);
  }
  createProgressBar();

  /** Update the progress bar
   *  when user scrolls */
  function updateScrollProgress() {
    document.addEventListener("scroll", () => {
      const winScroll =
        document.body.scrollTop || document.documentElement.scrollTop;
      const height =
        document.documentElement.scrollHeight -
        document.documentElement.clientHeight;
      const scrolled = (winScroll / height) * 100;
      if (document) {
        const myBar = document.getElementById("myBar");
        if (myBar) {
          myBar.style.width = scrolled + "%";
        }
      }
    });
  }
  updateScrollProgress();

  /** Attaches links to headings in the document,
   *  allowing sharing of sections easily */
  function addHeadingLinks() {
    const headings = Array.from(
      document.querySelectorAll("h2, h3, h4, h5, h6")
    );
    for (const heading of headings) {
      heading.classList.add("group");
      const link = document.createElement("a");
      link.className =
        "heading-link ml-2 opacity-0 group-hover:opacity-100 focus:opacity-100";
      link.href = "#" + heading.id;

      const span = document.createElement("span");
      span.ariaHidden = "true";
      span.innerText = "#";
      link.appendChild(span);
      heading.appendChild(link);
    }
  }
  addHeadingLinks();

  /** Attaches copy buttons to code blocks in the document,
   * allowing users to copy code easily. */
  function attachCopyButtons() {
    const copyButtonLabel = "Copy";
    const codeBlocks = Array.from(document.querySelectorAll("pre"));

    for (const codeBlock of codeBlocks) {
      const wrapper = document.createElement("div");
      wrapper.style.position = "relative";

      const copyButton = document.createElement("button");
      copyButton.className =
        "copy-code absolute right-3 -top-3 rounded bg-skin-card px-2 py-1 text-xs leading-4 text-skin-base font-medium";
      copyButton.innerHTML = copyButtonLabel;
      codeBlock.setAttribute("tabindex", "0");
      codeBlock.appendChild(copyButton);

      // wrap codebock with relative parent element
      codeBlock?.parentNode?.insertBefore(wrapper, codeBlock);
      wrapper.appendChild(codeBlock);

      copyButton.addEventListener("click", async () => {
        await copyCode(codeBlock, copyButton);
      });
    }

    async function copyCode(block, button) {
      const code = block.querySelector("code");
      const text = code?.innerText;

      await navigator.clipboard.writeText(text ?? "");

      // visual feedback that task is completed
      button.innerText = "Copied";

      setTimeout(() => {
        button.innerText = copyButtonLabel;
      }, 700);
    }
  }
  attachCopyButtons();

  /** Scrolls the document to the top when
   * the "Back to Top" button is clicked. */
  function backToTop() {
    document.querySelector("#back-to-top")?.addEventListener("click", () => {
      document.body.scrollTop = 0; // For Safari
      document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera
    });
  }
  backToTop();

  /* Go to page start after page swap */
  document.addEventListener("astro:after-swap", () =>
    window.scrollTo({ left: 0, top: 0, behavior: "instant" })
  );
</script>
