const express = require('express');
const db = require('../config/database');
const jwt = require('jsonwebtoken');
const Razorpay = require('razorpay');
const crypto = require('crypto');
const router = express.Router();

// Middleware to verify JWT token
const verifyToken = (req, res, next) => {
  const token = req.headers.authorization?.split(' ')[1];
  if (!token) {
    return res.status(401).json({ message: 'No token provided' });
  }
  
  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = decoded;
    next();
  } catch (error) {
    return res.status(401).json({ message: 'Invalid token' });
  }
};

const ensureRazorpayKeys = () => {
  if (!process.env.RAZORPAY_KEY_ID || !process.env.RAZORPAY_KEY_SECRET) {
    throw new Error('Razorpay keys are missing. Please set RAZORPAY_KEY_ID and RAZORPAY_KEY_SECRET');
  }
};

const getRazorpayClient = () => {
  ensureRazorpayKeys();
  return new Razorpay({
    key_id: process.env.RAZORPAY_KEY_ID,
    key_secret: process.env.RAZORPAY_KEY_SECRET
  });
};

// Create Razorpay order
router.post('/razorpay/create-order', verifyToken, async (req, res) => {
  try {
    const { amount, plan_id, device_id, subscription_id } = req.body;

    if (!amount || !plan_id) {
      return res.status(400).json({ message: 'amount and plan_id are required' });
    }

    const razorpayClient = getRazorpayClient();

    const order = await razorpayClient.orders.create({
      amount: Math.round(amount * 100),
      currency: 'INR',
      receipt: `order_${Date.now()}`,
      notes: {
        plan_id,
        device_id: device_id || '',
        subscription_id: subscription_id || ''
      }
    });

    await db.execute(
      `INSERT INTO payment_transactions (transaction_id, user_id, amount, status, gateway_transaction_id, metadata)
       VALUES (?, ?, ?, 'pending', ?, ?)` ,
      [order.receipt, req.user.id, amount, order.id, JSON.stringify({ plan_id, device_id, subscription_id })]
    );

    res.json({ order_id: order.id, amount, currency: order.currency });
  } catch (error) {
    console.error('Razorpay order error:', error);
    res.status(500).json({ message: 'Failed to create order', error: error.message });
  }
});

// Verify Razorpay payment
router.post('/razorpay/verify', verifyToken, async (req, res) => {
  try {
    const {
      razorpay_order_id,
      razorpay_payment_id,
      razorpay_signature,
      subscription_id,
      invoice_id,
      transaction_id
    } = req.body;

    if (!razorpay_order_id || !razorpay_payment_id || !razorpay_signature) {
      return res.status(400).json({ message: 'razorpay_order_id, razorpay_payment_id and razorpay_signature are required' });
    }

    const { RAZORPAY_KEY_SECRET } = process.env;
    const razorpayClient = getRazorpayClient();

    const expectedSignature = crypto
      .createHmac('sha256', RAZORPAY_KEY_SECRET)
      .update(`${razorpay_order_id}|${razorpay_payment_id}`)
      .digest('hex');

    if (expectedSignature !== razorpay_signature) {
      return res.status(400).json({ message: 'Invalid signature' });
    }

    await db.execute(
      `UPDATE payment_transactions
       SET status = 'completed', gateway_transaction_id = ?, gateway_response = ?, processed_at = NOW()
       WHERE (transaction_id = ? OR gateway_transaction_id = ?) AND user_id = ?`,
      [razorpay_payment_id, JSON.stringify(req.body), transaction_id, razorpay_order_id, req.user.id]
    );

    if (invoice_id) {
      await db.execute('UPDATE invoices SET status = "paid" WHERE id = ?', [invoice_id]);
    }

    if (subscription_id) {
      await db.execute('UPDATE device_subscriptions SET status = "active", updated_at = NOW() WHERE id = ?', [subscription_id]);
    }

    res.json({ success: true, message: 'Payment verified successfully' });
  } catch (error) {
    console.error('Razorpay verify error:', error);
    res.status(500).json({ message: 'Failed to verify payment', error: error.message });
  }
});

// Get user's invoices
router.get('/invoices', verifyToken, async (req, res) => {
  try {
    const [rows] = await db.execute(`
      SELECT i.*, ds.device_id, sp.name as plan_name
      FROM invoices i
      LEFT JOIN device_subscriptions ds ON i.subscription_id = ds.id
      LEFT JOIN subscription_plans sp ON ds.plan_id = sp.id
      WHERE i.user_id = ?
      ORDER BY i.created_at DESC
    `, [req.user.id]);
    
    res.json(rows);
  } catch (error) {
    res.status(500).json({ message: 'Server error: ' + error.message });
  }
});

// Get user's payment methods
router.get('/payment-methods', verifyToken, async (req, res) => {
  try {
    const [rows] = await db.execute(`
      SELECT id, type, provider, last_four, expiry_month, expiry_year, is_default, status
      FROM payment_methods 
      WHERE user_id = ? AND status = 'active'
      ORDER BY is_default DESC, created_at DESC
    `, [req.user.id]);
    
    res.json(rows);
  } catch (error) {
    res.status(500).json({ message: 'Server error: ' + error.message });
  }
});

