/**
 * PaySo (Thai e-Payment) Integration
 * 
 * Thai payment gateway supporting:
 * - QR Code (PromptPay)
 * - Credit Card
 * - Bank Transfer
 * 
 * Documentation: https://www.paysolutions.asia/
 */

export interface PaySoPaymentRequest {
  merchantid: string;
  refno: string;
  customeremail: string;
  productdetail: string;
  total: number;
  cc?: string;
  lang?: string;
}

export interface PaySoInquiryRequest {
  merchantId: string;
  orderNo: string;
  refNo: string;
  productDetail: string;
}

export interface PaySoPaymentData {
  referenceNo: string;
  orderNo: string;
  amount: number;
  qrCode?: string;
  paymentUrl?: string;
  paymentDate?: string;
  status?: string;
}

export interface PaySoPaymentResponse {
  status: number;
  message: string;
  data?: PaySoPaymentData;
}

export interface PaySoConfig {
  merchantId: string;
  apiKey: string;
  secretKey: string;
}

// API endpoints
const PAYSO_API_URL = import.meta.env.PAYSO_API_URL || 'https://www.thaiepay.com/epaylink/payment.aspx';
const PAYSO_INQUIRY_URL = import.meta.env.PAYSO_INQUIRY_URL || 'https://apis.paysolutions.asia/order/orderdetailpost';
const PAYSO_REFUND_URL = import.meta.env.PAYSO_REFUND_URL || 'https://apis.paysolutions.asia/refund/refundpost';

export class PaySoClient {
  private merchantId: string;
  private apiKey: string;
  private secretKey: string;

  constructor(merchantId: string, apiKey: string, secretKey: string) {
    this.merchantId = merchantId;
    this.apiKey = apiKey;
    this.secretKey = secretKey;
  }

  /**
   * Create PaySo payment URL (redirect user to payment page)
   */
  createPaymentUrl(params: {
    refno: string;
    customeremail: string;
    productdetail: string;
    total: number;
    cc?: string;
    lang?: string;
    returnUrl?: string;
    callbackUrl?: string;
  }): string {
    const url = new URL(PAYSO_API_URL);
    
    // Required parameters
    url.searchParams.append('merchantid', this.merchantId);
    url.searchParams.append('refno', params.refno);
    url.searchParams.append('customeremail', params.customeremail);
    url.searchParams.append('productdetail', params.productdetail);
    url.searchParams.append('total', params.total.toFixed(2));
    
    // Optional parameters
    if (params.cc) {
      url.searchParams.append('cc', params.cc);
    } else {
      // Enable all payment methods by default
      url.searchParams.append('cc', 'y');
    }
    
    if (params.lang) {
      url.searchParams.append('lang', params.lang);
    } else {
      url.searchParams.append('lang', 'TH');
    }
    
    if (params.returnUrl) {
      url.searchParams.append('returnUrl', params.returnUrl);
    }
    
    if (params.callbackUrl) {
      url.searchParams.append('callbackUrl', params.callbackUrl);
    }
    
    return url.toString();
  }

  /**
   * Create QR payment URL (PromptPay)
   */
  createQRPaymentUrl(params: {
    refno: string;
    customeremail: string;
    productdetail: string;
    total: number;
    returnUrl?: string;
  }): string {
    const url = new URL(PAYSO_API_URL);
    
    url.searchParams.append('merchantid', this.merchantId);
    url.searchParams.append('refno', params.refno);
    url.searchParams.append('customeremail', params.customeremail);
    url.searchParams.append('productdetail', params.productdetail);
    url.searchParams.append('total', params.total.toFixed(2));
    url.searchParams.append('cc', 'y'); // Enable credit card too
    url.searchParams.append('lang', 'TH');
    
    if (params.returnUrl) {
      url.searchParams.append('returnUrl', params.returnUrl);
    }
    
    return url.toString();
  }

  /**
   * Inquiry order status from PaySo API
   */
  async inquiryOrder(refNo: string): Promise<PaySoPaymentResponse> {
    try {
      const response = await fetch(PAYSO_INQUIRY_URL, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'apikey': this.apiKey,
          'secretkey': this.secretKey,
        },
        body: JSON.stringify({
          merchantId: this.merchantId,
          orderNo: '',
          refNo: refNo,
          productDetail: ''
        })
      });

      if (!response.ok) {
        return {
          status: -1,
          message: `API Error: ${response.status}`
        };
      }

      return await response.json();
    } catch (error) {
      return {
        status: -1,
        message: error instanceof Error ? error.message : 'Unknown error'
      };
    }
  }

  /**
   * Refund payment
   */
  async refund(params: {
    refNo: string;
    amount: number;
    reason?: string;
  }): Promise<PaySoPaymentResponse> {
    try {
      const response = await fetch(PAYSO_REFUND_URL, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'apikey': this.apiKey,
          'secretkey': this.secretKey,
        },
        body: JSON.stringify({
          merchantId: this.merchantId,
          refNo: params.refNo,
          amount: params.amount.toFixed(2),
          reason: params.reason || 'Customer request'
        })
      });

      if (!response.ok) {
        return {
          status: -1,
          message: `API Error: ${response.status}`
        };
      }

      return await response.json();
    } catch (error) {
      return {
        status: -1,
        message: error instanceof Error ? error.message : 'Unknown error'
      };
    }
  }

  /**
   * Parse PaySo callback/return response
   */
  static parseResponse(params: URLSearchParams): {
    refNo: string;
    status: string;
    amount: number;
    approveCode?: string;
    invoiceNo?: string;
    paymentDate?: string;
  } {
    return {
      refNo: params.get('refno') || '',
      status: params.get('status') || '',
      amount: parseFloat(params.get('amt') || '0'),
      approveCode: params.get('apprvcode') || undefined,
      invoiceNo: params.get('invoiceNo') || undefined,
      paymentDate: params.get('paydt') || undefined,
    };
  }
}

/**
 * Create PaySo client from environment variables
 */
export function createPaySoClient(): PaySoClient {
  const merchantId = import.meta.env.PAYSO_MERCHANT_ID;
  const apiKey = import.meta.env.PAYSO_API_KEY;
  const secretKey = import.meta.env.PAYSO_SECRET_KEY;

  if (!merchantId || !apiKey || !secretKey) {
    console.warn('PaySo credentials not configured. Set PAYSO_MERCHANT_ID, PAYSO_API_KEY, and PAYSO_SECRET_KEY in .env');
  }

  return new PaySoClient(
    merchantId || 'demo-merchant',
    apiKey || 'demo-api-key',
    secretKey || 'demo-secret-key'
  );
}

/**
 * Generate unique reference number for PaySo
 */
export function generatePaySoRefNo(): string {
  const timestamp = Date.now().toString().slice(-10);
  const random = Math.random().toString(36).substring(2, 8).toUpperCase();
  return `PS${timestamp}${random}`;
}

// Payment status mapping
export const PAYSO_STATUS = {
  SUCCESS: '0',
  PENDING: '1',
  FAIL: '2',
  CANCEL: '3',
} as const;

export type PaySoStatus = typeof PAYSO_STATUS[keyof typeof PAYSO_STATUS];

export function isPaymentSuccess(status: string): boolean {
  return status === PAYSO_STATUS.SUCCESS;
}

export function isPaymentPending(status: string): boolean {
  return status === PAYSO_STATUS.PENDING;
}

export function isPaymentFailed(status: string): boolean {
  return [PAYSO_STATUS.FAIL, PAYSO_STATUS.CANCEL].includes(status as PaySoStatus);
}
