"use server";

import {
  ConvertQueryResultToJSON,
  ServerAction,
  ServerResponse,
} from "@/lib/actions";
import { createWriteStream } from "fs";
import { mkdir } from "fs/promises";
import { ResultSetHeader, RowDataPacket } from "mysql2";
import { v4 } from "uuid";

export const createDownloadLink = async (formData: FormData) => {
  const { error, con, dict } = await ServerAction();

  if (error) {
    return ServerResponse({
      operation: false,
      data: error,
    });
  }

  const user = formData.get("user") as string;
  const title = formData.get("title") as string;
  const file = formData.get("file") as File;

  const uuid = v4();
  const filePath = `tmp/${uuid}`;
  const fileName = file.name;

  await con.beginTransaction();

  try {
    const path = `${filePath}/${fileName}`;
    const href = `${process.env.NEXTAUTH_URL}${path}`;

    await mkdir(`public/${filePath}`, { recursive: true });
    const writeStream = createWriteStream(`public/${path}`);
    writeStream.write(Buffer.from(await file.arrayBuffer()));

    await new Promise((resolve, reject) => {
      writeStream.on("finish", resolve);
      writeStream.on("error", reject);
      writeStream.end();
    });

    const [result] = await con.query<ResultSetHeader>(
      "INSERT INTO DOWNLOADLINKS (ID, TITLE, HREF, USER) VALUES (?, ?, ?, ?)",
      [uuid, title, href, user],
    );

    const [inserted] = await con.query<RowDataPacket[]>(
      "SELECT DL.*, U.NAME as USER, U.EMAIL FROM DOWNLOADLINKS DL JOIN USERS U ON U.ID = DL.USER WHERE DL.ID = ?",
      [uuid],
    );

    if (inserted.length === 0) {
      await con.rollback();

      return ServerResponse({
        operation: false,
        message: dict.alerts.create_download_link.error_cant_create,
      });
    }

    await con.commit();

    return ServerResponse({
      operation: true,
      message: dict.alerts.create_download_link.success,
      data: ConvertQueryResultToJSON(inserted)[0],
    });
  } catch (error) {
    await con.rollback();
    return ServerResponse({
      operation: false,
      message: dict.alerts.general.unexpected_error,
      data: error,
    });
  } finally {
    con.release();
  }
};
