"use client";

import { use } from "react";
import type { ExternalEmbed } from "@/data/queries";
import { LinkPreview } from "./LinkPreview";
import { BlueskyPostEmbed } from "./embeds/BlueskyPostEmbed";
import {
  getBlueskyPost,
  getLinkMetadata,
  type BlueskyPost,
  type LinkMetadata,
} from "./utils/embed-resolver";

type EmbedPromise = Promise<BlueskyPost | LinkMetadata | null>;
export type EmbedCache = Map<string, EmbedPromise>;

type Props = {
  external: ExternalEmbed;
  cache: EmbedCache;
  onDelete?: () => void;
};

function getOrCreatePromise(uri: string, cache: EmbedCache): EmbedPromise {
  const existing = cache.get(uri);
  if (existing) return existing;

  const promise =
    uri.startsWith("at://") || uri.includes("bsky.app")
      ? getBlueskyPost(uri)
      : getLinkMetadata(uri);

  cache.set(uri, promise);
  return promise;
}

export function StopEmbed({ external, cache, onDelete }: Props) {
  if (typeof window === "undefined") {
    throw new Error("Client only");
  }

  const uri = external.uri;
  const isBluesky = uri.startsWith("at://");
  const promise = getOrCreatePromise(uri, cache);
  const data = use(promise);

  if (!data) {
    return (
      <div className="BlueskyPostEmbed-container">
        <div className="BlueskyPostEmbed error">
          <div className="BlueskyPostEmbed-error">couldn't load embed</div>
        </div>
        {onDelete && (
          <button onClick={onDelete} className="BlueskyPostEmbed-deleteButton" title="remove link">
            ×
          </button>
        )}
      </div>
    );
  }

  if (isBluesky) {
    return <BlueskyPostEmbed post={data as BlueskyPost} onDelete={onDelete} />;
  }

  // For links, merge fetched metadata with external data (external may have more recent edits)
  const metadata = data as LinkMetadata;
  const mergedExternal = {
    ...external,
    title: metadata.title || external.title,
    description: metadata.description || external.description,
    thumb: metadata.thumb || external.thumb,
  };

  return <LinkPreview external={mergedExternal} fallbackToUrl onDelete={onDelete} />;
}
