const fs = require("fs");
const path = require("path");

const stripComponentId = (component: any) => {
  if (!component || typeof component !== "object") {
    return component;
  }

  const { id, ...rest } = component;
  return rest;
};

const normalizeMediaValue = (value: any) => {
  if (value === null || value === undefined) {
    return value;
  }

  if (typeof value === "string" || typeof value === "number") {
    return value;
  }

  if (Array.isArray(value)) {
    const [first] = value;
    return normalizeMediaValue(first);
  }

  if (typeof value === "object") {
    if (value.id !== undefined) {
      return value.id;
    }

    if (value.data !== undefined) {
      return normalizeMediaValue(value.data);
    }

    if (Array.isArray(value.connect)) {
      const [first] = value.connect;
      return normalizeMediaValue(first);
    }

    if (Array.isArray(value.set)) {
      const [first] = value.set;
      return normalizeMediaValue(first);
    }
  }

  // Fallback: drop invalid media payloads to avoid relation errors.
  return undefined;
};

const logInvalidMedia = (value: any, path: string) => {
  if (
    value === null ||
    value === undefined ||
    typeof value === "string" ||
    typeof value === "number"
  ) {
    return;
  }

  try {
    // Keep log minimal to avoid noisy output.
    console.warn(`[footer] Invalid media payload at ${path}`, {
      type: typeof value,
      value: JSON.stringify(value)?.slice(0, 200),
    });
  } catch (error) {
    console.warn(`[footer] Invalid media payload at ${path}`, { type: typeof value });
  }
};

const dumpFooterPayload = (payload: any, suffix: string) => {
  try {
    const tmpDir = path.resolve(process.cwd(), ".tmp");
    if (!fs.existsSync(tmpDir)) {
      fs.mkdirSync(tmpDir, { recursive: true });
    }

    const target = path.join(tmpDir, `footer-payload-${suffix}.json`);
    const safePayload = payload ?? {};
    fs.writeFileSync(target, JSON.stringify(safePayload, null, 2));
  } catch (error) {
    console.warn("[footer] Failed to write payload dump");
  }
};

const normalizeFooterMenuItem = (item: any) => {
  if (!item || typeof item !== "object") {
    return item;
  }

  const normalized = stripComponentId(item);
  const iconId = normalizeMediaValue(normalized?.icon);

  if (iconId !== undefined) {
    return {
      ...normalized,
      icon: iconId,
    };
  }

  return normalized;
};

const normalizeComponentArray = (value: any) => {
  if (Array.isArray(value)) {
    return value;
  }

  if (value && typeof value === "object") {
    if (Array.isArray(value.set)) {
      return value.set;
    }

    if (Array.isArray(value.connect)) {
      return value.connect;
    }
  }

  return undefined;
};

const sanitizeFooterMenuColumn = (column: any) => {
  if (!column || typeof column !== "object") {
    return column;
  }

  if (column.set && typeof column.set === "object") {
    return sanitizeFooterMenuColumn(column.set);
  }

  if (column.connect && typeof column.connect === "object") {
    if (Array.isArray(column.connect)) {
      const [first] = column.connect;
      return sanitizeFooterMenuColumn(first);
    }

    return sanitizeFooterMenuColumn(column.connect);
  }

  const { id, items, ...rest } = column;
  const normalizedItems = normalizeComponentArray(items);

  return {
    ...rest,
    ...(normalizedItems
      ? { items: normalizedItems.map(normalizeFooterMenuItem) }
      : {}),
  };
};

const sanitizeFooterComponents = (data: any) => {
  if (!data || typeof data !== "object") {
    return;
  }

  if (data.logo !== undefined) {
    data.logo = normalizeMediaValue(data.logo);
  }

  if (Array.isArray(data.socialMediaLinks)) {
    data.socialMediaLinks = data.socialMediaLinks.map((link: any) =>
      stripComponentId(link)
    );
  }

  if (data.localizations !== undefined) {
    const ids = Array.isArray(data.localizations)
      ? data.localizations
          .map((loc: any) =>
            loc && typeof loc === "object" && "id" in loc ? loc.id : loc
          )
          .filter((id: any) => typeof id === "string" || typeof id === "number")
      : [];

    if (ids.length > 0) {
      data.localizations = ids.map((id: any) => ({ id }));
    } else {
      delete data.localizations;
    }
  }

  if (data.contactInfo && typeof data.contactInfo === "object") {
    data.contactInfo = sanitizeFooterMenuColumn(data.contactInfo);
  }

  if (Array.isArray(data.menuColumns)) {
    data.menuColumns = data.menuColumns.map((column: any) =>
      sanitizeFooterMenuColumn(column)
    );
  }

  // Log any remaining invalid media payloads for debugging.
  logInvalidMedia(data.logo, "logo");
  if (data.contactInfo?.items) {
    data.contactInfo.items.forEach((item: any, idx: number) => {
      logInvalidMedia(item?.icon, `contactInfo.items[${idx}].icon`);
    });
  }
  if (Array.isArray(data.menuColumns)) {
    data.menuColumns.forEach((column: any, colIdx: number) => {
      if (Array.isArray(column?.items)) {
        column.items.forEach((item: any, idx: number) => {
          logInvalidMedia(
            item?.icon,
            `menuColumns[${colIdx}].items[${idx}].icon`
          );
        });
      }
    });
  }
};

export default (_config: unknown, { strapi }: { strapi: any }) => {
  return async (ctx: any, next: () => Promise<void>) => {
    const path = ctx?.request?.path ?? "";

    if (path.includes("/content-manager/single-types/api::footer.footer")) {
      const requestBody = ctx?.request?.body;
      const requestData = requestBody?.data;

      dumpFooterPayload(requestBody, "raw-body");
      dumpFooterPayload(requestData, "raw-data");

      sanitizeFooterComponents(requestData);

      dumpFooterPayload(requestBody, "sanitized-body");
      dumpFooterPayload(requestData, "sanitized-data");
    }

    await next();
  };
};
