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

export class SSLCommerzService {
  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://securepay.sslcommerz.com'
      : 'https://sandbox.sslcommerz.com';
  }

  private static mapChannelsToCardNames(channels?: string[]): string {
    if (!channels || channels.length === 0) {
      return '';
    }

    const channelMap: Record<string, string[]> = {
      cards: ['mastercard', 'visa', 'amex', 'othercard'],
      bkash: ['bkash'],
      nagad: ['nagad'],
      rocket: ['dbblmobilebanking', 'rocket'],
      internet_banking: ['internetbank', 'citybank', 'bracbank', 'ebl', 'dbblnexus', 'islamibank'],
    };

    const cardNames: string[] = [];
    channels.forEach(ch => {
      const mapped = channelMap[ch];
      if (mapped) {
        cardNames.push(...mapped);
      } else {
        cardNames.push(ch);
      }
    });

    return Array.from(new Set(cardNames)).join(',');
  }

  /**
   * Initiate SSLCommerz Payment 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; sessionKey?: string; message?: string }> {
    // 1. Enforce Gateway Enabled Check
    if (!config.is_enabled) {
      return {
        success: false,
        message: 'SSLCommerz 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 SSLCommerz have been turned OFF in settings.',
        };
      }
      if (requestedChannel && !config.allowed_channels.includes(requestedChannel)) {
        return {
          success: false,
          message: `Payment method "${requestedChannel}" is currently disabled for SSLCommerz.`,
        };
      }
    }

    const successUrl = `${appBaseUrl}/api/payments/sslcommerz/callback`;
    const failUrl = `${appBaseUrl}/api/payments/sslcommerz/callback`;
    const cancelUrl = `${appBaseUrl}/api/payments/sslcommerz/callback`;
    const ipnUrl = `${appBaseUrl}/api/payments/sslcommerz/ipn`;
    const multiCardName = this.mapChannelsToCardNames(config.allowed_channels);

    if (config.mode === 'live') {
      if (!config.store_id || !config.store_password) {
        return {
          success: false,
          message: 'SSLCommerz Store ID and Store Password are required in Live mode.',
        };
      }

      try {
        const baseUrl = this.getBaseUrl(config);
        const params = new URLSearchParams();
        params.append('store_id', config.store_id);
        params.append('store_passwd', config.store_password);
        params.append('total_amount', txn.amount.toString());
        params.append('currency', 'BDT');
        params.append('tran_id', txn.transaction_id);
        params.append('success_url', successUrl);
        params.append('fail_url', failUrl);
        params.append('cancel_url', cancelUrl);
        params.append('ipn_url', ipnUrl);
        params.append('product_name', `Outbid Spot: ${txn.listing_name}`);
        params.append('product_category', 'Digital Promotion');
        params.append('product_profile', 'general');
        params.append('cus_name', txn.listing_name);
        params.append('cus_email', 'bidder@topbd.com');
        params.append('cus_add1', 'Dhaka, Bangladesh');
        params.append('cus_city', 'Dhaka');
        params.append('cus_country', 'Bangladesh');
        params.append('cus_phone', '01700000000');
        params.append('shipping_method', 'NO');

        if (multiCardName) {
          params.append('multi_card_name', multiCardName);
        }

        const res = await fetch(`${baseUrl}/gwprocess/v4/api.php`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
          body: params.toString(),
        });

        const data: any = await res.json();
        if (data.status === 'SUCCESS' && data.GatewayPageURL) {
          return {
            success: true,
            gatewayUrl: data.GatewayPageURL,
            sessionKey: data.sessionkey,
          };
        }

        return {
          success: false,
          message: data.failedreason || 'SSLCommerz payment session initialization failed.',
        };
      } catch (err: any) {
        return {
          success: false,
          message: err.message || 'Failed to connect to SSLCommerz API.',
        };
      }
    }

    // Sandbox / Test Mode with Real Sandbox Store Credentials
    if (config.store_id && config.store_password && config.store_id !== 'topbd_sandbox_01') {
      try {
        const baseUrl = this.getBaseUrl(config);
        const params = new URLSearchParams();
        params.append('store_id', config.store_id);
        params.append('store_passwd', config.store_password);
        params.append('total_amount', txn.amount.toString());
        params.append('currency', 'BDT');
        params.append('tran_id', txn.transaction_id);
        params.append('success_url', successUrl);
        params.append('fail_url', failUrl);
        params.append('cancel_url', cancelUrl);
        params.append('ipn_url', ipnUrl);
        params.append('product_name', `Outbid Spot: ${txn.listing_name}`);
        params.append('product_category', 'Digital Promotion');
        params.append('product_profile', 'general');
        params.append('cus_name', txn.listing_name);
        params.append('cus_email', 'bidder@topbd.com');
        params.append('cus_add1', 'Dhaka');
        params.append('cus_city', 'Dhaka');
        params.append('cus_country', 'Bangladesh');
        params.append('cus_phone', '01700000000');
        params.append('shipping_method', 'NO');

        if (multiCardName) {
          params.append('multi_card_name', multiCardName);
        }

        const res = await fetch(`${baseUrl}/gwprocess/v4/api.php`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
          body: params.toString(),
        });

        const data: any = await res.json();
        if (data.status === 'SUCCESS' && data.GatewayPageURL) {
          return {
            success: true,
            gatewayUrl: data.GatewayPageURL,
            sessionKey: data.sessionkey,
          };
        }
      } catch {
        // Fallback to sandbox simulator
      }
    }

    return {
      success: true,
      gatewayUrl: `/payment-sandbox?txn=${txn.transaction_id}&gw=sslcommerz`,
      sessionKey: `SSL_DEMO_${txn.transaction_id}`,
    };
  }

  /**
   * Validate SSLCommerz Transaction (Server-to-Server Validation API)
   */
  public static async validateTransaction(
    config: GatewaySecretConfig,
    valId: string,
    expectedAmount?: number,
    expectedTxnId?: string
  ): Promise<{ valid: boolean; data?: any; message?: string }> {
    if (valId.startsWith('SSL_DEMO_') || valId.startsWith('SIM_')) {
      return {
        valid: true,
        data: {
          val_id: valId,
          tran_id: expectedTxnId || valId,
          amount: expectedAmount || 0,
          currency: 'BDT',
          status: 'VALID',
          simulated: true,
        },
      };
    }

    try {
      const baseUrl = this.getBaseUrl(config);
      const url = `${baseUrl}/validator/api/validationserverAPI.php?val_id=${encodeURIComponent(
        valId
      )}&store_id=${encodeURIComponent(config.store_id || '')}&store_passwd=${encodeURIComponent(
        config.store_password || ''
      )}&format=json`;

      const res = await fetch(url);
      const data: any = await res.json();

      const isValidStatus = data.status === 'VALID' || data.status === 'VALIDATED';
      if (!isValidStatus) {
        return {
          valid: false,
          data,
          message: data.error || data.failedreason || `Transaction status was not VALID (received: ${data.status})`,
        };
      }

      // Check transaction ID if provided
      if (expectedTxnId && data.tran_id && data.tran_id !== expectedTxnId) {
        return {
          valid: false,
          data,
          message: `Transaction identifier mismatch: expected ${expectedTxnId}, received ${data.tran_id}`,
        };
      }

      // Check amount
      const returnedAmount = parseFloat(data.amount || data.currency_amount || '0');
      if (expectedAmount !== undefined && expectedAmount > 0) {
        const isAmountMatching = Math.abs(returnedAmount - expectedAmount) <= 0.01;
        if (!isAmountMatching) {
          return {
            valid: false,
            data,
            message: `Amount mismatch: expected ৳${expectedAmount}, processed ৳${returnedAmount}`,
          };
        }
      }

      return {
        valid: true,
        data,
      };
    } catch (err: any) {
      return { valid: false, message: err.message || 'Failed to validate SSLCommerz transaction.' };
    }
  }
}
