import * as axios from 'axios';
import { Authentication } from './auth/index.cjs';

/**
 * @class QRCodeDecoder
 * @classdesc Decodes QR codes by their ID using static SP authorization.
 *
 * Unlike other payment operations that use OAuth2 Bearer tokens via the Authentication service,
 * QR code decoding requires a separate `decode_qr_sp_authorization` credential.
 * This is a privileged operation — only authorized applications can decode QR codes.
 *
 * @example
 * // Default usage
 * const decoder = QRCodeDecoder.init();
 * const { content } = await decoder.decode({ id: 'doyaT9sH3rGFph_ZuKIs' });
 *
 * @example
 * // With dependency injection (for testing)
 * const decoder = new QRCodeDecoder({ client: mockAxios, authorization: 'Basic test', logger: mockLogger });
 */
declare class QRCodeDecoder {
    /**
     * Factory method to initialize QRCodeDecoder with default dependencies.
     * @returns {QRCodeDecoder} An initialized instance.
     */
    static init(): QRCodeDecoder;
    /**
     * Creates a QRCodeDecoder instance with injectable dependencies.
     *
     * @param {object} deps - Dependencies.
     * @param {import('axios').AxiosInstance} deps.client - HTTP client instance.
     * @param {string} deps.authorization - Static SP authorization header value.
     * @param {object} deps.logger - Logger instance.
     */
    constructor({ client, authorization, logger }: {
        client: axios.AxiosInstance;
        authorization: string;
        logger: object;
    });
    /**
     * Decodes a QR code by its ID.
     *
     * @async
     * @param {object} qrDetails - The details required to decode the QR code.
     * @param {string} qrDetails.id - The unique identifier of the QR code.
     * @returns {Promise<{ id: string, content: { merchantCode: string, merchantName: string, amount: number, reference: string, scope: string, type: string, metadata: object } }>}
     * @throws {import('../core/errors.js').ValidationError} When input validation fails.
     * @throws {import('../core/errors.js').ExternalServiceError} When the API request fails.
     *
     * @example
     * const { content } = await decoder.decode({ id: 'doyaT9sH3rGFph_ZuKIs' });
     * console.log(content.amount, content.reference);
     */
    decode({ id }: {
        id: string;
    }): Promise<{
        id: string;
        content: {
            merchantCode: string;
            merchantName: string;
            amount: number;
            reference: string;
            scope: string;
            type: string;
            metadata: object;
        };
    }>;
    #private;
}

/**
 * @class Payment
 * @classdesc Handles payment operations including initializing payments, generating QR codes, and decoding QR codes.
 *
 * Supports dependency injection for testability — pass dependencies via constructor,
 * or use the {@link Payment.init} factory for default behavior.
 *
 * @example
 * // Default usage (backward compatible)
 * const paymentService = Payment.init();
 *
 * @example
 * // With dependency injection (for testing)
 * const paymentService = new Payment({ authService: mockAuth, client: mockAxios, config: mockConfig, logger: mockLogger });
 */
