import { Injectable } from '@angular/core';
import { environment } from 'src/environments/environment';

interface INativeBridgeHost {
  pay?: (payload: string) => unknown;
  print?: (payload: string) => unknown;
}

export interface INativePayRequest {
  amount: number;
  totalAmount: number;
  invoiceDate: string;
}

export interface INativePrintRequest {
  invoiceId?: string;
  code?: string;
}

export interface INativeBridgeResult<T = unknown> {
  success: boolean;
  data?: T;
  error?: string;
}

@Injectable({ providedIn: 'root' })
export class NativeBridgeService {
  private get host(): INativeBridgeHost | undefined {
    const globalWindow = window as unknown as {
      AndroidBridge?: INativeBridgeHost;
      Android?: INativeBridgeHost;
    };

    return globalWindow.AndroidBridge || globalWindow.Android;
  }

  isEnabled(): boolean {
    return !!environment.enableNativeBridge;
  }

  canPay(): boolean {
    return this.isEnabled() && typeof this.host?.pay === 'function';
  }

  canPrint(): boolean {
    return this.isEnabled() && typeof this.host?.print === 'function';
  }

  pay(request: INativePayRequest): INativeBridgeResult {
    return this.invoke('pay', request);
  }

  print(request: INativePrintRequest): INativeBridgeResult {
    return this.invoke('print', request);
  }

  private invoke(method: 'pay' | 'print', payload: object): INativeBridgeResult {
    if (!this.isEnabled()) {
      return { success: false, error: 'Native bridge is disabled for this tenant.' };
    }

    const fn = this.host?.[method];
    if (typeof fn !== 'function') {
      return { success: false, error: `Native method "${method}" 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;
    }
  }
}
