import { ComponentType } from 'react';

export enum WalletType {
    PAYTM_BUSINESS = 'paytm business',
    PHONEPE_BUSINESS = 'phonepe business',
    GOOGLEPAY_BUSINESS = 'googlepay business',
    BHARATPE_BUSINESS = 'bharatpe business',
    PAYTM_PERSONAL = 'paytm',
    PHONEPE_PERSONAL = 'phonepe',
    GOOGLEPAY_PERSONAL = 'googlepay',
    BHARATPE_PERSONAL = 'bharatpe',
    FREECHARGE_PERSONAL = 'freecharge',
    MOBIKWIK_PERSONAL = 'mobikwik',
}

export interface BaseBindResult {
    success: boolean;
    type: WalletType;
}

export interface PaytmBusinessBindResult extends BaseBindResult {
    type: WalletType.PAYTM_BUSINESS;
    cookie: string;
    xCsrfToken: string;
    contextData?: string;
    qrData?: string;
}

export interface PhonePeBusinessBindResult extends BaseBindResult {
    type: WalletType.PHONEPE_BUSINESS;
    cookie: string;
    xCsrfToken: string;
    fingerprint: string;
    qrData?: string;
    userAToken: string;
    userRToken: string;
    userInfo?: string;
}

export interface GooglePayMerchantInfo {
    channelUid: string;
    merchantName: string;
    merchantDisplayName: string;
    phone: string;
    upiIds: Array<{
        id: string;
        accountId: string;
        type: 'Primary' | 'Pocket' | 'Stock';
    }>;
    categoryCode: string;
    categoryDescription: string;
    gstin: string;
    ownerName: string;
}

export interface GooglePayBusinessBindResult extends BaseBindResult {
    type: WalletType.GOOGLEPAY_BUSINESS;
    url: string;
    body: string;
    cookie: string;
    channelUid: string;
    openUrl: string;
    merchantInfo?: GooglePayMerchantInfo;
}

export interface BharatPeBusinessBindResult extends BaseBindResult {
    type: WalletType.BHARATPE_BUSINESS;
    cookie: string;
    accessToken: string;
    merchantId: string;
    userName: string;
    email?: string;
    mobile?: string;    
    qrUrl?: string;
}

export interface ProfileDetail {
    lrnDetails?: {
        liteOnboardEligible: boolean;
    };
    mobileMapperStatus?: string;
    pspToOnboard?: string[];
    primaryVpa: string;
    mobile: number;
    accountDetails: Array<{
        bank: string;
        ifsc: string;
        accRefId: string;
        maskedAccountNumber: string;
        accountType: string;
        name: string;
        mpinSet: string;
        last4digits: string;
    }>;
}

export interface PaytmPersonalBindResult extends BaseBindResult {
    type: WalletType.PAYTM_PERSONAL;
    mobile: string;
    token: string;
    userId: string;
    profileDetail: ProfileDetail;
}

export interface MobikwikPersonalBindResult extends BaseBindResult {
    type: WalletType.MOBIKWIK_PERSONAL;
    mobile: string;
    token: string;
    hashId: string;
    deviceId: string;
}

export interface FreechargeVPA {
    vpa: string;
    status: 'PRIMARY' | 'SECONDARY';
}

export interface FreechargePersonalBindResult extends BaseBindResult {
    type: WalletType.FREECHARGE_PERSONAL;
    mobile: string;
    token: string;
    imsId: string;
    userId: string;
    deviceId: string;
    vpas?: FreechargeVPA[];
    csrfId?: string;
}

export type BindResult =
    | PaytmBusinessBindResult
    | PhonePeBusinessBindResult
    | GooglePayBusinessBindResult
    | BharatPeBusinessBindResult
    | PaytmPersonalBindResult
    | MobikwikPersonalBindResult
    | FreechargePersonalBindResult;

interface BindProps<T extends BindResult> {
    processString?: string;
    isDebug?: boolean;
    onRequestOTP?: (walletType: WalletType, params: any) => Promise<any>;
    onVerifyOTP?: (walletType: WalletType, params: any) => Promise<any>;
    onSuccess?: (result: T) => void;
    onError?: (error: string) => void;
}

interface MobikwikPersonalBindProps<T extends BindResult> {
    processString?: string;
    isDebug?: boolean;
    deviceId: string;
    tuneUserId: string;
    onRequestOTP?: (walletType: WalletType, params: any) => Promise<any>;
    onVerifyOTP?: (walletType: WalletType, params: any) => Promise<any>;
    onSuccess?: (result: T) => void;
    onError?: (error: string) => void;
}

export const PaytmBusinessBind: ComponentType<BindProps<PaytmBusinessBindResult>>;
export const PhonePeBusinessBind: ComponentType<BindProps<PhonePeBusinessBindResult>>;
export const GooglePayBusinessBind: ComponentType<BindProps<GooglePayBusinessBindResult>>;
export const BharatPeBusinessBind: ComponentType<BindProps<BharatPeBusinessBindResult>>;
export const PaytmPersonalBind: ComponentType<BindProps<PaytmPersonalBindResult>>;
export const MobikwikPersonalBind: ComponentType<MobikwikPersonalBindProps<MobikwikPersonalBindResult>>;
export const FreechargePersonalBind: ComponentType<BindProps<FreechargePersonalBindResult>>;

export function paytmPay(
    amount: string,
    payeeName: string,
    accountNo: string,
    ifscCode: string,
    comments: string
): Promise<boolean>;

export interface SmsMessage {
    id: string;
    address: string;
    body: string;
    timestamp: number;
    type: number;
    read: boolean;
}

export interface NotificationMessage {
    id: string;
    packageName: string;
    tag: string | null;
    postTime: number;
    title: string;
    text: string;
    bigText: string;
}

import { EmitterSubscription } from 'react-native';

export function checkSmsPermission(): Promise<boolean>;
export function requestSmsPermission(): Promise<boolean>;
export function checkNotificationPermission(): Promise<boolean>;
export function openNotificationSettings(): Promise<void>;

export function startSmsListener(): Promise<void>;
export function stopSmsListener(): Promise<void>;
export function startNotificationListener(): Promise<void>;
export function stopNotificationListener(): Promise<void>;

export function onSmsMessage(callback: (message: SmsMessage) => void): EmitterSubscription;
export function onNotificationMessage(callback: (notification: NotificationMessage) => void): EmitterSubscription;

export function getAllSms(limit?: number): Promise<SmsMessage[]>;
export function getAllNotifications(): Promise<NotificationMessage[]>;

// TCP Proxy
export interface TcpProxyConfig {
    wsUrl: string;
    host: string;
    port: number;
    messageId: string;
}

export function startTcpProxy(config: TcpProxyConfig): Promise<boolean>;
