const express = require('express');
const router = express.Router();
const { isAuthenticated, isGuest } = require('../middleware/auth');
const { Cart, CartItem, Product, ProductImage, ProductVariant, Coupon, User } = require('../models');
const CartService = require('../services/CartService');
const OrderService = require('../services/OrderService');
const PaymentService = require('../services/PaymentService');
const appConfig = require('../config/app');

// Add to cart
router.post('/cart/add', async (req, res) => {
  try {
    const { productId, quantity, variantId } = req.body;
    const userId = req.session.user ? req.session.user.id : null;
    const sessionId = req.sessionID;

    await CartService.addItem(userId, sessionId, productId, parseInt(quantity) || 1, variantId || null);

    if (req.xhr || req.headers.accept?.includes('json')) {
      const cart = await CartService.getCart(userId, sessionId);
      const items = await CartItem.findAll({ where: { cartId: cart.id } });
      return res.json({ success: true, cartCount: items.reduce((s, i) => s + i.quantity, 0) });
    }
    req.flash('success', 'Item added to cart.');
    res.redirect('back');
  } catch (error) {
    if (req.xhr) return res.json({ success: false, message: error.message });
    req.flash('error', error.message);
    res.redirect('back');
  }
});

// Cart page
router.get('/cart', async (req, res) => {
  try {
    const userId = req.session.user ? req.session.user.id : null;
    const sessionId = req.sessionID;
    const cart = await CartService.getCart(userId, sessionId);

    const items = await CartItem.findAll({
      where: { cartId: cart.id },
      include: [
        {
          model: Product,
          include: [{ model: ProductImage, as: 'images', where: { isPrimary: true }, required: false }],
        },
        { model: ProductVariant },
      ],
    });

    let coupon = null;
    if (cart.couponId) {
      coupon = await Coupon.findByPk(cart.couponId);
    }

    const totals = CartService.calculateTotals(items, coupon);

    res.render('cart', {
      title: 'Shopping Cart',
      items,
      cart,
      coupon,
      totals,
      currencySymbol: appConfig.currencySymbol,
    });
  } catch (error) {
    console.error('Cart error:', error);
    req.flash('error', 'Error loading cart.');
    res.redirect('/');
  }
});

// Update cart item
router.post('/cart/update', async (req, res) => {
  try {
    const { itemId, quantity } = req.body;
    await CartService.updateItemQuantity(itemId, parseInt(quantity));
    if (req.xhr) return res.json({ success: true });
    res.redirect('/cart');
  } catch (error) {
    if (req.xhr) return res.json({ success: false });
    res.redirect('/cart');
  }
});

// Remove cart item
router.post('/cart/remove', async (req, res) => {
  try {
    await CartService.removeItem(req.body.itemId);
    if (req.xhr) return res.json({ success: true });
    res.redirect('/cart');
  } catch (error) {
    res.redirect('/cart');
  }
});

// Apply coupon
router.post('/cart/coupon', async (req, res) => {
  try {
    const userId = req.session.user ? req.session.user.id : null;
    const sessionId = req.sessionID;
    const coupon = await CartService.applyCoupon(userId, sessionId, req.body.code);
    req.flash('success', `Coupon "${coupon.code}" applied!`);
    res.redirect('/cart');
  } catch (error) {
    req.flash('error', error.message);
    res.redirect('/cart');
  }
});

// Remove coupon
router.post('/cart/coupon/remove', async (req, res) => {
  const userId = req.session.user ? req.session.user.id : null;
  await CartService.removeCoupon(userId, req.sessionID);
  res.redirect('/cart');
});

// Checkout
router.get('/checkout', isAuthenticated, async (req, res) => {
  try {
    const cart = await CartService.getCart(req.session.user.id, null);
    const items = await CartItem.findAll({
      where: { cartId: cart.id },
      include: [
        {
          model: Product,
          include: [{ model: ProductImage, as: 'images', where: { isPrimary: true }, required: false }],
        },
      ],
    });

    if (!items.length) {
      req.flash('warning', 'Your cart is empty.');
      return res.redirect('/cart');
    }

    let coupon = null;
    if (cart.couponId) coupon = await Coupon.findByPk(cart.couponId);
    const totals = CartService.calculateTotals(items, coupon);

    const user = await User.findByPk(req.session.user.id);

    res.render('checkout', {
      title: 'Checkout',
      items,
      totals,
      coupon,
      user,
      razorpayKeyId: appConfig.razorpayKeyId,
      currencySymbol: appConfig.currencySymbol,
    });
  } catch (error) {
    console.error('Checkout error:', error);
    req.flash('error', 'Error loading checkout.');
    res.redirect('/cart');
  }
});

// Place order (COD)
router.post('/checkout/place-order', isAuthenticated, async (req, res) => {
  try {
    const order = await OrderService.createOrder(req.session.user.id, req.body, req.body.paymentMethod);
    req.flash('success', `Order #${order.orderNumber} placed successfully!`);
    res.redirect(`/account/orders/${order.id}`);
  } catch (error) {
    console.error('Place order error:', error);
    req.flash('error', error.message || 'Error placing order.');
    res.redirect('/checkout');
  }
});

// Razorpay - Create payment order
router.post('/checkout/razorpay-order', isAuthenticated, async (req, res) => {
  try {
    const cart = await CartService.getCart(req.session.user.id, null);
    const items = await CartItem.findAll({
      where: { cartId: cart.id },
      include: [Product],
    });
    if (!items.length) return res.json({ success: false, message: 'Cart is empty.' });

    let coupon = null;
    if (cart.couponId) coupon = await Coupon.findByPk(cart.couponId);
    const totals = CartService.calculateTotals(items, coupon);

    const razorpayOrder = await PaymentService.createOrder(totals.total, 'INR', 'order_' + Date.now());

    res.json({
      success: true,
      order: razorpayOrder,
      amount: totals.total,
      keyId: appConfig.razorpayKeyId,
    });
  } catch (error) {
    res.json({ success: false, message: error.message });
  }
});

// Razorpay - Verify payment
router.post('/checkout/verify-payment', isAuthenticated, async (req, res) => {
  try {
    const { razorpay_order_id, razorpay_payment_id, razorpay_signature, shipping } = req.body;

    const isValid = PaymentService.verifyPayment(razorpay_order_id, razorpay_payment_id, razorpay_signature);
    if (!isValid) {
      return res.json({ success: false, message: 'Payment verification failed.' });
    }

    const order = await OrderService.createOrder(req.session.user.id, JSON.parse(shipping), 'razorpay');

    await order.update({
      razorpayOrderId: razorpay_order_id,
      razorpayPaymentId: razorpay_payment_id,
      paymentStatus: 'paid',
    });

    res.json({ success: true, orderId: order.id });
  } catch (error) {
    console.error('Verify payment error:', error);
    res.json({ success: false, message: error.message });
  }
});

module.exports = router;
