import {
  Accessor,
  createContext,
  createRenderEffect,
  createResource,
  Signal,
  useContext,
} from "solid-js";
import { Account } from "../accounts/stores";
import { createRestAPIClient, mastodon } from "masto";
import { useLocation, useNavigate } from "@solidjs/router";

const restfulCache: Record<string, mastodon.rest.Client> = {};

export function createMastoClientFor(account: Account) {
  const cacheKey = [account.site, account.accessToken].join("");
  const cache = restfulCache[cacheKey];
  if (cache) return cache;

  const client = createRestAPIClient({
    url: account.site,
    accessToken: account.accessToken,
  });
  restfulCache[cacheKey] = client;

  return client;
}

export function createUnauthorizedClient(site: string) {
  const cache = restfulCache[site];
  if (cache) return cache;

  const client = createRestAPIClient({
    url: site,
  });
  restfulCache[site] = client;

  return client;
}

export function useInstance(client: Accessor<mastodon.rest.Client>) {
  return createResource(client, async (client) => {
    return await client.v2.instance.fetch();
  });
}

export type Session = {
  account: Account;
  client: mastodon.rest.Client;
};

const Context = /* @__PURE__ */ createContext<Signal<Session[]>>();

export const Provider = Context.Provider;

export function useSessions() {
  const [sessions] = useSessionsRw();
  const navigate = useNavigate();
  const location = useLocation();

  createRenderEffect(() => {
    if (sessions().length > 0) return;
    navigate(
      "/accounts/sign-in?back=" + encodeURIComponent(location.pathname),
      { replace: true },
    );
  });

  return sessions;
}

function useSessionsRw() {
  const store = useContext(Context);
  if (!store) {
    throw new TypeError("sessions are not provided");
  }
  return store;
}