/**
 * Payment Gateway Configuration Routes
 * Super Admin only — manages Stripe/Razorpay keys and settings.
 * The /publishable-key endpoint is accessible to all authenticated users.
 */

import express, { Request, Response } from 'express';
import { authenticate, requireRole } from '../middleware/auth';
import { getModels } from '../models';
import { getPublishableKeys } from '../services/payments/paymentService';
import { testStripeConnection, testRazorpayConnection } from '../services/payments/gatewayTestUtils';

const router = express.Router();

// Helper: mask sensitive values
function maskValue(value: string | undefined): string {
  if (!value || value.length <= 8) return value ? '••••••••' : '';
  return value.substring(0, 4) + '••••••••' + value.substring(value.length - 4);
}

// GET /publishable-key — Get public keys for frontend (all authenticated users)
router.get('/publishable-key', authenticate, async (req: Request, res: Response) => {
  try {
    const keys = await getPublishableKeys();
    res.json(keys);
  } catch (error) {
    console.error('Error fetching publishable keys:', error);
    res.status(500).json({ error: 'Failed to fetch publishable keys' });
  }
});

// All other routes require super-admin
router.use(authenticate, requireRole('super-admin'));

// GET / — Get current gateway config (keys masked)
router.get('/', async (req: Request, res: Response) => {
  try {
    const { PaymentGatewayConfig } = getModels();
    let config = await PaymentGatewayConfig.findOne({});
    if (!config) {
      // Create default config if none exists
      config = await PaymentGatewayConfig.create({});
    }
    // Mask sensitive keys before sending
    const masked = {
      ...config.toObject(),
      stripe: {
        ...config.stripe.toObject(),
        publishableKey: config.stripe.publishableKey ? maskValue(config.stripe.publishableKey) : '',
        secretKey: config.stripe.secretKey ? maskValue(config.stripe.secretKey) : '',
        webhookSecret: config.stripe.webhookSecret ? maskValue(config.stripe.webhookSecret) : '',
        mode: config.stripe.mode,
      },
      razorpay: {
        ...config.razorpay.toObject(),
        keyId: config.razorpay.keyId || '',
        keySecret: config.razorpay.keySecret ? maskValue(config.razorpay.keySecret) : '',
        webhookSecret: config.razorpay.webhookSecret ? maskValue(config.razorpay.webhookSecret) : '',
        mode: config.razorpay.mode,
      },
    };
    res.json(masked);
  } catch (error) {
    console.error('Error fetching gateway config:', error);
    res.status(500).json({ error: 'Failed to fetch gateway configuration' });
  }
});

// PUT / — Update gateway config
router.put('/', async (req: Request, res: Response) => {
  try {
    const { PaymentGatewayConfig } = getModels();
    let config = await PaymentGatewayConfig.findOne({});

    if (!config) {
      config = await PaymentGatewayConfig.create({});
    }

    const { stripe, razorpay } = req.body;

    if (stripe) {
      // Only update keys that are not masked (i.e., actually changed)
      if (stripe.publishableKey && !stripe.publishableKey.includes('••')) {
        config.stripe.publishableKey = stripe.publishableKey;
      }
      if (stripe.secretKey && !stripe.secretKey.includes('••')) {
        config.stripe.secretKey = stripe.secretKey;
      }
      if (stripe.webhookSecret && !stripe.webhookSecret.includes('••')) {
        config.stripe.webhookSecret = stripe.webhookSecret;
      }
      if (stripe.mode) {
        config.stripe.mode = stripe.mode;
      }
    }

    if (razorpay) {
      if (razorpay.keyId) {
        config.razorpay.keyId = razorpay.keyId;
      }
      if (razorpay.keySecret && !razorpay.keySecret.includes('••')) {
        config.razorpay.keySecret = razorpay.keySecret;
      }
      if (razorpay.webhookSecret && !razorpay.webhookSecret.includes('••')) {
        config.razorpay.webhookSecret = razorpay.webhookSecret;
      }
      if (razorpay.mode) {
        config.razorpay.mode = razorpay.mode;
      }
    }

    await config.save();
    res.json({ message: 'Gateway configuration updated successfully' });
  } catch (error) {
    console.error('Error updating gateway config:', error);
    res.status(500).json({ error: 'Failed to update gateway configuration' });
  }
});

// POST /test/stripe — Test Stripe connection with real API call
router.post('/test/stripe', async (req: Request, res: Response) => {
  try {
    const result = await testStripeConnection();
    res.json(result);
  } catch (error) {
    console.error('Error testing Stripe:', error);
    res.status(500).json({ success: false, message: 'Failed to test Stripe connection' });
  }
});

// POST /test/razorpay — Test Razorpay connection with real API call
router.post('/test/razorpay', async (req: Request, res: Response) => {
  try {
    const result = await testRazorpayConnection();
    res.json(result);
  } catch (error) {
    console.error('Error testing Razorpay:', error);
    res.status(500).json({ success: false, message: 'Failed to test Razorpay connection' });
  }
});

export default router;