const crypto = require('crypto');
const https = require('https');

/**
 * PayTR Ödeme Entegrasyon Modülü
 * Doküman: https://www.paytr.com/entegrasyon
 */

class PayTR {
  constructor(config) {
    this.merchant_id = config.merchant_id;
    this.merchant_key = config.merchant_key;
    this.merchant_salt = config.merchant_salt;
    this.test_mode = config.test_mode || false;
    this.success_url = config.success_url || 'http://localhost:5173/payment/success';
    this.fail_url = config.fail_url || 'http://localhost:5173/payment/fail';
  }

  /**
   * PayTR iframe token oluşturur
   * @param {Object} orderData - Sipariş bilgileri
   * @returns {Promise<Object>} - Token ve iframe URL
   */
  async createPaymentToken(orderData) {
    try {
      const {
        merchant_oid,        // Sipariş numarası (benzersiz olmalı)
        email,               // Müşteri email
        payment_amount,      // Ödeme tutarı (kuruş cinsinden)
        user_basket,         // Sepet içeriği (JSON string)
        user_name,           // Müşteri adı
        user_address,        // Müşteri adresi
        user_phone,          // Müşteri telefonu
        user_ip,             // Müşteri IP adresi
        currency = 'TL',     // Para birimi (TL, EUR, USD)
        no_installment = 0,  // Taksit yok: 1, Var: 0
        max_installment = 0, // Maksimum taksit sayısı
        debug_on = 1,        // Test modu: 1, Canlı: 0
        lang = 'tr'          // Dil
      } = orderData;

      // PayTR merchant_oid max 64 karakter olmalı
      const trimmed_merchant_oid = merchant_oid.substring(0, 64);

      // Hash oluşturma (PayTR dokümanına göre)
      // Sıra: merchant_id + user_ip + merchant_oid + email + payment_amount + user_basket + no_installment + max_installment + currency + test_mode
      const test_mode_str = debug_on !== undefined ? String(debug_on) : (this.test_mode ? '1' : '0');
      const hashSTR = `${this.merchant_id}${user_ip}${trimmed_merchant_oid}${email}${payment_amount}${user_basket}${no_installment}${max_installment}${currency}${test_mode_str}`;
      const paytr_token = this.createHash(hashSTR);

      // PayTR API'ye gönderilecek data
      // ÖNEMLİ: merchant_key ve merchant_salt GÖNDERİLMEMELİ!
      const postData = {
        merchant_id: this.merchant_id,
        user_ip: user_ip,
        merchant_oid: trimmed_merchant_oid,
        email: email,
        payment_amount: payment_amount,
        paytr_token: paytr_token,
        user_basket: user_basket,
        debug_on: debug_on || (this.test_mode ? '1' : '0'),
        no_installment: no_installment,
        max_installment: max_installment,
        user_name: user_name,
        user_address: user_address,
        user_phone: user_phone,
        merchant_ok_url: this.success_url,
        merchant_fail_url: this.fail_url,
        timeout_limit: '30',
        currency: currency,
        lang: lang
      };

      // PayTR'a gönderilen veriyi logla
      console.log('📤 PayTR Request:', {
        merchant_id: postData.merchant_id,
        merchant_oid: postData.merchant_oid,
        email: postData.email,
        payment_amount: postData.payment_amount,
        user_basket: postData.user_basket,
        debug_on: postData.debug_on
      });

      // PayTR API çağrısı
      const response = await this.makeRequest('https://www.paytr.com/odeme/api/get-token', postData);

      console.log('📥 PayTR Response:', response);

      if (response.status === 'success') {
        return {
          success: true,
          token: response.token,
          iframeUrl: `https://www.paytr.com/odeme/guvenli/${response.token}`
        };
      } else {
        console.error('❌ PayTR Error:', response);
        return {
          success: false,
          error: response.reason || 'PayTR token oluşturulamadı'
        };
      }
    } catch (error) {
      console.error('PayTR Token Error:', error);
      return {
        success: false,
        error: error.message
      };
    }
  }

