export type Result<T, E = { code: string; message: string; statusCode?: number }> =
  | { success: true; data: T }
  | { success: false; error: E };

export type ApiError = {
  code: string;
  message: string;
  statusCode?: number;
};

/**
 * Backend errors arrive as snake_case i18n-style codes (e.g.
 * "unable_to_log_in"). Map the known ones to friendly copy and prettify
 * anything else so raw codes never reach the UI. `code` stays raw for
 * programmatic checks.
 */
const API_ERROR_MESSAGES: Record<string, string> = {
  unable_to_log_in: "Incorrect email or password.",
  invalid_refresh_token: "Your session has expired. Please sign in again.",
  session_expired: "Your session has expired. Please sign in again.",
  session_not_found: "Your session has expired. Please sign in again.",
  user_not_found: "No account found for these credentials.",
};

const SNAKE_CASE_CODE = /^[a-z0-9]+(?:_[a-z0-9]+)+$/;

function humanizeApiMessage(raw: string): string {
  const known = API_ERROR_MESSAGES[raw];
  if (known) return known;
  if (SNAKE_CASE_CODE.test(raw)) {
    const text = raw.replaceAll("_", " ");
    return `${text.charAt(0).toUpperCase()}${text.slice(1)}.`;
  }
  return raw;
}

export function extractApiError(err: unknown): ApiError {
  if (err && typeof err === "object") {
    const obj = err as Record<string, unknown>;
    const response = obj.response as Record<string, unknown> | undefined;
    if (response) {
      const statusCode = response.status as number | undefined;
      const data = response.data as Record<string, unknown> | undefined;
      return {
        code: (data?.message as string) || (data?.error as string) || "api_error",
        message: humanizeApiMessage(
          (data?.message as string) ||
            (data?.error as string) ||
            "An unexpected error occurred",
        ),
        statusCode,
      };
    }
    if (obj.message && typeof obj.message === "string") {
      return { code: "client_error", message: obj.message };
    }
  }
  return { code: "unknown_error", message: "An unexpected error occurred" };
}
