import { UAParser } from "ua-parser-js";

export type InAppBrowserName =
  | "facebook"
  | "instagram"
  | "wechat"
  | "weibo"
  | "qq"
  | "line"
  | "tiktok"
  | "webview"
  | "unknown";

export interface BrowserInfo {
  name: string;
  version: string;
  major: string;
  engineName: string;
  engineVersion: string;
  isInAppBrowser: boolean;
  inAppBrowserName: InAppBrowserName | null;
  userAgent: string;
}

/**
 * 浏览器 / WebView 检测
 *
 * 只放浏览器相关能力。OS / 设备 / 平台检测请使用 `PlatformDetector`。
 */
export class BrowserDetector {
  private constructor() {}

  static getBrowserInfo(ua: string | null = null): BrowserInfo {
    const userAgent = BrowserDetector.getUserAgent(ua);
    const result = new UAParser(userAgent).getResult();
    const inAppBrowserName = BrowserDetector.getInAppBrowserName(userAgent);

    return {
      name: result.browser.name ?? "",
      version: result.browser.version ?? "",
      major: result.browser.major ?? "",
      engineName: result.engine.name ?? "",
      engineVersion: result.engine.version ?? "",
      isInAppBrowser: inAppBrowserName !== null,
      inAppBrowserName,
      userAgent,
    };
  }

  static getBrowserName(ua: string | null = null): string {
    return BrowserDetector.getBrowserInfo(ua).name;
  }

  static getBrowserVersion(ua: string | null = null): string {
    return BrowserDetector.getBrowserInfo(ua).version;
  }

  static isChrome(ua: string | null = null): boolean {
    return /Chrome|CriOS/i.test(BrowserDetector.getBrowserName(ua));
  }

  static isSafari(ua: string | null = null): boolean {
    return /Safari/i.test(BrowserDetector.getBrowserName(ua));
  }

  static isEdge(ua: string | null = null): boolean {
    return /Edge/i.test(BrowserDetector.getBrowserName(ua));
  }

  /** 当前是否在 Facebook 内嵌浏览器 */
  static isFacebookInAppBrowser(ua: string | null = null): boolean {
    return /FBAN|FBAV|FB_IAB|FB4A|FBIOS/i.test(BrowserDetector.getUserAgent(ua));
  }

  /** 当前是否在 Instagram 内嵌浏览器 */
  static isInstagramInAppBrowser(ua: string | null = null): boolean {
    return /Instagram/i.test(BrowserDetector.getUserAgent(ua));
  }

  /** 当前是否在微信内嵌浏览器 */
  static isWeChatInAppBrowser(ua: string | null = null): boolean {
    return /MicroMessenger/i.test(BrowserDetector.getUserAgent(ua));
  }

  /** 当前是否在微博内嵌浏览器 */
  static isWeiboInAppBrowser(ua: string | null = null): boolean {
    return /Weibo/i.test(BrowserDetector.getUserAgent(ua));
  }

  /** 当前是否在 QQ 内嵌浏览器 */
  static isQQInAppBrowser(ua: string | null = null): boolean {
    return /QQ\//i.test(BrowserDetector.getUserAgent(ua));
  }

  /** 当前是否在 Line 内嵌浏览器 */
  static isLineInAppBrowser(ua: string | null = null): boolean {
    return /Line\//i.test(BrowserDetector.getUserAgent(ua));
  }

  /** 当前是否在 TikTok 内嵌浏览器 */
  static isTikTokInAppBrowser(ua: string | null = null): boolean {
    return /BytedanceWebview|TikTok|Musical_ly/i.test(
      BrowserDetector.getUserAgent(ua),
    );
  }

  /** 当前是否在 WebView（不通用；仅作 best-effort 判断） */
  static isWebView(ua: string | null = null): boolean {
    const userAgent = BrowserDetector.getUserAgent(ua);
    return (
      /WebView|; wv\)/i.test(userAgent) ||
      (/iPhone|iPad|iPod/i.test(userAgent) &&
        /AppleWebKit/i.test(userAgent) &&
        !/Safari/i.test(userAgent))
    );
  }

  /** 当前是否在应用内浏览器 */
  static isInAppBrowser(ua: string | null = null): boolean {
    return BrowserDetector.getInAppBrowserName(ua) !== null;
  }

  static getInAppBrowserName(
    ua: string | null = null,
  ): InAppBrowserName | null {
    if (BrowserDetector.isFacebookInAppBrowser(ua)) return "facebook";
    if (BrowserDetector.isInstagramInAppBrowser(ua)) return "instagram";
    if (BrowserDetector.isWeChatInAppBrowser(ua)) return "wechat";
    if (BrowserDetector.isWeiboInAppBrowser(ua)) return "weibo";
    if (BrowserDetector.isQQInAppBrowser(ua)) return "qq";
    if (BrowserDetector.isLineInAppBrowser(ua)) return "line";
    if (BrowserDetector.isTikTokInAppBrowser(ua)) return "tiktok";
    if (BrowserDetector.isWebView(ua)) return "webview";
    return null;
  }

  private static getUserAgent(ua: string | null = null): string {
    if (ua) return ua;
    if (typeof navigator === "undefined") return "";
    return navigator.userAgent;
  }
}