  /**
   * PayTR callback doğrulama
   * @param {Object} callbackData - PayTR'dan gelen callback verisi
   * @returns {Object} - Doğrulama sonucu
   */
  verifyCallback(callbackData) {
    try {
      const {
        merchant_oid,
        status,
        total_amount,
        hash
      } = callbackData;

      // Hash doğrulama
      const hashSTR = `${merchant_oid}${this.merchant_salt}${status}${total_amount}`;
      const calculatedHash = this.createHash(hashSTR);

      if (hash !== calculatedHash) {
        return {
          success: false,
          error: 'Hash doğrulama hatası',
          status: 'failed'
        };
      }

      // Ödeme durumuna göre sonuç
      if (status === 'success') {
        return {
          success: true,
          status: 'success',
          merchant_oid: merchant_oid,
          total_amount: total_amount
        };
      } else {
        return {
          success: false,
          status: 'failed',
          merchant_oid: merchant_oid,
          error: 'Ödeme başarısız'
        };
      }
    } catch (error) {
      console.error('PayTR Callback Error:', error);
      return {
        success: false,
        error: error.message,
        status: 'error'
      };
    }
  }

  /**
   * Hash oluşturma (HMAC SHA256)
   * @param {String} str - Hash edilecek string
   * @returns {String} - Base64 encoded hash
   */
  createHash(str) {
    return crypto
      .createHmac('sha256', this.merchant_key)
      .update(str + this.merchant_salt)
      .digest('base64');
  }

  /**
   * PayTR API'ye HTTPS POST isteği gönder
   * @param {String} url - API URL
   * @param {Object} data - POST verisi
   * @returns {Promise<Object>} - API yanıtı
   */
  makeRequest(url, data) {
    return new Promise((resolve, reject) => {
      const postDataStr = Object.keys(data)
        .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`)
        .join('&');

      const options = {
        method: 'POST',
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
          'Content-Length': Buffer.byteLength(postDataStr)
        }
      };

      const req = https.request(url, options, (res) => {
        let body = '';

        res.on('data', (chunk) => {
          body += chunk;
        });

        res.on('end', () => {
          try {
            const response = JSON.parse(body);
            resolve(response);
          } catch (error) {
            reject(new Error('PayTR yanıtı parse edilemedi: ' + body));
          }
        });
      });

      req.on('error', (error) => {
        reject(error);
      });

      req.write(postDataStr);
      req.end();
    });
  }

  /**
   * Ödeme tutarını kuruşa çevir
   * @param {Number} amount - TL/EUR cinsinden tutar
   * @returns {Number} - Kuruş cinsinden tutar
   */
  static amountToKurus(amount) {
    return Math.round(amount * 100);
  }

  /**
   * Kuruşu TL/EUR'ye çevir
   * @param {Number} kurus - Kuruş cinsinden tutar
   * @returns {Number} - TL/EUR cinsinden tutar
   */
  static kurusToAmount(kurus) {
    return (kurus / 100).toFixed(2);
  }

  /**
   * Sepet içeriği JSON formatına çevir ve Base64 encode et
   * @param {Array} items - Sepet içeriği [{name, price, quantity}]
   * @returns {String} - Base64 encoded JSON string
   */
  static createUserBasket(items) {
    const basketItems = items.map(item => [
      item.name || 'Ürün',
      String(item.price || 0),
      item.quantity || 1
    ]);
    const jsonString = JSON.stringify(basketItems);
    return Buffer.from(jsonString).toString('base64');
  }

  /**
   * Test için örnek ödeme verisi oluştur
   * @returns {Object} - Test ödeme verisi
   */
  static createTestData() {
    return {
      merchant_oid: 'TEST-' + Date.now(),
      email: 'test@example.com',
      payment_amount: 10000, // 100.00 TL
      user_basket: this.createUserBasket([
        { name: 'Test Tur', price: 100, quantity: 1 }
      ]),
      user_name: 'Test User',
      user_address: 'Test Address',
      user_phone: '5551234567',
      user_ip: '127.0.0.1',
      currency: 'TL',
      no_installment: 0,
      max_installment: 0,
      debug_on: 1
    };
  }
}

module.exports = PayTR;
