import type {
  StorageindexId,
  StorageindexUpdate,
} from "~/schemas/public/Storageindex";
import type { TempTokensToken } from "~/schemas/public/TempTokens";
import { TRPCError } from "@trpc/server";
import { env } from "~/env.mjs";
import type { Querier } from "~/server/db";
import type { UsersId } from "~/schemas/public/Users";

export const getNewTokenHandler = async ({
  db,
  num,
}: {
  db: Querier;
  num?: number;
}): Promise<TempTokensToken[]> => {
  const tokens: TempTokensToken[] = [];
  if (num && num > 1) {
    for (let i = 0; i < num; i++) {
      const tok = await newToken({ db });

      tokens.push(tok.token);
    }
    return tokens;
  }
  const tok = await newToken({ db });
  return [tok.token];
};

const newToken = async ({ db }: { db: Querier }) => {
  try {
    return await db
      .insertInto("temp_tokens")
      .defaultValues()
      .returning("token")
      .executeTakeFirstOrThrow();
  } catch {
    throw new TRPCError({
      code: "INTERNAL_SERVER_ERROR",
      message: "Error while creating token",
    });
  }
};

export const deleteFile = async ({
  db,
  fileId,
  cb,
}: {
  db: Querier;
  fileId: StorageindexId;
  cb?: (fileId: StorageindexId) => Promise<void>;
}) => {
  try {
    const storage = await db
      .selectFrom("storageindex")
      .select(["id", "ext"])
      .where("id", "=", fileId)
      .executeTakeFirstOrThrow();

    const authToken = (await getNewTokenHandler({ db }))[0];
    if (!authToken) {
      throw new TRPCError({
        code: "INTERNAL_SERVER_ERROR",
        message: "Error while getting auth token",
      });
    }
    const url = `${env.BACKENDSERVER_URL}/storage/delete/${storage.id}${storage.ext}?token=${authToken}`;
    const response = await fetch(url, {
      method: "DELETE",
    });

    if (!response.ok) {
      throw new Error("File remove failed");
    }
    if (cb) {
      await cb(fileId);
    }
  } catch (error) {
    console.error("Error:", error);
    throw new TRPCError({
      code: "INTERNAL_SERVER_ERROR",
      message: "Error while deleting file",
    });
  }
};

// export const deleteFiles = async ({
//   db,
//   refs,
//   cb,
// }: {
//   db: Querier;
//   refs: { storageid: StorageindexId }[];
//   cb?: (refs: { storageid: StorageindexId }[]) => Promise<void>;
// }) => {
//   try {
//     await Promise.all(
//       refs.map((ref) => deleteFile({ db, fileId: ref.storageid })),
//     );
//     if (cb) {
//       await cb(refs);
//     }
//   } catch (error) {
//     console.error("Error deleting files:", error);
//     throw new TRPCError({
//       code: "INTERNAL_SERVER_ERROR",
//       message: "Error while deleting files",
//     });
//   }
// };

export const updateFile = async ({
  db,
  fileId,
  data,
}: {
  db: Querier;
  fileId: StorageindexId;
  data: StorageindexUpdate;
}) => {
  try {
    await db
      .updateTable("storageindex")
      .set(data)
      .where("id", "=", fileId)
      .execute();
    return "ok";
  } catch (e) {
    throw new TRPCError({
      code: "INTERNAL_SERVER_ERROR",
      message: "Error while updating file: " + (e as Error).message,
    });
  }
};

export const addUserStorageJunc = async ({
  db,
  userId,
  storageId,
}: {
  db: Querier;
  userId: UsersId;
  storageId: StorageindexId;
}) => {
  try {
    return await db
      .insertInto("users_storage")
      .values({ userid: userId, storageid: storageId })
      .onConflict((oc) => oc.columns(["userid", "storageid"]).doNothing())
      .returningAll()
      .execute();
  } catch (e) {
    throw new TRPCError({
      code: "INTERNAL_SERVER_ERROR",
      message: "Error while adding user storage: " + (e as Error).message,
    });
  }
};

export const deleteUserStorageJunc = async ({
  db,
  userId,
  storageId,
}: {
  db: Querier;
  userId: UsersId;
  storageId: StorageindexId;
}) => {
  try {
    await db
      .deleteFrom("users_storage")
      .where("userid", "=", userId)
      .where("storageid", "=", storageId)
      .execute();
    return "ok";
  } catch (e) {
    throw new TRPCError({
      code: "INTERNAL_SERVER_ERROR",
      message: "Error while deleting user storage: " + (e as Error).message,
    });
  }
};
