/**
 * Error extractors shared between the standalone /admin/promo-codes update
 * flow and the promo-code-campaigns nested promo edit modal. Keep both call
 * sites in sync — if you tweak one, fix the other or it'll silently diverge.
 */

export const extractErrorMessage = (input: any, fallback: string) => {
  if (!input) return fallback;
  const direct =
    input.message ||
    input.error ||
    input?.error?.message ||
    input?.data?.message ||
    input?.data?.error ||
    input?.detail?.message;
  if (typeof direct === "string" && direct.trim()) return direct;

  const rawErrors =
    input.errors ||
    input?.data?.errors ||
    input?.error?.errors ||
    input?.detail?.errors ||
    input?.error?.issues ||
    input?.data?.issues ||
    input?.issues;

  if (Array.isArray(rawErrors)) {
    const messages = rawErrors
      .map((entry) =>
        typeof entry === "string" ? entry : entry?.message || entry?.msg,
      )
      .filter((entry) => typeof entry === "string" && entry.trim());
    if (messages.length) return messages.join(" | ");
  }

  if (rawErrors && typeof rawErrors === "object") {
    const messages = Object.values(rawErrors)
      .flatMap((entry) => (Array.isArray(entry) ? entry : [entry]))
      .map((entry) =>
        typeof entry === "string" ? entry : entry?.message || entry?.msg,
      )
      .filter((entry) => typeof entry === "string" && entry.trim());
    if (messages.length) return messages.join(" | ");
  }

  return fallback;
};

const mapErrorPathSegment = (segment: string) => {
  const map: Record<string, string> = {
    is_active: "isActive",
    expires_at: "expiresAt",
    access_list: "access_list",
    membership_accounts: "membershipAccounts",
    membership_clubs: "membershipClubs",
    membership_account_types: "membershipAccountTypes",
    signup_promos: "signupPromoCodes",
    signup_promo_codes: "signupPromoCodes",
    service_center_id: "serviceCenterID",
    external_membership_entity_id: "externalMembershipEntityID",
    membership_account_type_id: "membershipAccountTypeID",
    edm_template_id: "edmTemplateIDs",
  };
  return map[segment] ?? segment;
};

const normalizeErrorPath = (path: string | Array<string | number>) => {
  if (Array.isArray(path)) {
    return path
      .map((segment) =>
        typeof segment === "number"
          ? String(segment)
          : mapErrorPathSegment(segment),
      )
      .join(".");
  }
  return path
    .split(".")
    .map((segment) => mapErrorPathSegment(segment))
    .join(".");
};

export const extractFieldErrors = (input: any): Record<string, string> => {
  const collected: Record<string, string> = {};
  if (!input) return collected;

  const rawErrors =
    input.errors ||
    input?.data?.errors ||
    input?.detail?.errors ||
    input?.data?.issues ||
    input?.issues;

  if (Array.isArray(rawErrors)) {
    rawErrors.forEach((entry) => {
      const path = entry?.path;
      const message = entry?.message || entry?.msg;
      if (path && message) {
        collected[normalizeErrorPath(path)] = message;
      }
    });
  } else if (rawErrors && typeof rawErrors === "object") {
    Object.entries(rawErrors).forEach(([key, value]) => {
      const message = Array.isArray(value) ? value[0] : value;
      if (message) {
        collected[normalizeErrorPath(key)] = String(message);
      }
    });
  }

  return collected;
};
