import { inject, Injectable } from '@angular/core'; import { environment } from 'src/environments/environment'; import { Maybe } from '../models'; import { ToastService } from './toast.service'; interface INativeBridgeHost { pay?: ((payload: string) => unknown) | ((amount: number, id: Maybe) => unknown); print?: (payload: string) => unknown; isEnabled?: () => boolean; } export interface INativePayRequest { amount: number; id: Maybe; } export interface INativePrintRequest { invoiceId?: string; code?: string; } export interface INativeBridgeResult { success: boolean; data?: T; error?: string; } @Injectable({ providedIn: 'root' }) export class NativeBridgeService { private readonly toastService = inject(ToastService); private get host(): INativeBridgeHost | undefined { const globalWindow = window as unknown as { AndroidBridge?: INativeBridgeHost; Android?: INativeBridgeHost; AndroidPSP?: INativeBridgeHost; }; return globalWindow.AndroidPSP || globalWindow.AndroidBridge || globalWindow.Android; } isEnabled(): boolean { const hostEnabled = this.host?.isEnabled; if (typeof hostEnabled === 'function') { try { return !!hostEnabled(); } catch { return false; } } return !!environment.enableNativeBridge && !!this.host; } canPay(): boolean { return this.isEnabled() && typeof this.host?.pay === 'function'; } canPrint(): boolean { return this.isEnabled() && typeof this.host?.print === 'function'; } pay(request: INativePayRequest): INativeBridgeResult { this.toastService.info({ text: 'در حال پردازش پرداخت...', life: 3000 }); const fn = this.host?.pay; if (typeof fn !== 'function') { return { success: false, error: 'Native method "pay" is not available.' }; } try { let raw: unknown; if (fn.length >= 2) { raw = (fn as (amount: number, id: Maybe) => unknown)(request.amount, request.id); } else { raw = (fn as (payload: string) => unknown)(JSON.stringify(request)); } const parsed = this.tryParse(raw); if (parsed && typeof parsed === 'object' && 'success' in parsed) { return parsed as INativeBridgeResult; } return { success: true, data: parsed ?? raw }; } catch (error) { return { success: false, error: (error as Error).message }; } } print(request: INativePrintRequest): INativeBridgeResult { return this.invokePrint(request); } private invokePrint(payload: object): INativeBridgeResult { const fn = this.host?.print; if (typeof fn !== 'function') { return { success: false, error: 'Native method "print" is not available.' }; } try { const raw = fn(JSON.stringify(payload)); const parsed = this.tryParse(raw); if (parsed && typeof parsed === 'object' && 'success' in parsed) { return parsed as INativeBridgeResult; } return { success: true, data: parsed ?? raw }; } catch (error) { return { success: false, error: (error as Error).message }; } } private tryParse(value: unknown): unknown { if (typeof value !== 'string') return value; try { return JSON.parse(value); } catch { return value; } } }