/**
 * Crownline Global — Node.js (Express) Integration Example
 *
 * This is a minimal working example showing how to:
 *   1. Create a payment
 *   2. Check a payment's status
 *   3. Receive and verify webhook notifications
 *
 * Install dependencies first:
 *   npm install express node-fetch
 *
 * Run:
 *   CROWNLINE_API_KEY=your_api_key node server.js
 */

const express = require('express');
const crypto = require('crypto');
const fetch = require('node-fetch');

const app = express();
app.use(express.json());

const API_BASE_URL = 'https://api.crownlineglobal.co.uk';
const API_KEY = process.env.CROWNLINE_API_KEY;

// ---------------------------------------------------------------------
// 1. Create a payment (call this when your customer clicks "Pay")
// ---------------------------------------------------------------------
async function createPayment(orderId, amount, customer) {
  const response = await fetch(`${API_BASE_URL}/api/payments/create`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      merchantOrderId: orderId,
      amount: amount,
      countryCode: 'IDN',
      currency: 'Rp',
      language: 'ID',
      paymentMethodCode: 'BNIVA',
      notificationUrl: 'https://yourshop.com/webhooks/payment',
      customerName: customer.name,
      customerEmail: customer.email,
      customerPhone: customer.phone,
      productName: `Order #${orderId}`,
    }),
  });

  const data = await response.json();
  if (data.code !== 'SUCCESS') {
    throw new Error(`Payment creation failed: ${data.error || data.message}`);
  }
  return data;
}

// Example usage in a checkout route:
app.post('/checkout', async (req, res) => {
  try {
    const payment = await createPayment('ORDER-1001', 150000, {
      name: 'Jane Doe',
      email: 'jane@example.com',
      phone: '081234567890',
    });
    // Show payment.paymentInfo.content to your customer
    res.json(payment);
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

// ---------------------------------------------------------------------
// 2. Check payment status (poll this if you haven't received a webhook yet)
// ---------------------------------------------------------------------
async function checkPaymentStatus(orderId) {
  const response = await fetch(
    `${API_BASE_URL}/api/payments/status?merchantOrderId=${orderId}`,
    { headers: { 'Authorization': `Bearer ${API_KEY}` } }
  );
  return response.json();
}

app.get('/orders/:orderId/status', async (req, res) => {
  const status = await checkPaymentStatus(req.params.orderId);
  res.json(status);
});

// ---------------------------------------------------------------------
// 3. Receive and verify webhook notifications
// ---------------------------------------------------------------------

// IMPORTANT: we need the RAW request body to verify the signature,
// so we use express.raw() for this specific route instead of express.json().
app.post(
  '/webhooks/payment',
  express.raw({ type: 'application/json' }),
  (req, res) => {
    const signature = req.headers['x-payfac-signature'];
    const rawBody = req.body; // Buffer

    const expectedSignature = crypto
      .createHmac('sha256', API_KEY)
      .update(rawBody)
      .digest('hex');

    if (signature !== expectedSignature) {
      console.warn('Webhook signature mismatch — rejecting');
      return res.status(401).send('invalid signature');
    }

    const notification = JSON.parse(rawBody.toString());
    console.log('Payment update received:', notification);

    // notification.status will be "SUCCESS", "PENDING", or "FAILED"
    // notification.paidAmount is the ACTUAL amount paid — use this,
    // not notification.amount, to confirm the order was paid in full.
    if (notification.status === 'SUCCESS') {
      // TODO: mark the order as paid in your own database
    }

    res.sendStatus(200);
  }
);

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Listening on port ${PORT}`));