// Add payment method
router.post('/payment-methods', verifyToken, async (req, res) => {
  try {
    const { type, provider, last_four, expiry_month, expiry_year, is_default } = req.body;
    
    // If this is set as default, unset others
    if (is_default) {
      await db.execute(
        'UPDATE payment_methods SET is_default = FALSE WHERE user_id = ?',
        [req.user.id]
      );
    }
    
    const [result] = await db.execute(`
      INSERT INTO payment_methods (user_id, type, provider, last_four, expiry_month, expiry_year, is_default)
      VALUES (?, ?, ?, ?, ?, ?, ?)
    `, [req.user.id, type, provider, last_four, expiry_month, expiry_year, is_default]);
    
    res.json({ 
      message: 'Payment method added successfully',
      payment_method_id: result.insertId
    });
  } catch (error) {
    res.status(500).json({ message: 'Server error: ' + error.message });
  }
});

// Get payment transactions
router.get('/transactions', verifyToken, async (req, res) => {
  try {
    const [rows] = await db.execute(`
      SELECT pt.*, i.invoice_number, pm.type as payment_type, pm.last_four
      FROM payment_transactions pt
      JOIN invoices i ON pt.invoice_id = i.id
      LEFT JOIN payment_methods pm ON pt.payment_method_id = pm.id
      WHERE pt.user_id = ?
      ORDER BY pt.created_at DESC
    `, [req.user.id]);
    
    res.json(rows);
  } catch (error) {
    res.status(500).json({ message: 'Server error: ' + error.message });
  }
});

// Create payment transaction
router.post('/create-transaction', verifyToken, async (req, res) => {
  try {
    const { invoice_id, payment_method_id, amount } = req.body;
    
    // Generate transaction ID
    const transactionId = 'TXN-' + Date.now() + '-' + Math.random().toString(36).substr(2, 9);
    
    const [result] = await db.execute(`
      INSERT INTO payment_transactions (transaction_id, invoice_id, user_id, payment_method_id, amount, status)
      VALUES (?, ?, ?, ?, ?, 'pending')
    `, [transactionId, invoice_id, req.user.id, payment_method_id, amount]);
    
    res.json({ 
      message: 'Transaction created successfully',
      transaction_id: transactionId,
      payment_transaction_id: result.insertId
    });
  } catch (error) {
    res.status(500).json({ message: 'Server error: ' + error.message });
  }
});

// Update payment status (webhook endpoint)
router.put('/update-status/:transactionId', async (req, res) => {
  try {
    const { transactionId } = req.params;
    const { status, gateway_transaction_id, gateway_response } = req.body;
    
    // Update transaction status
    await db.execute(`
      UPDATE payment_transactions 
      SET status = ?, gateway_transaction_id = ?, gateway_response = ?, processed_at = NOW()
      WHERE transaction_id = ?
    `, [status, gateway_transaction_id, JSON.stringify(gateway_response), transactionId]);
    
    // If payment completed, update invoice status
    if (status === 'completed') {
      const [txnRows] = await db.execute(
        'SELECT invoice_id FROM payment_transactions WHERE transaction_id = ?',
        [transactionId]
      );
      
      if (txnRows.length > 0) {
        await db.execute(
          'UPDATE invoices SET status = "paid" WHERE id = ?',
          [txnRows[0].invoice_id]
        );
      }
    }
    
    res.json({ message: 'Payment status updated successfully' });
  } catch (error) {
    res.status(500).json({ message: 'Server error: ' + error.message });
  }
});

// Generate invoice for subscription
router.post('/generate-invoice', verifyToken, async (req, res) => {
  try {
    const { subscription_id } = req.body;
    
    // Get subscription details
    const [subRows] = await db.execute(`
      SELECT ds.*, sp.name, sp.price 
      FROM device_subscriptions ds
      JOIN subscription_plans sp ON ds.plan_id = sp.id
      WHERE ds.id = ? AND ds.user_id = ?
    `, [subscription_id, req.user.id]);
    
    if (subRows.length === 0) {
      return res.status(404).json({ message: 'Subscription not found' });
    }
    
    const subscription = subRows[0];
    const invoiceNumber = 'INV-' + Date.now();
    const amount = subscription.price;
    const taxAmount = amount * 0.18; // 18% GST
    const totalAmount = amount + taxAmount;
    const dueDate = new Date();
    dueDate.setDate(dueDate.getDate() + 15); // 15 days to pay
    
    const [result] = await db.execute(`
      INSERT INTO invoices (invoice_number, user_id, subscription_id, amount, tax_amount, total_amount, due_date, invoice_date, description)
      VALUES (?, ?, ?, ?, ?, ?, ?, CURDATE(), ?)
    `, [invoiceNumber, req.user.id, subscription_id, amount, taxAmount, totalAmount, dueDate.toISOString().split('T')[0], `${subscription.name} - ${subscription.device_id}`]);
    
    res.json({ 
      message: 'Invoice generated successfully',
      invoice_id: result.insertId,
      invoice_number: invoiceNumber,
      total_amount: totalAmount
    });
  } catch (error) {
    res.status(500).json({ message: 'Server error: ' + error.message });
  }
});

module.exports = router;