import { cache, ReactElement } from "react";
import { ActionMenu } from "@/app/components/action-menu";
import { Metadata } from "next";
import moment from "moment";
import { notFound } from "next/navigation";
import { CodeBlock } from "@/app/components/code-block";
import { detectLanguage } from "@/app/common/lang-detection/detection";

type PasteProps = {
  params: {
    id: string;
  };
};

type Paste = {
  /**
   * The paste content.
   */
  content: string;

  /**
   * The date the paste was created.
   */
  created: string;

  /**
   * The detected language of the paste.
   */
  language: string;
};

const getPaste = cache(async (id: string) => {
  const response: Response = await fetch(
    `${process.env.NEXT_PUBLIC_API_ENDPOINT}/${id}`,
    {
      next: {
        revalidate: 300, // Keep this response cached for 5 minutes
      },
    },
  );
  const json = await response.json();

  if (json.code && json.message) {
    return undefined;
  }
  return {
    content: json.content,
    created: json.created,
    language: await detectLanguage(json.content),
  };
}) as (id: string) => Promise<Paste | undefined>;

export async function generateMetadata({
  params: { id },
}: PasteProps): Promise<Metadata> {
  const data: Paste | undefined = await getPaste(id);
  if (data == undefined) {
    return {
      description: "Not found",
    };
  }
  const created = moment(data.created)
    .format("MMMM Do YYYY, h:mm:ss a")
    .toString();

  return {
    title: `Paste - ${id}.${data.language}`,
    description: `Created: ${created}\n\nClick to view the paste.`,
  };
}

export default async function Paste({
  params: { id },
}: PasteProps): Promise<ReactElement> {
  const data: Paste | undefined = await getPaste(id);

  if (data == undefined) {
    return notFound();
  }

  const created = moment(data.created)
    .format("MMMM Do YYYY, h:mm:ss a")
    .toString();

  return (
    <div className="relative h-full">
      <div className="absolute top-0 right-0 flex flex-col items-end mx-3 mt-2">
        <ActionMenu />
      </div>

      <div className="absolute right-0 bottom-0 text-right p-1.5">
        <p>{data.language}</p>
        <p>{created}</p>
      </div>

      <div className="p-1 hljs !bg-transparent text-sm">
        <CodeBlock code={data.content} language={data.language} />
      </div>
    </div>
  );
}
