import hash_sum from "hash-sum";
import { fetchViaProxy } from "../proxy";

export const dbProxy = (dburl: string) => {
  return new Proxy(
    {},
    {
      get(_, table: string) {
        if (table === "_tables") {
          return () => {
            return fetchSendDb(
              {
                name,
                action: "definition",
                table: "*",
              },
              dburl
            );
          };
        }

        if (table === "_definition") {
          return (table: string) => {
            return fetchSendDb(
              {
                name,
                action: "definition",
                table,
              },
              dburl
            );
          };
        }

        if (table.startsWith("$")) {
          return (...params: any[]) => {
            return fetchSendDb(
              {
                name,
                action: "query",
                table,
                params,
              },
              dburl
            );
          };
        }

        return new Proxy(
          {},
          {
            get(_, action: string) {
              return (...params: any[]) => {
                if (table === "query") {
                  table = action;
                  action = "query";
                }
                return fetchSendDb(
                  {
                    name,
                    action,
                    table,
                    params,
                  },
                  dburl
                );
              };
            },
          }
        );
      },
    }
  );
};

const cachedQueryResult: Record<
  string,
  { timestamp: number; result: any; promise: Promise<any> }
> = {};

export const fetchSendDb = async (params: any, dburl: string) => {
  const base = new URL(dburl);
  base.pathname = `/_dbs`;
  if (params.table) {
    base.pathname += `/${params.table}`;
  }
  const url = base.toString();

  const hsum = hash_sum(params);
  const cached = cachedQueryResult[hsum];

  if (!cached || (cached && Date.now() - cached.timestamp > 1000)) {
    cachedQueryResult[hsum] = {
      timestamp: Date.now(),
      promise: fetchViaProxy(url, params, {
        "content-type": "application/json",
      }),
      result: null,
    };

    const result = await cachedQueryResult[hsum].promise;
    cachedQueryResult[hsum].result = result;
    return result;
  }

  return await cached.promise;
};
