import {
  ConvertJSONToFormData,
  ServerAction,
  ServerRequest,
} from "@/lib/actions";
import { getCpanelVars } from "@/models/cpanel";
import { DBEType } from "@/models/ErrorType";
import downloadSubdomainFiles from "@/services/files/downloadSubdomainFiles";
import { postServerLog } from "@/services/logs";
import { rm } from "fs/promises";
import { NextRequest, NextResponse } from "next/server";
import { join } from "path";
import { getCertificates } from "./utils/certificates";
import { getCodeList } from "./utils/codeList";
import { getPastPerformance } from "./utils/pastPerformance";
import { processFiles } from "./utils/processFiles";
import { projectExists } from "./utils/projectExists";
import { readAndModifyTemplate } from "./utils/readAndModifyTemplate";
import { getServices } from "./utils/services";
import { getSubdomain } from "./utils/subdomain";
import { updateDatabase } from "./utils/updateDatabase";
import { getWhyChooseUs } from "./utils/whyChooseUs";

const TMP_DIR = join("public", "tmp");

export async function POST(req: NextRequest) {
  const { error, con } = await ServerAction({ isAuth: false });
  const cpanel = getCpanelVars();
  const groqApiKey = process.env.GROQ_API_KEY;

  let tmpDir = "";

  if (error) {
    return new NextResponse(null, {
      status: 500,
      statusText: "Internal Server Error",
    });
  }

  try {
    const data = await req.json();
    const exists = await projectExists({ con, data });

    if (exists) {
      await updateDatabase({ con, url: data.url });
      return NextResponse.json({
        operation: true,
        message:
          "A note has been sent to the editors to update the Landing Page.",
      });
    }

    let template = await readAndModifyTemplate(data);

    const { template: updatedTemplate, certs } = getCertificates(
      template,
      data.certifications ?? [],
    );
    template = updatedTemplate;

    template = getCodeList(template, {
      naics: data.naicsCodes ?? [],
      psc: data.pcsCodes ?? [],
    });
    template = getServices(
      template,
      data.services.list ?? [],
      data.template ?? "v1",
    );
    template = getWhyChooseUs(template, data.whyChooseUs.message ?? "");
    template = getPastPerformance(template, data.pastPerformance.list ?? []);

    const subdomain = await getSubdomain({
      name: `DBA Name: ${data.dbaName} | Legal Name: ${data.legalName}`,
      apiKey: groqApiKey,
    });

    const downloadFileFormData = ConvertJSONToFormData({
      name: `${subdomain}/site`,
      files: [
        `/home/${cpanel.user}/FEDSITE_template/${data.template ?? "v1"}/`,
      ],
      permanent: "1",
    });
    const downloadFileResult = await ServerRequest<DownloadFileResult>(
      downloadSubdomainFiles(downloadFileFormData, {
        isAuth: false,
      }),
    );

    tmpDir = downloadFileResult.data.uuid;

    const local = downloadFileResult.data.local;

    await processFiles(
      local,
      template,
      subdomain,
      certs,
      data.template ?? "v1",
    );
    await updateDatabase({ con, subdomain, email: data.email });

    return NextResponse.json({
      operation: true,
      message:
        "The project was uploaded, please wait for the editors to adjust the Landing Page.",
    });
  } catch (error) {
    await postServerLog({ type: DBEType.ERROR, log: error });
    return new NextResponse(null, {
      status: 500,
      statusText: `Internal Server Error`,
    });
  } finally {
    con.release();

    if (tmpDir) {
      await rm(join(TMP_DIR, tmpDir), { recursive: true, force: true });
    }
  }
}
