import { error, redirect } from "@sveltejs/kit";

export class ApiError extends Error {
  constructor(
    public statusCode: number,
    public message: string,
    public details?: unknown,
  ) {
    super(message);
    this.name = "ApiError";
  }
}

/**
 * Detects "invalid signature" or malformed-token errors from the API,
 * which indicate the access or refresh token has been tampered with or
 * the server signing key has changed.
 */
export function isInvalidSignatureError(err: unknown): boolean {
  if (err && typeof err === "object") {
    const axiosErr = err as Record<string, unknown>;
    const responseData = (axiosErr?.response as Record<string, unknown>)
      ?.data as Record<string, unknown> | undefined;
    const candidates = [
      responseData?.message,
      responseData?.error,
      (err as Error)?.message,
    ];
    return candidates.some((val) => {
      if (typeof val !== "string") return false;
      const lower = val.toLowerCase();
      return (
        lower.includes("invalid signature") ||
        lower.includes("jwt malformed") ||
        lower.includes("invalid token")
      );
    });
  }
  return false;
}

export function handleApiError(err: unknown): never {
  console.error("API Error:", err);

  // Treat invalid-signature errors as a forced logout
  if (isInvalidSignatureError(err)) {
    console.warn("Invalid token signature detected — forcing logout.");
    throw redirect(303, "/logout");
  }

  if (err instanceof ApiError) {
    throw error(err.statusCode, {
      message: err.message,
      details: err.details,
    });
  }

  if (err instanceof Error) {
    const message = err.message || "An unexpected error occurred";
    throw error(500, {
      message,
      details: err.stack,
    });
  }

  throw error(500, {
    message: "An unexpected error occurred",
    details: String(err),
  });
}

export function isNetworkError(err: unknown): boolean {
  if (err instanceof Error) {
    return (
      err.message.includes("Network") ||
      err.message.includes("fetch") ||
      err.message.includes("ECONNREFUSED")
    );
  }
  return false;
}

export function isUnauthorizedError(err: unknown): boolean {
  return err instanceof ApiError && err.statusCode === 401;
}

export function isForbiddenError(err: unknown): boolean {
  return err instanceof ApiError && err.statusCode === 403;
}

export function isNotFoundError(err: unknown): boolean {
  return err instanceof ApiError && err.statusCode === 404;
}
