import { Router } from 'express';
import Stripe from 'stripe';
import { prisma } from '../config/database.js';
import { authenticate } from '../middleware/auth.js';
import { env } from '../config/env.js';
import { AppError } from '../middleware/errorHandler.js';
import { getPlatformConfig } from '../utils/moderation.js';

const router = Router();

const stripe = env.STRIPE_SECRET_KEY ? new Stripe(env.STRIPE_SECRET_KEY) : null;

// --- Stripe config (no auth required) ---
router.get('/config', (_req, res) => {
  res.json({ publishableKey: env.STRIPE_PUBLISHABLE_KEY || null });
});

// --- Payment history ---
router.get('/history', authenticate, async (req, res, next) => {
  try {
    const payments = await prisma.payment.findMany({
      where: { userId: req.userId },
      include: {
        listing: { select: { id: true, title: true, images: { take: 1, orderBy: { order: 'asc' } } } },
      },
      orderBy: { createdAt: 'desc' },
    });
    res.json(payments);
  } catch (error) {
    next(error);
  }
});

// --- Payment status ---
router.get('/:id/status', authenticate, async (req, res, next) => {
  try {
    const payment = await prisma.payment.findUnique({
      where: { id: req.params.id },
      include: {
        listing: { select: { id: true, title: true } },
      },
    });
    if (!payment) throw new AppError(404, 'Payment not found');
    if (payment.userId !== req.userId) throw new AppError(403, 'Not authorized');

    res.json(payment);
  } catch (error) {
    next(error);
  }
});

// --- Create payment intent ---
router.post('/create-intent', authenticate, async (req, res, next) => {
  try {
    const { listingId } = req.body;
    if (!stripe) throw new AppError(500, 'Stripe not configured');

    const listing = await prisma.listing.findUnique({ where: { id: listingId } });
    if (!listing) throw new AppError(404, 'Listing not found');
    if (listing.sellerId !== req.userId) throw new AppError(403, 'Not authorized');

    const existingPayment = await prisma.payment.findFirst({
      where: { listingId, status: 'COMPLETED' },
    });
    if (existingPayment) throw new AppError(400, 'Listing already paid for');

    const config = await getPlatformConfig();
    const feeInCents = Math.round(config.listingFee * 100);

    const paymentIntent = await stripe.paymentIntents.create({
      amount: feeInCents,
      currency: 'usd',
      metadata: { listingId, userId: req.userId! },
    });

    await prisma.payment.create({
      data: {
        userId: req.userId!,
        listingId,
        stripePaymentId: paymentIntent.id,
        amount: config.listingFee,
        status: 'PENDING',
        type: 'LISTING_FEE',
      },
    });

    res.json({ clientSecret: paymentIntent.client_secret });
  } catch (error) {
    next(error);
  }
});

// --- Stripe webhook ---
router.post('/webhook', async (req, res, next) => {
  try {
    if (!stripe) throw new AppError(500, 'Stripe not configured');

    const sig = req.headers['stripe-signature'] as string;
    const event = stripe.webhooks.constructEvent(req.body, sig, env.STRIPE_WEBHOOK_SECRET);

    if (event.type === 'payment_intent.succeeded') {
      const paymentIntent = event.data.object;
      const { listingId } = paymentIntent.metadata;

      await prisma.payment.updateMany({
        where: { stripePaymentId: paymentIntent.id },
        data: { status: 'COMPLETED' },
      });

      if (listingId) {
        await prisma.listing.update({
          where: { id: listingId },
          data: { status: 'ACTIVE' },
        });
      }
    } else if (event.type === 'payment_intent.payment_failed') {
      const paymentIntent = event.data.object;

      await prisma.payment.updateMany({
        where: { stripePaymentId: paymentIntent.id },
        data: { status: 'FAILED' },
      });
    }

    res.json({ received: true });
  } catch (error) {
    next(error);
  }
});

export default router;
