"use server";

import { MediaKind } from "@prisma/client";
import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";
import { isRedirectError } from "next/dist/client/components/redirect-error";

import { getAdminAppPath, toInternalAdminPath } from "@/lib/admin-routing";
import { clearAdminSessionCookie, isAdminAuthenticated } from "@/lib/admin-auth";
import { countMediaUsageReferences, getMediaAssetById } from "@/lib/media";
import { createStandaloneMediaAsset, deleteMediaAssetAndFile } from "@/lib/media-service";
import { isManagedMediaFilePath } from "@/lib/media-storage";
import { prisma } from "@/lib/prisma";

async function ensureAdmin() {
  if (!(await isAdminAuthenticated())) {
    await clearAdminSessionCookie();
    redirect(getAdminAppPath("/"));
  }
}

function withMessage(pathname: string, type: "success" | "error", message: string) {
  const params = new URLSearchParams();
  params.set(type, message);

  return `${pathname}?${params.toString()}`;
}

function revalidateMediaPages() {
  revalidatePath(toInternalAdminPath("/"));
  revalidatePath(toInternalAdminPath("/media"));
  revalidatePath(toInternalAdminPath("/portfolio"));
  revalidatePath(toInternalAdminPath("/portfolio/projects"));
}

export async function createMediaAssetAction(formData: FormData) {
  await ensureAdmin();

  try {
    const kindValue = String(formData.get("kind") ?? "IMAGE");
    const kind = kindValue === "DOCUMENT" ? MediaKind.DOCUMENT : MediaKind.IMAGE;

    await createStandaloneMediaAsset({
      kind,
      label: String(formData.get("label") ?? ""),
      uploadFile: formData.get("file"),
    });

    revalidateMediaPages();
    redirect(withMessage(getAdminAppPath("/media"), "success", "Datei gespeichert."));
  } catch (error) {
    if (isRedirectError(error)) {
      throw error;
    }

    const message = error instanceof Error ? error.message : "Datei konnte nicht gespeichert werden.";
    redirect(withMessage(getAdminAppPath("/media"), "error", message));
  }
}

export async function deleteMediaAssetAction(formData: FormData) {
  await ensureAdmin();

  const assetId = String(formData.get("assetId") ?? "");

  try {
    const asset = await getMediaAssetById(assetId);

    if (!asset) {
      redirect(withMessage(getAdminAppPath("/media"), "error", "Datei nicht gefunden."));
    }

    const usageCount = await countMediaUsageReferences(asset.id);

    if (usageCount > 0) {
      redirect(withMessage(getAdminAppPath("/media"), "error", "Datei wird noch verwendet."));
    }

    await prisma.mediaAsset.delete({
      where: {
        id: asset.id,
      },
    });

    if (isManagedMediaFilePath(asset.url)) {
      await deleteMediaAssetAndFile({
        assetId: asset.id,
        assetUrl: asset.url,
      });
    }

    revalidateMediaPages();
    redirect(withMessage(getAdminAppPath("/media"), "success", "Datei geloescht."));
  } catch (error) {
    if (isRedirectError(error)) {
      throw error;
    }

    const message = error instanceof Error ? error.message : "Datei konnte nicht geloescht werden.";
    redirect(withMessage(getAdminAppPath("/media"), "error", message));
  }
}
