"use client";
import { SWRConfig } from "swr";
import { useReplicache } from "src/replicache";
import useSWR from "swr";
import { callRPC } from "app/api/rpc/client";
import { getPollData } from "actions/pollActions";
import type { GetLeafletDataReturnType } from "app/api/rpc/[command]/get_leaflet_data";
import { createContext, useContext, useMemo } from "react";
import { getPublicationMetadataFromLeafletData } from "src/utils/getPublicationMetadataFromLeafletData";
import {
  getPublicationURL,
  getDocumentURL,
} from "app/lish/createPub/getPublicationURL";
import { AtUri } from "@atproto/syntax";
import {
  normalizeDocumentRecord,
  normalizePublicationRecord,
  type NormalizedDocument,
  type NormalizedPublication,
} from "src/utils/normalizeRecords";

export const StaticLeafletDataContext = createContext<
  null | GetLeafletDataReturnType["result"]["data"]
>(null);
export function PageSWRDataProvider(props: {
  leaflet_id: string;
  leaflet_data: GetLeafletDataReturnType["result"];
  poll_data: Awaited<ReturnType<typeof getPollData>>;
  children: React.ReactNode;
}) {
  return (
    <SWRConfig
      value={{
        fallback: {
          poll_data: props.poll_data,
          [`${props.leaflet_id}-leaflet_data`]: props.leaflet_data.data,
        },
      }}
    >
      {props.children}
    </SWRConfig>
  );
}

export function usePollData() {
  let { permission_token } = useReplicache();
  return useSWR(`poll_data`, () =>
    getPollData(
      permission_token.permission_token_rights.map((pr) => pr.entity_set),
    ),
  );
}

let useLeafletData = () => {
  let { permission_token } = useReplicache();
  let staticLeafletData = useContext(StaticLeafletDataContext);
  let res = useSWR(
    staticLeafletData ? null : `${permission_token.id}-leaflet_data`,
    async () =>
      permission_token.id
        ? (await callRPC("get_leaflet_data", { token_id: permission_token.id }))
            ?.result.data
        : undefined,
  );
  if (staticLeafletData) return { data: staticLeafletData, mutate: res.mutate };
  return res;
};
export function useLeafletPublicationData() {
  let { data, mutate } = useLeafletData();

  // First check for leaflets in publications
  let pubData = getPublicationMetadataFromLeafletData(data);

  // Normalize records so consumers don't have to
  const normalizedPublication = useMemo(
    () => normalizePublicationRecord(pubData?.publications?.record),
    [pubData?.publications?.record],
  );
  const normalizedDocument = useMemo(
    () => normalizeDocumentRecord(pubData?.documents?.data),
    [pubData?.documents?.data],
  );

  return {
    data: pubData || null,
    // Pre-normalized data - consumers should use these instead of normalizing themselves
    normalizedPublication,
    normalizedDocument,
    mutate,
  };
}
export function useLeafletDomains() {
  let { data, mutate } = useLeafletData();
  return { data: data?.custom_domain_routes, mutate: mutate };
}

/**
 * Returns the publication_pages row this leaflet is the source of, if any.
 * Mirrors `draftInPublication` from useLeafletPublicationStatus, but for
 * leaflets that back a publication page rather than a draft post.
 */
export function useLeafletPublicationPage() {
  let { data } = useLeafletData();
  return data?.publication_pages?.[0] ?? null;
}

export function useLeafletPublicationStatus() {
  const data = useContext(StaticLeafletDataContext);
  if (!data) return null;

  const publishedInPublication = data.leaflets_in_publications?.find(
    (l) => l.doc,
  );
  const publishedStandalone = data.leaflets_to_documents?.find(
    (l) => !!l.documents,
  );

  const documentUri =
    publishedInPublication?.documents?.uri ?? publishedStandalone?.document;

  // Compute the full post URL for sharing
  let postShareLink: string | undefined;
  if (
    publishedInPublication?.publications &&
    publishedInPublication.documents
  ) {
    const normalizedDoc = normalizeDocumentRecord(
      publishedInPublication.documents.data,
      publishedInPublication.documents.uri,
    );
    if (normalizedDoc) {
      postShareLink = getDocumentURL(
        normalizedDoc,
        publishedInPublication.documents.uri,
        publishedInPublication.publications,
      );
    }
  } else if (publishedStandalone?.document) {
    const normalizedDoc = publishedStandalone.documents
      ? normalizeDocumentRecord(
          publishedStandalone.documents.data,
          publishedStandalone.document,
        )
      : null;
    if (normalizedDoc) {
      postShareLink = getDocumentURL(
        normalizedDoc,
        publishedStandalone.document,
      );
    } else {
      const docUri = new AtUri(publishedStandalone.document);
      postShareLink = `/p/${docUri.host}/${docUri.rkey}`;
    }
  }

  return {
    token: data,
    leafletId: data.root_entity,
    shareLink: data.id,
    // Draft state - in a publication but not yet published
    draftInPublication:
      data.leaflets_in_publications?.[0]?.publication ?? undefined,
    // Published state
    isPublished: !!(publishedInPublication || publishedStandalone),
    publishedAt:
      publishedInPublication?.documents?.indexed_at ??
      publishedStandalone?.documents?.indexed_at,
    documentUri,
    // Full URL for sharing published posts
    postShareLink,
  };
}
