import axios from "axios";

const FRIENDLY_FALLBACK = "There was an error processing your request.";
const MAX_TOAST_BODY_CHARS = 400; // avoid massive, unreadable toasts

export function clampText(s: string, max = MAX_TOAST_BODY_CHARS): string {
  return s && s.length > max ? `${s.slice(0, max)}…` : s;
}

function isUnhelpfulMessage(msg: string | null | undefined): boolean {
  const s = (msg || "").trim();
  if (!s) return true;
  // Common unhelpful payloads we see
  if (s === "{}" || s === "[]") return true;
  if (/^request failed/i.test(s)) return true;
  if (/^network error/i.test(s)) return true;
  if (/^[45]\d\d\b/.test(s)) return true; // "500 Server Error" etc.
  return false;
}

function titleForStatus(status?: number): string {
  if (!status) return "Network error";
  if (status >= 500) return "Server error";
  if (status >= 400) return "Request error";
  return "Request failed";
}

export function extractAxiosErrorMessage(error: any): {
  title: string;
  body: string;
} {
  if (axios.isAxiosError(error)) {
    const status = error.response?.status;
    const _statusText = error.response?.statusText || "";
    let parsed: any = undefined;
    const raw = error.response?.data;
    if (typeof raw === "string") {
      try {
        parsed = JSON.parse(raw);
      } catch {
        /* keep as string */
      }
    } else {
      parsed = raw;
    }
    const extractIds = (): string[] | undefined => {
      if (Array.isArray(parsed?.errorFileIds))
        return parsed.errorFileIds as string[];
      const rawText = typeof raw === "string" ? raw : "";
      const uuidMatches = rawText.match(
        /[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/g,
      );
      return uuidMatches && uuidMatches.length > 0
        ? Array.from(new Set(uuidMatches))
        : undefined;
    };

    const body = ((): string => {
      const data = parsed;
      if (!data) return typeof raw === "string" ? raw : "";
      const ids = extractIds();
      if (ids && ids.length > 0) return `Failed files: ${ids.join(", ")}`;
      if (data?.message) return data.message as string;
      if (typeof raw === "string") return raw;
      try {
        return JSON.stringify(data);
      } catch {
        return "";
      }
    })();
    const ids = extractIds();
    const title = titleForStatus(status);
    if (ids && ids.length > 0) {
      return { title, body: "Process failed due to invalid/corrupted file(s)" };
    }
    if (status === 422) {
      const fallbackMsg = "Process failed due to invalid/corrupted file(s)";
      const bodyMsg = isUnhelpfulMessage(body) ? fallbackMsg : body;
      return { title, body: bodyMsg };
    }
    const bodyMsg = isUnhelpfulMessage(body) ? FRIENDLY_FALLBACK : body;
    return { title, body: bodyMsg };
  }
  try {
    const msg = (error?.message || String(error)) as string;
    return {
      title: "Network error",
      body: isUnhelpfulMessage(msg) ? FRIENDLY_FALLBACK : msg,
    };
  } catch (e) {
    // ignore extraction errors
    console.debug("extractAxiosErrorMessage", e);
    return { title: "Network error", body: FRIENDLY_FALLBACK };
  }
}
