"use server";

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

import {
  SITE_SETTINGS_DEFAULT_OG_IMAGE_FIELD_KEY,
  SITE_SETTINGS_ENTITY_ID,
  SITE_SETTINGS_ENTITY_TYPE,
  SITE_SETTINGS_FAVICON_FIELD_KEY,
  SITE_SETTINGS_LOGO_DARK_FIELD_KEY,
  SITE_SETTINGS_LOGO_LIGHT_FIELD_KEY,
  updateSiteSettings,
} from "@/lib/app-config";
import { getAdminAppPath, toInternalAdminPath } from "@/lib/admin-routing";
import { PAGE_TITLE_TOKEN, type SiteSettings } from "@/lib/site-settings";
import { clearAdminSessionCookie, isAdminAuthenticated } from "@/lib/admin-auth";
import { replaceEntityMediaUsages } from "@/lib/media";
import { resolveMediaSelection } from "@/lib/media-service";
import { routing } from "@/i18n/routing";
import { getLocalizedPath } from "@/lib/locale";
import { removeManagedMediaFile } from "@/lib/media-storage";
import { mediaFieldInputSchema } from "@/lib/media-validation";
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 parseJsonObject(rawValue: FormDataEntryValue | null, key: string) {
  if (typeof rawValue !== "string" || rawValue.trim() === "") {
    return undefined;
  }

  try {
    const parsed = JSON.parse(rawValue);

    if (!parsed || Array.isArray(parsed) || typeof parsed !== "object") {
      throw new Error(`${key} must be an object.`);
    }

    return parsed;
  } catch {
    throw new Error(`Invalid ${key} payload.`);
  }
}

async function cleanupCreatedMedia(assetIds: string[], uploadedPaths: string[]) {
  if (assetIds.length > 0) {
    await prisma.mediaAsset.deleteMany({
      where: {
        id: {
          in: Array.from(new Set(assetIds)),
        },
      },
    });
  }

  for (const filePath of Array.from(new Set(uploadedPaths.filter(Boolean)))) {
    await removeManagedMediaFile(filePath);
  }
}

