import { useEffect } from "react";
import { LoaderFunctionArgs, useLoaderData, Link } from "react-router";
import { Helmet } from "react-helmet-async";
import {
  ICONS_PREPEND,
  IS_ARCHIVER_ENABLED,
  KEMONO_SITE,
  SITE_NAME,
} from "#env/env-vars";
import { fetchArtistProfile } from "#api/profiles";
import { fetchPostRevision, fetchPostComments } from "#api/posts";
import { PageSkeleton } from "#components/pages";
import { SliderAd } from "#components/advs";
import { paysites, validatePaysite } from "#entities/paysites";
import {
  IComment,
  IPost,
  IPostAttachment,
  IPostPreview,
  IPostVideo,
  PostOverview,
} from "#entities/posts";
import { IArtistDetails } from "#entities/profiles";

import * as styles from "./post-revision.module.scss";

interface IProps {
  post: IPost;
  profile: IArtistDetails;
  revisions: Awaited<
    ReturnType<typeof fetchPostRevision>
  >["props"]["revisions"];
  flagged: string | null;
  videos?: IPostVideo[];
  attachments?: IPostAttachment[];
  previews?: IPostPreview[];
  archives_enabled?: boolean;
  comments: Promise<IComment[]>;
}

export function PostRevisionPage() {
  const {
    post,
    profile,
    revisions,
    flagged,
    videos,
    attachments,
    previews,
    archives_enabled,
    comments,
  } = useLoaderData() as IProps;
  const paysite = paysites[post.service];
  const postTitle = post.title ?? "Untitled";
  const artistName = profile.name ?? post.user;

  const title = !profile
    ? `Post "${postTitle}"`
    : `Post "${postTitle}" by "${artistName}" from ${paysite.title}`;

  function handlePrevNextLinks(event: KeyboardEvent) {
    switch (event.key) {
      case "ArrowLeft":
        document
          .querySelector<HTMLAnchorElement>(".post__nav-link.prev")
          ?.click();
        break;
      case "ArrowRight":
        document
          .querySelector<HTMLAnchorElement>(".post__nav-link.next")
          ?.click();
        break;
    }
  }

  useEffect(() => {
    document.addEventListener("keydown", handlePrevNextLinks);

    return () => {
      document.removeEventListener("keydown", handlePrevNextLinks);
    };
  }, []);

  return (
    <PageSkeleton name="post" title={title}>
      <Helmet>
        <meta name="service" content={post.service} />
        <meta name="id" content={post.id} />
        <meta name="user" content={post.user} />
        {!post.published ? undefined : (
          <meta name="published" content={post.published} />
        )}

        {/* <link rel="canonical" href="{{ g.canonical_url }}" /> */}

        <meta property="og:title" content={title} />
        <meta property="og:type" content="website" />
        <meta property="og:site_name" content={SITE_NAME} />
        <meta
          property="og:image"
          content={`${ICONS_PREPEND ?? KEMONO_SITE}/icons/${post.service}/${
            post.user
          }`}
        />
        {/* <meta property="og:url" content="{{ g.canonical_url }}" /> */}
      </Helmet>

      <SliderAd />

      <nav className="post__nav-links">
        <ul className="post__nav-list">
          {!post.prev ? (
            <li className="post__nav-item subtitle">‹ previous</li>
          ) : (
            <li className="post__nav-item">
              <Link
                className="post__nav-link prev"
                to={`/${post.service}/user/${post.user}/post/${post.prev}`}
              >
                ‹ previous
              </Link>
            </li>
          )}

          {!post.next ? (
            <li className="post__nav-item subtitle">next ›</li>
          ) : (
            <li className="post__nav-item">
              <Link
                className="post__nav-link next"
                to={`/${post.service}/user/${post.user}/post/${post.next}`}
              >
                next ›
              </Link>
            </li>
          )}
        </ul>
      </nav>

      <PostOverview
        post={post}
        profile={profile}
        flagged={flagged}
        videos={videos}
        attachments={attachments}
        previews={previews}
        archives_enabled={archives_enabled}
        postTitle={postTitle}
        paysite={paysite}
        // @ts-expect-error TODO: refactor something
        revisions={revisions}
      />
    </PageSkeleton>
  );
}

export async function loader({ params }: LoaderFunctionArgs): Promise<IProps> {
  const service = params.service?.trim();
  {
    if (!service) {
      throw new Error("Service is required.");
    }

    validatePaysite(service);
  }

  const profileID = params.creator_id?.trim();
  {
    if (!profileID) {
      throw new Error("Profile ID is required.");
    }
  }

  const postID = params.post_id?.trim();
  {
    if (!postID) {
      throw new Error("Post ID is required.");
    }
  }

  const revisionID = params.revision_id?.trim();
  {
    if (!revisionID) {
      throw new Error("Revision ID is required.");
    }
  }

  const profile = await fetchArtistProfile(service, profileID);
  const { post, result_attachments, result_previews, videos, props } =
    await fetchPostRevision(service, profileID, postID, revisionID);
  const { flagged, revisions } = props;

  const comments = fetchPostComments(service, profileID, postID);

  const pageProps = {
    profile,
    post,
    revisions,
    attachments: result_attachments,
    previews: result_previews,
    videos,
    archives_enabled: IS_ARCHIVER_ENABLED,
    flagged,
    comments,
  } satisfies IProps;

  return pageProps;
}
