import { ChecklistBlock } from "@/components/resources/ChecklistBlock";
import { Alert } from "@/components/ui/Icons";
import type { ArticleBlock } from "@/content/types";
import { cn } from "@/lib/cn";
import { renderInline } from "@/lib/inline";
import { slugify } from "@/lib/text";

export function headingsFrom(blocks: ArticleBlock[]): { id: string; text: string }[] {
  return blocks.flatMap((block) => (block.type === "h2" ? [{ id: slugify(block.text), text: block.text }] : []));
}

export function ArticleBody({ blocks, slug }: { blocks: ArticleBlock[]; slug: string }) {
  return (
    <div className="article-body">
      {blocks.map((block, index) => {
        switch (block.type) {
          case "h2":
            return (
              <h2 key={index} id={slugify(block.text)} className="mt-16 scroll-mt-28 text-[1.75rem] font-medium leading-tight tracking-[-0.025em] first:mt-0">
                {block.text}
              </h2>
            );
          case "h3":
            return (
              <h3 key={index} className="mt-10 text-[1.25rem] font-medium leading-snug tracking-[-0.015em]">
                {block.text}
              </h3>
            );
          case "p":
            return (
              <p key={index} className="mt-5 text-[1.0625rem] leading-[1.75] text-ink-soft">
                {renderInline(block.text)}
              </p>
            );
          case "ul":
          case "ol": {
            const List = block.type;
            return (
              <List key={index} className={cn("mt-5 space-y-2.5 text-[1.0625rem] leading-[1.7] text-ink-soft", block.type === "ol" ? "list-decimal pl-6" : "")}>
                {block.items.map((item) => (
                  <li key={item} className={block.type === "ul" ? "relative pl-6" : "pl-1"}>
                    {block.type === "ul" ? <span aria-hidden="true" className="absolute left-0 top-[0.7em] size-1.5 bg-signal" /> : null}
                    {renderInline(item)}
                  </li>
                ))}
              </List>
            );
          }
          case "checklist":
            return <ChecklistBlock key={index} storageKey={`axidys-${slug}-${index}`} title={block.title} items={block.items} />;
          case "callout":
            return (
              <aside
                key={index}
                className={cn(
                  "mt-8 rounded-lg border p-5 sm:p-6",
                  block.tone === "warning" ? "border-ink/20 bg-sand" : "border-signal/20 bg-signal-mist/60",
                )}
              >
                <p className="flex items-center gap-2 text-label uppercase text-ink">
                  {block.tone === "warning" ? <Alert size={14} /> : <span aria-hidden="true" className="size-1.5 bg-signal" />}
                  {block.title ?? (block.tone === "warning" ? "Watch out" : "Note")}
                </p>
                <p className="mt-2.5 text-[1rem] leading-relaxed text-ink">{renderInline(block.text)}</p>
              </aside>
            );
          case "formula":
            return (
              <figure key={index} className="mt-8 rounded-lg border border-line bg-surface p-6 text-center">
                <figcaption className="text-label uppercase text-muted">{block.label}</figcaption>
                <p className="mt-3 font-mono text-[1.0625rem] leading-relaxed text-ink sm:text-lg">{block.expression}</p>
                {block.note ? <p className="mx-auto mt-3 max-w-lg text-sm text-muted">{renderInline(block.note)}</p> : null}
              </figure>
            );
          case "table":
            return (
              <div key={index} className="mt-8 overflow-x-auto rounded-lg border border-line bg-surface">
                <table className="w-full min-w-[34rem] border-collapse text-left text-[0.9375rem]">
                  {block.caption ? <caption className="border-b border-line px-5 py-3 text-left text-label uppercase text-muted">{block.caption}</caption> : null}
                  <thead>
                    <tr className="border-b border-ink/60">
                      {block.columns.map((column) => (
                        <th key={column} scope="col" className="px-5 py-3 font-semibold">
                          {column}
                        </th>
                      ))}
                    </tr>
                  </thead>
                  <tbody>
                    {block.rows.map((row, rowIndex) => (
                      <tr key={rowIndex} className="border-b border-line align-top last:border-b-0">
                        {row.map((cell, cellIndex) =>
                          cellIndex === 0 ? (
                            <th key={cellIndex} scope="row" className="px-5 py-3 font-medium">
                              {renderInline(cell)}
                            </th>
                          ) : (
                            <td key={cellIndex} className="px-5 py-3 text-ink-soft">
                              {renderInline(cell)}
                            </td>
                          ),
                        )}
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            );
          case "example":
            return (
              <figure key={index} className="mt-8 rounded-lg bg-ink p-6 text-paper sm:p-7">
                <div className="flex flex-wrap items-center justify-between gap-3">
                  <figcaption className="font-medium">{block.title}</figcaption>
                  <span className="rounded-sm border border-night-line px-2 py-1 font-mono text-data uppercase tracking-[0.1em] text-night-muted">
                    Hypothetical numbers
                  </span>
                </div>
                <ul className="mt-4 space-y-1.5 font-mono text-[0.875rem] leading-relaxed text-paper/90">
                  {block.lines.map((line) => (
                    <li key={line}>{line}</li>
                  ))}
                </ul>
                {block.note ? <p className="mt-4 border-t border-night-line pt-3 text-sm text-night-muted">{block.note}</p> : null}
              </figure>
            );
        }
      })}
    </div>
  );
}