async function revalidateSiteSettingsPages() {
  revalidatePath("/", "layout");
  revalidatePath(toInternalAdminPath("/"));
  revalidatePath(toInternalAdminPath("/site-settings"));
  revalidatePath("/coming-soon");

  const publicPaths = ["/", "/about", "/portfolio", "/contact", "/success", "/coming-soon"];

  for (const locale of routing.locales) {
    revalidatePath(getLocalizedPath(locale), "layout");

    for (const path of publicPaths) {
      revalidatePath(getLocalizedPath(locale, path));
    }
  }
}

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

  const createdMediaAssetIds: string[] = [];
  const uploadedPaths: string[] = [];

  try {
    const siteLogoLightMedia = parseJsonObject(formData.get("siteLogoLightMedia"), "siteLogoLightMedia");
    const siteLogoDarkMedia = parseJsonObject(formData.get("siteLogoDarkMedia"), "siteLogoDarkMedia");
    const faviconMedia = parseJsonObject(formData.get("faviconMedia"), "faviconMedia");
    const defaultOgImageMedia = parseJsonObject(
      formData.get("defaultOgImageMedia"),
      "defaultOgImageMedia",
    );

    const parsedSettings: SiteSettings = {
      locales: {
        ar: {
          siteName: String(formData.get("siteNameAr") ?? "").trim(),
          titleTemplate: String(formData.get("titleTemplateAr") ?? "").trim(),
          siteDescription: String(formData.get("siteDescriptionAr") ?? "").trim(),
          subhead: String(formData.get("subheadAr") ?? "").trim(),
        },
        en: {
          siteName: String(formData.get("siteNameEn") ?? "").trim(),
          titleTemplate: String(formData.get("titleTemplateEn") ?? "").trim(),
          siteDescription: String(formData.get("siteDescriptionEn") ?? "").trim(),
          subhead: String(formData.get("subheadEn") ?? "").trim(),
        },
        de: {
          siteName: String(formData.get("siteNameDe") ?? "").trim(),
          titleTemplate: String(formData.get("titleTemplateDe") ?? "").trim(),
          siteDescription: String(formData.get("siteDescriptionDe") ?? "").trim(),
          subhead: String(formData.get("subheadDe") ?? "").trim(),
        },
      },
    };

    for (const locale of routing.locales) {
      if (!parsedSettings.locales[locale].siteName) {
        throw new Error(`Site Name fuer ${locale} ist erforderlich.`);
      }

      if (
        !parsedSettings.locales[locale].titleTemplate ||
        !parsedSettings.locales[locale].titleTemplate.includes(PAGE_TITLE_TOKEN)
      ) {
        throw new Error(`Title Template fuer ${locale} muss {pageTitle} enthalten.`);
      }
    }

    const siteLogoLightSelection = siteLogoLightMedia
      ? await resolveMediaSelection({
          media: mediaFieldInputSchema.parse(siteLogoLightMedia),
          uploadFile: formData.get("siteLogoLightFile"),
          folder: "site-settings",
          fallbackLabel: `${parsedSettings.locales.de.siteName || parsedSettings.locales.en.siteName} logo light`,
          required: false,
        })
      : {
          assetId: null,
          url: "",
          createdAssetId: null,
          uploadedUrl: null,
        };

    const siteLogoDarkSelection = siteLogoDarkMedia
      ? await resolveMediaSelection({
          media: mediaFieldInputSchema.parse(siteLogoDarkMedia),
          uploadFile: formData.get("siteLogoDarkFile"),
          folder: "site-settings",
          fallbackLabel: `${parsedSettings.locales.de.siteName || parsedSettings.locales.en.siteName} logo dark`,
          required: false,
        })
      : {
          assetId: null,
          url: "",
          createdAssetId: null,
          uploadedUrl: null,
        };

    const faviconSelection = faviconMedia
      ? await resolveMediaSelection({
          media: mediaFieldInputSchema.parse(faviconMedia),
          uploadFile: formData.get("faviconFile"),
          folder: "site-settings",
          fallbackLabel: `${parsedSettings.locales.de.siteName || parsedSettings.locales.en.siteName} favicon`,
          required: false,
        })
      : {
          assetId: null,
          url: "",
          createdAssetId: null,
          uploadedUrl: null,
        };

    const defaultOgImageSelection = defaultOgImageMedia
      ? await resolveMediaSelection({
          media: mediaFieldInputSchema.parse(defaultOgImageMedia),
          uploadFile: formData.get("defaultOgImageFile"),
          folder: "site-settings",
          fallbackLabel: `${parsedSettings.locales.de.siteName || parsedSettings.locales.en.siteName} og-image`,
          required: false,
        })
      : {
          assetId: null,
          url: "",
          createdAssetId: null,
          uploadedUrl: null,
        };

    if (siteLogoLightSelection.createdAssetId) {
      createdMediaAssetIds.push(siteLogoLightSelection.createdAssetId);
    }

    if (siteLogoLightSelection.uploadedUrl) {
      uploadedPaths.push(siteLogoLightSelection.uploadedUrl);
    }

    if (siteLogoDarkSelection.createdAssetId) {
      createdMediaAssetIds.push(siteLogoDarkSelection.createdAssetId);
    }

    if (siteLogoDarkSelection.uploadedUrl) {
      uploadedPaths.push(siteLogoDarkSelection.uploadedUrl);
    }

    if (faviconSelection.createdAssetId) {
      createdMediaAssetIds.push(faviconSelection.createdAssetId);
    }

    if (faviconSelection.uploadedUrl) {
      uploadedPaths.push(faviconSelection.uploadedUrl);
    }

    if (defaultOgImageSelection.createdAssetId) {
      createdMediaAssetIds.push(defaultOgImageSelection.createdAssetId);
    }

    if (defaultOgImageSelection.uploadedUrl) {
      uploadedPaths.push(defaultOgImageSelection.uploadedUrl);
    }

    await updateSiteSettings(parsedSettings);
    await replaceEntityMediaUsages({
      entityType: SITE_SETTINGS_ENTITY_TYPE,
      entityId: SITE_SETTINGS_ENTITY_ID,
      usages: [
        ...(siteLogoLightSelection.assetId
          ? [
              {
                assetId: siteLogoLightSelection.assetId,
                usageType: MediaUsageType.GENERIC,
                fieldKey: SITE_SETTINGS_LOGO_LIGHT_FIELD_KEY,
              },
            ]
          : []),
        ...(siteLogoDarkSelection.assetId
          ? [
              {
                assetId: siteLogoDarkSelection.assetId,
                usageType: MediaUsageType.GENERIC,
                fieldKey: SITE_SETTINGS_LOGO_DARK_FIELD_KEY,
              },
            ]
          : []),
        ...(faviconSelection.assetId
          ? [
              {
                assetId: faviconSelection.assetId,
                usageType: MediaUsageType.GENERIC,
                fieldKey: SITE_SETTINGS_FAVICON_FIELD_KEY,
              },
            ]
          : []),
        ...(defaultOgImageSelection.assetId
          ? [
              {
                assetId: defaultOgImageSelection.assetId,
                usageType: MediaUsageType.GENERIC,
                fieldKey: SITE_SETTINGS_DEFAULT_OG_IMAGE_FIELD_KEY,
              },
            ]
          : []),
      ],
    });

    await revalidateSiteSettingsPages();
    redirect(withMessage(getAdminAppPath("/site-settings"), "success", "Einstellungen gespeichert."));
  } catch (error) {
    if (isRedirectError(error)) {
      throw error;
    }

    await cleanupCreatedMedia(createdMediaAssetIds, uploadedPaths);

    const message =
      error instanceof Error
        ? error.message
        : "Einstellungen konnten nicht gespeichert werden.";

    redirect(withMessage(getAdminAppPath("/site-settings"), "error", message));
  }
}
