import { ExceptionCode } from "../exception-code";
import type { ExceptionResult } from "../exception-result";

export class BrowserExceptionHandler {
  static canHandle(error: unknown): error is Error | DOMException {
    if (!isErrorLike(error)) return false;
    return isPermissionError(error) || isUnsupportedFeatureError(error);
  }

  static handle(error: Error | DOMException): ExceptionResult {
    if (isPermissionError(error)) {
      return {
        code: ExceptionCode.permissionDenied,
        message: "Permission denied.",
      };
    }

    return {
      code: ExceptionCode.unsupported,
      message: "This feature is not supported in this browser.",
    };
  }
}

function isPermissionError(error: Error | DOMException): boolean {
  const name = error.name.toLowerCase();
  const message = error.message.toLowerCase();
  return (
    name === "notallowederror" ||
    name === "permissiondeniederror" ||
    message.includes("permission denied") ||
    (message.includes("permission") && message.includes("denied"))
  );
}

function isUnsupportedFeatureError(error: Error | DOMException): boolean {
  const name = error.name.toLowerCase();
  const message = error.message.toLowerCase();
  return (
    name === "notsupportederror" ||
    message.includes("not supported") ||
    message.includes("not available on server") ||
    message.includes("unsupported")
  );
}

function isErrorLike(error: unknown): error is Error | DOMException {
  if (error instanceof Error) return true;
  return typeof DOMException !== "undefined" && error instanceof DOMException;
}
