/*
  blog-content.tsx
  spboucher.ai Web
  Author: Simon-Pierre Boucher
  Mail: contact@spboucher.ai
*/

import katex from "katex";
import "katex/dist/katex.min.css";

import type { BlogBlock } from "@/lib/blog";

function renderTex(tex: string, displayMode: boolean): string {
  return katex.renderToString(tex, {
    displayMode,
    throwOnError: false,
    strict: false,
  });
}

/** Render the **bold** and inline-math \( ... \) spans used by the essays. */
function renderInline(text: string) {
  return text.split(/(\*\*[^*]+\*\*|\\\(.+?\\\))/g).map((part, i) => {
    if (part.startsWith("**") && part.endsWith("**")) {
      return (
        <strong key={i} className="font-semibold text-foreground">
          {part.slice(2, -2)}
        </strong>
      );
    }
    if (part.startsWith("\\(") && part.endsWith("\\)")) {
      return (
        <span
          key={i}
          dangerouslySetInnerHTML={{
            __html: renderTex(part.slice(2, -2).trim(), false),
          }}
        />
      );
    }
    return <span key={i}>{part}</span>;
  });
}

/** Long-form essay body with sharp editorial typography. */
export function BlogContent({ blocks }: { blocks: BlogBlock[] }) {
  let paragraphIndex = 0;

  return (
    <div className="space-y-5">
      {blocks.map((block, i) => {
        switch (block.type) {
          case "math":
            return (
              <div
                key={i}
                className="overflow-x-auto border-y border-border bg-muted/40 px-5 py-4 text-foreground/90"
                dangerouslySetInnerHTML={{
                  __html: renderTex(block.tex, true),
                }}
              />
            );
          case "h2":
            return (
              <div key={i} className="pt-7">
                <span
                  aria-hidden="true"
                  className="block h-1 w-10 rounded-full bg-gradient-to-r from-primary to-primary/30"
                />
                <h2 className="mt-4 font-display text-2xl font-bold tracking-tight">
                  {block.text}
                </h2>
              </div>
            );
          case "quote":
            return (
              <blockquote
                key={i}
                className="border-l-2 border-primary/60 pl-5 font-display text-xl font-medium leading-snug tracking-tight text-foreground/90"
              >
                {renderInline(block.text)}
              </blockquote>
            );
          case "ul":
            return (
              <ul key={i} className="space-y-2 pl-1">
                {block.items.map((item) => (
                  <li
                    key={item}
                    className="flex items-start gap-3 leading-relaxed text-muted-foreground"
                  >
                    <span
                      aria-hidden="true"
                      className="mt-[0.6em] h-1.5 w-1.5 shrink-0 rounded-full bg-primary/70"
                    />
                    <span>{renderInline(item)}</span>
                  </li>
                ))}
              </ul>
            );
          case "p": {
            paragraphIndex += 1;
            const isLead = paragraphIndex === 1;
            return (
              <p
                key={i}
                className={
                  isLead
                    ? "text-lg leading-relaxed text-foreground/90 sm:text-xl"
                    : "leading-relaxed text-muted-foreground"
                }
              >
                {renderInline(block.text)}
              </p>
            );
          }
        }
      })}
    </div>
  );
}