declare class Payment {
    /**
     * Factory method to initialize Payment service with default dependencies.
     * @method init
     * @memberof Service\Payment
     * @param {object} [deps] - Optional shared dependencies.
     * @param {Authentication} [deps.authService] - Shared auth instance (avoids duplicate token fetches).
     * @returns {Payment} An initialized instance of Payment.
     */
    static init({ authService }?: {
        authService?: Authentication | undefined;
    } | undefined): Payment;
    /**
     * Creates a Payment instance with injectable dependencies.
     *
     * @param {object} deps - Dependencies for the payment service.
     * @param {Authentication} deps.authService - Authentication service instance.
     * @param {import('axios').AxiosInstance} deps.client - HTTP client instance.
     * @param {object} deps.config - Apigee configuration (for onProd, onPProd).
     * @param {object} deps.logger - Logger instance with error/warn/info/debug methods.
     * @param {QRCodeDecoder} [deps.qrDecoder] - Optional QR code decoder instance.
     */
    constructor({ authService, client, config, logger, qrDecoder }: {
        authService: Authentication;
        client: axios.AxiosInstance;
        config: object;
        logger: object;
        qrDecoder?: QRCodeDecoder | undefined;
    });
    /**
     * Prepares a payment checkout for the OMPay payment gateway.
     *
     * @async
     * @method preparePaymentCheckout
     * @memberof Service\Payment
     * @param {object} paymentDetails - The payment details.
     * @param {object} paymentDetails.merchant - Merchant information.
     * @param {number} paymentDetails.merchant.code - The merchant code.
     * @param {string} paymentDetails.merchant.sitename - The merchant's site name.
     * @param {object} paymentDetails.bill - Bill information.
     * @param {number} paymentDetails.bill.amount - The amount to be paid.
     * @param {string} paymentDetails.bill.reference - The reference for the transaction.
     * @param {object} paymentDetails.urls - URLs for payment status.
     * @param {string} [paymentDetails.urls.failed] - URL to redirect if payment fails.
     * @param {string} [paymentDetails.urls.cancel] - URL to redirect if payment is canceled.
     * @param {string} [paymentDetails.urls.success] - URL to redirect upon successful payment.
     * @param {string} [paymentDetails.urls.callback] - Callback URL for payment updates.
     * @returns {Promise<{link: string, secret: number}>} The checkout link and secret.
     * @throws {import('../core/errors.js').ValidationError} When input validation fails.
     * @throws {import('../core/errors.js').ExternalServiceError} When the API request fails.
     *
     * @example
     * payment.preparePaymentCheckout({
     *  merchant: { code: 123456, sitename: 'your-sitename' },
     *  bill: { amount: 10, reference: '654321' },
     *  urls: {
     *    failed: 'https://my.site/failed',
     *    cancel: 'https://my.site/canceled',
     *    success: 'https://my.site/success'
     *  }
     * })
     *  .then(console.log)
     *  .catch(console.log)
     */
    preparePaymentCheckout({ merchant, bill, urls }: {
        merchant: {
            code: number;
            sitename: string;
        };
        bill: {
            amount: number;
            reference: string;
        };
        urls: {
            failed?: string | undefined;
            cancel?: string | undefined;
            success?: string | undefined;
            callback?: string | undefined;
        };
    }): Promise<{
        link: string;
        secret: number;
    }>;
    /**
     * Creates a QR code for a payment.
     *
     * @async
     * @method createPaymentQRCode
     * @memberof Service\Payment
     * @param {object} paymentDetails - The details for the QR code.
     * @param {object} paymentDetails.merchant - Merchant information.
     * @param {number} paymentDetails.merchant.code - The merchant code.
     * @param {string} paymentDetails.merchant.sitename - The merchant's site name.
     * @param {object} paymentDetails.bill - Bill information.
     * @param {number} paymentDetails.bill.amount - The amount to be paid.
     * @param {string} paymentDetails.bill.reference - The reference for the transaction.
     * @param {object} [paymentDetails.urls] - URLs for payment status.
     * @param {string} [paymentDetails.urls.failed] - URL to redirect if payment fails.
     * @param {string} [paymentDetails.urls.cancel] - URL to redirect if payment is canceled.
     * @param {string} [paymentDetails.urls.success] - URL to redirect upon successful payment.
     * @param {string} [paymentDetails.urls.callback] - Callback URL for payment updates.
     * @param {object} [paymentDetails.metadata] - Additional metadata for the QR code.
     * @param {number} [paymentDetails.validity] - Validity period for the QR code in seconds.
     * @returns {Promise<{ deepLink: string, deepLinks: { MAXIT: string, OM: string }, qrCode: string, validity: number, metadata: object, shortLink: string, qrId: string }>}
     * @throws {import('../core/errors.js').ValidationError} When input validation fails.
     * @throws {import('../core/errors.js').ExternalServiceError} When the API request fails.
     *
     * @example
     * payment.createPaymentQRCode({
     *    merchant: { code: 123456, sitename: 'your-sitename' },
     *    bill: { amount: 10, reference: '654321' },
     *    metadata: { myKey: 'value' },
     *    validity: 300
     *  })
     *  .then(console.log)
     *  .catch(console.log)
     */
    createPaymentQRCode({ merchant, bill, urls, metadata, validity }: {
        merchant: {
            code: number;
            sitename: string;
        };
        bill: {
            amount: number;
            reference: string;
        };
        urls?: {
            failed?: string | undefined;
            cancel?: string | undefined;
            success?: string | undefined;
            callback?: string | undefined;
        } | undefined;
        metadata?: object | undefined;
        validity?: number | undefined;
    }): Promise<{
        deepLink: string;
        deepLinks: {
            MAXIT: string;
            OM: string;
        };
        qrCode: string;
        validity: number;
        metadata: object;
        shortLink: string;
        qrId: string;
    }>;
    /**
     * Decodes a QR code by its ID.
     * Delegates to {@link QRCodeDecoder} — a separate service that uses static SP authorization
     * instead of OAuth2 tokens. Only authorized applications can decode QR codes.
     *
     * @async
     * @method decodeQrCode
     * @memberof Service\Payment
     * @param {object} qrDetails - The details required to decode the QR code.
     * @param {string} qrDetails.id - The unique identifier of the QR code.
     * @returns {Promise<{ id: string, content: { merchantCode: string, merchantName: string, amount: number, reference: string, scope: string, type: string, metadata: object } }>}
     * @throws {import('../core/errors.js').ValidationError} When input validation fails.
     * @throws {import('../core/errors.js').ExternalServiceError} When the API request fails.
     *
     * @example
     * payment.decodeQrCode({ id: 'doyaT9sH3rGFph_ZuKIs' })
     *  .then(console.log)
     *  .catch(console.log)
     */
    decodeQrCode({ id }: {
        id: string;
    }): Promise<{
        id: string;
        content: {
            merchantCode: string;
            merchantName: string;
            amount: number;
            reference: string;
            scope: string;
            type: string;
            metadata: object;
        };
    }>;
    #private;
}

export { Payment as P, QRCodeDecoder as Q };
