import { IN_APP_LINK_DOMAINS } from "/js/config.js";
import { createEmbedFromPost } from "/js/dataHelpers.js";

// e.g. https://bsky.app/profile/gracekind.net/post/3m63ewg5nws23
const RECORD_LINK_PATTERNS = [
  {
    pattern: /^\/profile\/([a-zA-Z0-9:.-]+)\/post\/([a-zA-Z0-9.-]+)$/,
    collection: "app.bsky.feed.post",
  },
  {
    pattern: /^\/profile\/([a-zA-Z0-9:.-]+)\/feed\/([a-zA-Z0-9.-]+)$/,
    collection: "app.bsky.feed.generator",
  },
  {
    pattern: /^\/profile\/([a-zA-Z0-9:.-]+)\/lists\/([a-zA-Z0-9.-]+)$/,
    collection: "app.bsky.graph.list",
  },
  {
    pattern: /^\/profile\/([a-zA-Z0-9:.-]+)\/starter-pack\/([a-zA-Z0-9.-]+)$/,
    collection: "app.bsky.graph.starterpack",
  },
  {
    pattern: /^\/starter-pack\/([a-zA-Z0-9:.-]+)\/([a-zA-Z0-9.-]+)$/,
    collection: "app.bsky.graph.starterpack",
  },
];

// E.g. https://bsky.app/profile/gracekind.net/post/3m63ewg5nws23
// -> { collection: "app.bsky.feed.post", didOrHandle: "gracekind.net", rkey: "3m63ewg5nws23" }
export function parseRecordLink(url) {
  try {
    const parsedUrl = new URL(url);
    if (!IN_APP_LINK_DOMAINS.includes(parsedUrl.hostname)) {
      return null;
    }
    for (const { pattern, collection } of RECORD_LINK_PATTERNS) {
      const match = pattern.exec(parsedUrl.pathname);
      if (match) {
        return { collection, didOrHandle: match[1], rkey: match[2] };
      }
    }
    return null;
  } catch (error) {
    return null;
  }
}

export async function resolveRecordFromLink(
  url,
  { identityResolver, dataLayer },
) {
  const parsedLink = parseRecordLink(url);
  if (!parsedLink) {
    throw new Error(`Not a record link: ${url}`);
  }
  const { collection, didOrHandle, rkey } = parsedLink;
  const did = didOrHandle.startsWith("did:")
    ? didOrHandle
    : await identityResolver.resolveHandle(didOrHandle);
  const recordUri = `at://${did}/${collection}/${rkey}`;
  if (collection === "app.bsky.feed.post") {
    const post = await dataLayer.declarative.ensurePost(recordUri);
    return createEmbedFromPost(post);
  } else if (collection === "app.bsky.feed.generator") {
    const view = await dataLayer.declarative.ensureFeedGenerator(recordUri);
    return { ...view, $type: "app.bsky.feed.defs#generatorView" };
  } else if (collection === "app.bsky.graph.list") {
    const view = await dataLayer.declarative.ensureList(recordUri);
    return { ...view, $type: "app.bsky.graph.defs#listView" };
  }
  const view = await dataLayer.declarative.ensureStarterPack(recordUri);
  return { ...view, $type: "app.bsky.graph.defs#starterPackViewBasic" };
}
