import { GatewaySecretConfig, ServerTransaction } from './types';

export class AamarPayService {
  private static getBaseUrl(config: GatewaySecretConfig): string {
    if (config.api_url && config.api_url.trim()) {
      return config.api_url.trim().replace(/\/+$/, '');
    }
    return config.mode === 'live'
      ? 'https://secure.aamarpay.com'
      : 'https://sandbox.aamarpay.com';
  }

  /**
   * Initiate aamarPay Hosted Checkout Session
   * Enforces admin-configured individual payment-method ON/OFF settings (allowed_channels)
   */
  public static async initPayment(
    config: GatewaySecretConfig,
    txn: ServerTransaction,
    appBaseUrl: string,
    requestedChannel?: string
  ): Promise<{ success: boolean; gatewayUrl?: string; message?: string }> {
    // 1. Enforce Gateway Enabled Check
    if (!config.is_enabled) {
      return {
        success: false,
        message: 'aamarPay payment gateway is currently disabled by administrator.',
      };
    }

    // 2. Enforce Admin-Configured Channel ON/OFF Settings
    if (config.allowed_channels !== undefined) {
      if (config.allowed_channels.length === 0) {
        return {
          success: false,
          message: 'All payment methods/channels for aamarPay have been turned OFF in settings.',
        };
      }
      if (requestedChannel && !config.allowed_channels.includes(requestedChannel)) {
        return {
          success: false,
          message: `Payment method "${requestedChannel}" is currently disabled for aamarPay.`,
        };
      }
    }

    const successUrl = `${appBaseUrl}/api/payments/aamarpay/callback`;
    const failUrl = `${appBaseUrl}/api/payments/aamarpay/callback`;
    const cancelUrl = `${appBaseUrl}/api/payments/aamarpay/callback`;

    const storeId = config.store_id || config.merchant_id || (config.mode === 'live' ? '' : 'aamarpaytest');
    const signatureKey = config.signature_key || config.app_secret || config.app_key || (config.mode === 'live' ? '' : 'dbb74892e8241a45a7f0144916d6664e');
    const channelsString = config.allowed_channels && config.allowed_channels.length > 0
      ? config.allowed_channels.join(',')
      : 'cards,bkash,nagad,rocket,internet_banking';

    // Live mode verification of credentials
    if (config.mode === 'live') {
      if (!storeId || !signatureKey) {
        return {
          success: false,
          message: 'aamarPay Store ID and Signature Key are required in Live mode.',
        };
      }

      try {
        const baseUrl = this.getBaseUrl(config);
        const payload = {
          store_id: storeId,
          signature_key: signatureKey,
          tran_id: txn.transaction_id,
          success_url: successUrl,
          fail_url: failUrl,
          cancel_url: cancelUrl,
          amount: txn.amount.toString(),
          currency: 'BDT',
          desc: `Outbid Spot: ${txn.listing_name}`,
          cus_name: txn.listing_name,
          cus_email: 'bidder@topbd.com',
          cus_phone: '01700000000',
          cus_add1: 'Dhaka, Bangladesh',
          cus_city: 'Dhaka',
          cus_country: 'Bangladesh',
          opt_a: txn.listing_id,
          opt_b: txn.category_id,
          opt_c: channelsString,
          type: 'json',
        };

        const res = await fetch(`${baseUrl}/jsonpost.php`, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Accept': 'application/json',
          },
          body: JSON.stringify(payload),
        });

        const rawText = await res.text();
        let data: any;
        try {
          data = JSON.parse(rawText);
        } catch {
          // If server returned plain text or redirect URL string
          if (rawText.startsWith('http://') || rawText.startsWith('https://')) {
            return {
              success: true,
              gatewayUrl: rawText.trim(),
            };
          }
          return {
            success: false,
            message: rawText || 'Unexpected response format from aamarPay API.',
          };
        }

        // aamarPay JSON format response
        if (data.payment_url) {
          return {
            success: true,
            gatewayUrl: data.payment_url,
          };
        }

        if (data.result === 'true' && data.payment_url) {
          return {
            success: true,
            gatewayUrl: data.payment_url,
          };
        }

        return {
          success: false,
          message: data.reason || data.message || 'aamarPay session initialization was rejected.',
        };
      } catch (err: any) {
        return {
          success: false,
          message: err.message || 'Failed to connect to aamarPay server.',
        };
      }
    }

    // Sandbox / Test Mode with Custom Configured Sandbox Credentials
    if (storeId && signatureKey && storeId !== 'aamarpaytest') {
      try {
        const baseUrl = this.getBaseUrl(config);
        const payload = {
          store_id: storeId,
          signature_key: signatureKey,
          tran_id: txn.transaction_id,
          success_url: successUrl,
          fail_url: failUrl,
          cancel_url: cancelUrl,
          amount: txn.amount.toString(),
          currency: 'BDT',
          desc: `Outbid Spot: ${txn.listing_name}`,
          cus_name: txn.listing_name,
          cus_email: 'bidder@topbd.com',
          cus_phone: '01700000000',
          cus_add1: 'Dhaka',
          cus_city: 'Dhaka',
          cus_country: 'Bangladesh',
          opt_a: txn.listing_id,
          opt_b: txn.category_id,
          opt_c: channelsString,
          type: 'json',
        };

        const res = await fetch(`${baseUrl}/jsonpost.php`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
          body: JSON.stringify(payload),
        });

        const rawText = await res.text();
        try {
          const data = JSON.parse(rawText);
          if (data.payment_url) {
            return {
              success: true,
              gatewayUrl: data.payment_url,
            };
          }
        } catch {
          if (rawText.startsWith('http://') || rawText.startsWith('https://')) {
            return {
              success: true,
              gatewayUrl: rawText.trim(),
            };
          }
        }
      } catch {
        // Fallback to interactive sandbox tester
      }
    }

    // Default Sandbox Simulator Flow
    return {
      success: true,
      gatewayUrl: `/payment-sandbox?txn=${txn.transaction_id}&gw=aamarpay`,
    };
  }

  /**
   * Verify aamarPay Transaction with Server-to-Server Verification API.
   *
   * CRITICAL SECURITY REQUIREMENTS:
   * 1. pg_txnid existence alone NEVER means successful payment.
   * 2. Must verify actual success status ('Successful' / 'SUCCESS' / status_code '2').
   * 3. Must verify transaction identifier matches expected merchant order ID.
   * 4. Must verify exact amount processed matches expected BDT amount.
   * 5. Must verify currency is BDT.
   */
  public static async verifyTransaction(
    config: GatewaySecretConfig,
    pgTxnIdOrMerTxnId: string,
    expectedAmount?: number,
    expectedTxnId?: string
  ): Promise<{ valid: boolean; data?: any; message?: string }> {
    // Simulator test mode bypass (explicitly generated sandbox tokens only)
    if (pgTxnIdOrMerTxnId.startsWith('SIM_AAMARPAY_') || pgTxnIdOrMerTxnId.startsWith('SIM_')) {
      return {
        valid: true,
        data: {
          pg_txnid: pgTxnIdOrMerTxnId,
          mer_txnid: expectedTxnId || pgTxnIdOrMerTxnId,
          amount: expectedAmount || 0,
          currency: 'BDT',
          pay_status: 'Successful',
          status_code: '2',
          simulated: true,
          mode: 'test_sandbox',
        },
      };
    }

    try {
      const baseUrl = this.getBaseUrl(config);
      const storeId = config.store_id || config.merchant_id || (config.mode === 'live' ? '' : 'aamarpaytest');
      const signatureKey = config.signature_key || config.app_secret || config.app_key || (config.mode === 'live' ? '' : 'dbb74892e8241a45a7f0144916d6664e');

      if (!storeId || !signatureKey) {
        return {
          valid: false,
          message: 'aamarPay credentials missing for server verification.',
        };
      }

      const checkUrl = `${baseUrl}/api/v1/trxcheck/request.php?request_id=${encodeURIComponent(
        pgTxnIdOrMerTxnId
      )}&store_id=${encodeURIComponent(storeId)}&signature_key=${encodeURIComponent(
        signatureKey
      )}&type=json`;

      const res = await fetch(checkUrl, {
        headers: { Accept: 'application/json' },
      });

      const rawText = await res.text();
      let data: any;
      try {
        data = JSON.parse(rawText);
      } catch {
        return {
          valid: false,
          message: 'Invalid non-JSON response received from aamarPay verification API.',
        };
      }

      // Check for API-level errors
      if (data.status === 'failed' || data.result === 'false' || data.error) {
        return {
          valid: false,
          data,
          message: data.reason || data.error || data.message || 'aamarPay verification returned failed status.',
        };
      }

      // 1. Verify Actual Success Status (pg_txnid presence alone is STRICTLY INSUFFICIENT)
      const rawStatus = (data.pay_status || data.status_title || data.status || '').toString().trim().toLowerCase();
      const statusCode = (data.status_code || '').toString().trim();

      const isStatusSuccessful =
        (rawStatus === 'successful' || rawStatus === 'success' || statusCode === '2') &&
        !rawStatus.includes('fail') &&
        !rawStatus.includes('cancel') &&
        !rawStatus.includes('pend') &&
        !rawStatus.includes('reject') &&
        !rawStatus.includes('declin') &&
        statusCode !== '0' &&
        statusCode !== '7';

      if (!isStatusSuccessful) {
        return {
          valid: false,
          data,
          message: data.reason || data.error_title || `Payment is not successful (status: ${data.pay_status || data.status_title || 'Unknown'}).`,
        };
      }

      // 2. Verify Transaction Identifier
      const returnedMerchantTxn = (data.mer_txnid || data.tran_id || data.opt_a || '').toString().trim();
      const returnedPgTxn = (data.pg_txnid || '').toString().trim();

      if (expectedTxnId && expectedTxnId.trim()) {
        const exp = expectedTxnId.trim();
        const isTxnMatched = (
          returnedMerchantTxn === exp ||
          returnedPgTxn === exp ||
          pgTxnIdOrMerTxnId.trim() === returnedMerchantTxn ||
          pgTxnIdOrMerTxnId.trim() === returnedPgTxn
        );

        if (!isTxnMatched) {
          return {
            valid: false,
            data,
            message: `Transaction identifier mismatch: expected ${expectedTxnId}, received ${returnedMerchantTxn || returnedPgTxn}`,
          };
        }
      }

      // 3. Verify Exact Payment Amount
      const returnedAmount = parseFloat(
        data.amount_original || data.amount_bdt || data.amount || data.rec_amount || '0'
      );

      if (expectedAmount !== undefined && expectedAmount > 0) {
        const isAmountMatching = Math.abs(returnedAmount - expectedAmount) <= 0.01;
        if (!isAmountMatching) {
          return {
            valid: false,
            data,
            message: `Payment amount mismatch: expected ৳${expectedAmount}, but aamarPay processed ৳${returnedAmount}`,
          };
        }
      }

      // 4. Verify Currency
      const returnedCurrency = (data.currency || data.currency_name || 'BDT').toString().toUpperCase();
      if (returnedCurrency !== 'BDT' && returnedCurrency !== 'TK') {
        return {
          valid: false,
          data,
          message: `Invalid transaction currency: expected BDT, received ${returnedCurrency}`,
        };
      }

      // 5. Must have a valid non-empty gateway pg_txnid
      if (!returnedPgTxn) {
        return {
          valid: false,
          data,
          message: 'Missing pg_txnid in aamarPay verification response.',
        };
      }

      return {
        valid: true,
        data,
      };
    } catch (err: any) {
      return {
        valid: false,
        message: err.message || 'Failed to verify transaction with aamarPay API.',
      };
    }
  }
}
