import { resolveDid, resolveHandle } from "../common/identity.ts";
import { VIDEO_PATTERN } from "../common/routes.ts";

type BlobRef = {
  $type: "blob";
  ref: { $link: string };
  mimeType?: string;
  size?: number;
};
type VideoRecord = { video: BlobRef; title?: string; description?: string };

const fetchVideoRecord = async (
  did: string,
  rkey: string
): Promise<VideoRecord> => {
  // TODO: we do lots of casting here that we shouldn't need once we have lexicon.ts validations

  const didDoc = await resolveDid(did);
  const pds = didDoc.service?.find((it) => it.id === "#atproto_pds")
    ?.serviceEndpoint as string | undefined;

  if (!pds) throw new Error("could not resolve pds for requested repo");

  const getRecordURL = new URL("/xrpc/com.atproto.repo.getRecord", pds);
  getRecordURL.searchParams.set("collection", "blue.cerulea.video.video");
  getRecordURL.searchParams.set("repo", did);
  getRecordURL.searchParams.set("rkey", rkey);

  const recordResponse = await fetch(getRecordURL);
  if (recordResponse.status !== 200)
    throw new Error("got error fetching record");

  const record = (await recordResponse.json()).value as VideoRecord;
  return record;
};

const resolveVideoURL = async (did: string, blob: string): Promise<string> => {
  const res = await fetch("/xrpc/blue.cerulea.video.fetchVideo", {
    method: "POST",
    headers: { "content-encoding": "application/json" },
    body: JSON.stringify({ repo: did, blob }),
  }).then((r) => r.json());
  return `/user-content/${res.filename}`;
};

const main = async () => {
  const player = document.querySelector("#player")! as HTMLElement;

  const location = VIDEO_PATTERN.exec(globalThis.location.href);
  if (!location) throw new Error("video pattern did not match url");
  const { repo, rkey } = location.pathname.groups as {
    repo: string;
    rkey: string;
  };

  const did = repo.startsWith("did:") ? repo : await resolveHandle(repo);

  const video = await fetchVideoRecord(did, rkey);
  const videoURL = await resolveVideoURL(did, video.video.ref.$link);

  player.append(
    <video crossOrigin="anonymous" controls>
      <source src={videoURL} />
    </video>
  );

  if (video.title) {
    player.append(<h1>{video.title}</h1>);
    document.title = `${video.title} | video.cerulea.blue`;
  }
  if (video.description)
    player.append(<p className="description">{video.description}</p>);
};

main();
