const express = require('express');
const router = express.Router();
const { query } = require('../utils/db');
const { requireFirebaseAuth, requireAdminAuth } = require('../middleware/auth');
const { v4: uuidv4 } = require('uuid');

const PAYCHANGU_BASE = process.env.PAYCHANGU_BASE_URL || 'https://api.paychangu.com';
const PAYCHANGU_KEY  = process.env.PAYCHANGU_SECRET_KEY;

/**
 * POST /api/payments/initiate
 * Initiate a Paychangu payment for a movie rental.
 * Body: { movieId, method ('airtel'|'tnm'|'card'), phone? }
 */
router.post('/initiate', requireFirebaseAuth, async (req, res) => {
  try {
    const { movieId, method, phone } = req.body;
    const { uid, email, name } = req.user;

    // Fetch movie
    const movieResult = await query('SELECT id, title, rental_price, is_rental FROM movies WHERE id=$1', [movieId]);
    if (!movieResult.rows.length) return res.status(404).json({ success: false, message: 'Movie not found' });

    const movie = movieResult.rows[0];
    if (!movie.is_rental) return res.status(400).json({ success: false, message: 'Movie is not a rental' });

    // Create pending payment record
    const reference = `MAST-${uuidv4().split('-')[0].toUpperCase()}`;
    await query(`
      INSERT INTO payments (reference, user_firebase_uid, movie_id, method, phone, amount, status)
      VALUES ($1, $2, $3, $4, $5, $6, 'pending')
    `, [reference, uid, movieId, method, phone || null, movie.rental_price]);

    // ── Call Paychangu API ──────────────────────────────────────
    const nameParts = (name || 'User').split(' ');
    const payload = {
      amount: movie.rental_price,
      currency: 'MWK',
      email,
      first_name: nameParts[0],
      last_name: nameParts.slice(1).join(' ') || nameParts[0],
      callback_url: `${process.env.APP_URL}/api/payments/webhook`,
      return_url: `${process.env.APP_URL}/api/payments/return?ref=${reference}`,
      tx_ref: reference,
      customization: {
        title: `Mastreams — Rent ${movie.title}`,
        description: `24-hour rental of "${movie.title}"`,
      },
    };

    // Mobile money specific fields
    if (method === 'airtel' || method === 'tnm') {
      payload.mobile_money = { phone, network: method === 'airtel' ? 'airtel' : 'tnm' };
    }

    let paychanguResponse = null;
    try {
      const fetch = (...args) => import('node-fetch').then(({default: f}) => f(...args));
      const resp = await fetch(`${PAYCHANGU_BASE}/payment`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${PAYCHANGU_KEY}`,
        },
        body: JSON.stringify(payload),
      });
      paychanguResponse = await resp.json();
    } catch (fetchErr) {
      console.warn('Paychangu API call failed (dev mode):', fetchErr.message);
      // In dev, simulate a response
      paychanguResponse = { status: 'success', data: { link: `https://paychangu.com/pay/${reference}` } };
    }

    res.json({
      success: true,
      reference,
      amount: movie.rental_price,
      currency: 'MWK',
      paymentLink: paychanguResponse?.data?.link || null,
      message: 'Payment initiated. Complete on your phone or via the payment link.',
    });
  } catch (err) {
    console.error('Payment initiate error:', err);
    res.status(500).json({ success: false, message: 'Failed to initiate payment' });
  }
});

/**
 * POST /api/payments/webhook
 * Paychangu webhook — called when payment status changes.
 * Verifies payment and activates rental.
 */
router.post('/webhook', async (req, res) => {
  try {
    const { tx_ref, status, amount, currency } = req.body;

    if (!tx_ref) return res.status(400).json({ success: false });

    const paymentResult = await query(
      'SELECT id, user_firebase_uid, movie_id, amount FROM payments WHERE reference=$1',
      [tx_ref]
    );
    if (!paymentResult.rows.length) return res.status(404).json({ success: false });

    const payment = paymentResult.rows[0];

    if (status === 'successful' || status === 'completed') {
      // Mark payment completed
      await query(
        "UPDATE payments SET status='completed', paychangu_ref=$1, updated_at=NOW() WHERE reference=$2",
        [tx_ref, tx_ref]
      );

      // Create rental (24 hours)
      const expires = new Date(Date.now() + 24 * 60 * 60 * 1000);
      await query(`
        INSERT INTO rentals (user_firebase_uid, movie_id, payment_reference, status, expires_at)
        VALUES ($1, $2, $3, 'active', $4)
        ON CONFLICT DO NOTHING
      `, [payment.user_firebase_uid, payment.movie_id, tx_ref, expires]);

    } else if (status === 'failed') {
      await query(
        "UPDATE payments SET status='failed', updated_at=NOW() WHERE reference=$1",
        [tx_ref]
      );
    }

    res.json({ success: true });
  } catch (err) {
    console.error('Webhook error:', err);
    res.status(500).json({ success: false });
  }
});

/**
 * GET /api/payments/status/:reference
 * Check payment status (Flutter polls this after initiating).
 */
router.get('/status/:reference', requireFirebaseAuth, async (req, res) => {
  try {
    const result = await query(
      'SELECT reference, status, amount, method, created_at FROM payments WHERE reference=$1 AND user_firebase_uid=$2',
      [req.params.reference, req.user.uid]
    );
    if (!result.rows.length) return res.status(404).json({ success: false, message: 'Payment not found' });
    res.json({ success: true, payment: result.rows[0] });
  } catch (err) {
    res.status(500).json({ success: false, message: 'Failed to fetch payment' });
  }
});

/**
 * GET /api/payments  (admin)
 * List all payments with filters.
 */
router.get('/', requireAdminAuth, async (req, res) => {
  try {
    const { status, method, limit = 50, offset = 0 } = req.query;
    const conditions = [];
    const params = [];
    let p = 1;

    if (status) { conditions.push(`p.status = $${p++}`); params.push(status); }
    if (method) { conditions.push(`p.method = $${p++}`); params.push(method); }

    const where = conditions.length ? `WHERE ${conditions.join(' AND ')}` : '';
    params.push(parseInt(limit), parseInt(offset));

    const result = await query(`
      SELECT p.*, u.name as user_name, u.email as user_email, m.title as movie_title
      FROM payments p
      LEFT JOIN users u ON u.firebase_uid = p.user_firebase_uid
      LEFT JOIN movies m ON m.id = p.movie_id
      ${where}
      ORDER BY p.created_at DESC
      LIMIT $${p} OFFSET $${p+1}
    `, params);

    const total = await query(`SELECT COUNT(*) FROM payments ${where}`, params.slice(0,-2));

    res.json({ success: true, payments: result.rows, total: parseInt(total.rows[0].count) });
  } catch (err) {
    res.status(500).json({ success: false, message: 'Failed to fetch payments' });
  }
});

module.exports = router;
