const express = require('express');
const router = express.Router();
const { isAuthenticated, isAdmin } = require('../middleware/auth');
const { User, Order, OrderItem, Product, Category, ProductImage, Review, Coupon, Page, Banner, Setting } = require('../models');
const { Op } = require('sequelize');
const ReportService = require('../services/ReportService');
const OrderService = require('../services/OrderService');
const InvoiceService = require('../services/InvoiceService');
const createUploader = require('../middleware/upload');
const bcrypt = require('bcryptjs');

// All admin routes require admin auth
router.use(isAuthenticated, isAdmin);

// Set admin layout
router.use((req, res, next) => {
  res.locals.layout = 'layouts/admin';
  next();
});

// ===================== DASHBOARD =====================
router.get('/', async (req, res) => {
  try {
    const stats = await ReportService.getDashboardStats();
    const salesChart = await ReportService.getSalesChartData(30);
    const topProducts = await ReportService.getTopProducts(5);
    const recentOrders = await ReportService.getRecentOrders(10);
    const lowStock = await ReportService.getLowStockProducts(5);

    res.render('admin/dashboard', {
      title: 'Admin Dashboard',
      stats,
      salesChart: JSON.stringify(salesChart),
      topProducts,
      recentOrders,
      lowStock,
    });
  } catch (error) {
    console.error('Admin dashboard error:', error);
    req.flash('error', 'Error loading dashboard.');
    res.redirect('/');
  }
});

// ===================== PRODUCTS =====================
router.get('/products', async (req, res) => {
  try {
    const { page = 1, search, category, status } = req.query;
    const limit = 15;
    const offset = (parseInt(page) - 1) * limit;
    const where = {};
    if (search) where.name = { [Op.like]: `%${search}%` };
    if (category) where.categoryId = category;
    if (status === 'active') where.isActive = true;
    if (status === 'inactive') where.isActive = false;

    const { count, rows: products } = await Product.findAndCountAll({
      where,
      include: [{ model: Category }, { model: ProductImage, as: 'images', where: { isPrimary: true }, required: false }],
      order: [['createdAt', 'DESC']],
      limit,
      offset,
    });
    const categories = await Category.findAll({ order: [['name', 'ASC']] });
    res.render('admin/products/index', {
      title: 'Manage Products',
      products,
      categories,
      currentPage: parseInt(page),
      totalPages: Math.ceil(count / limit),
      total: count,
      search,
      status,
    });
  } catch (error) {
    console.error(error);
    req.flash('error', 'Error loading products.');
    res.redirect('/admin');
  }
});

router.get('/products/create', async (req, res) => {
  const categories = await Category.findAll({ where: { isActive: true }, order: [['name', 'ASC']] });
  res.render('admin/products/form', { title: 'Add Product', product: null, categories });
});

router.post('/products/create', createUploader('products').array('images', 5), async (req, res) => {
  try {
    const { name, description, shortDescription, price, comparePrice, costPrice, sku, stockQuantity, categoryId, isFeatured, metaTitle, metaDescription } = req.body;
    const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '') + '-' + Date.now();

    const product = await Product.create({
      name, slug, description, shortDescription,
      price, comparePrice, costPrice, sku, stockQuantity: stockQuantity || 0,
      categoryId: categoryId || null,
      isFeatured: isFeatured === 'on',
      isActive: true,
      metaTitle, metaDescription,
    });

    if (req.files && req.files.length) {
      for (let i = 0; i < req.files.length; i++) {
        await ProductImage.create({
          productId: product.id,
          imagePath: '/uploads/products/' + req.files[i].filename,
          isPrimary: i === 0,
          sortOrder: i,
        });
      }
    }

    req.flash('success', 'Product created successfully.');
    res.redirect('/admin/products');
  } catch (error) {
    console.error(error);
    req.flash('error', 'Error creating product: ' + (error.errors?.[0]?.message || error.message));
    res.redirect('/admin/products/create');
  }
});

router.get('/products/:id/edit', async (req, res) => {
  try {
    const product = await Product.findByPk(req.params.id, {
      include: [{ model: ProductImage, as: 'images', order: [['sortOrder', 'ASC']] }],
    });
    if (!product) { req.flash('error', 'Product not found.'); return res.redirect('/admin/products'); }
    const categories = await Category.findAll({ where: { isActive: true }, order: [['name', 'ASC']] });
    res.render('admin/products/form', { title: 'Edit Product', product, categories });
  } catch (error) {
    req.flash('error', 'Error loading product.');
    res.redirect('/admin/products');
  }
});

router.post('/products/:id/edit', createUploader('products').array('images', 5), async (req, res) => {
  try {
    const product = await Product.findByPk(req.params.id);
    if (!product) { req.flash('error', 'Product not found.'); return res.redirect('/admin/products'); }

    const { name, description, shortDescription, price, comparePrice, costPrice, sku, stockQuantity, categoryId, isFeatured, isActive, metaTitle, metaDescription } = req.body;
    const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '') + '-' + product.id;

    await product.update({
      name, slug, description, shortDescription, price, comparePrice, costPrice, sku,
      stockQuantity: stockQuantity || 0, categoryId: categoryId || null,
      isFeatured: isFeatured === 'on', isActive: isActive === 'on',
      metaTitle, metaDescription,
    });

    if (req.files && req.files.length) {
      for (let i = 0; i < req.files.length; i++) {
        await ProductImage.create({
          productId: product.id,
          imagePath: '/uploads/products/' + req.files[i].filename,
          isPrimary: i === 0 && !(await ProductImage.count({ where: { productId: product.id } })),
          sortOrder: i,
        });
      }
    }

    req.flash('success', 'Product updated successfully.');
    res.redirect('/admin/products');
  } catch (error) {
    req.flash('error', 'Error updating product.');
    res.redirect(`/admin/products/${req.params.id}/edit`);
  }
});

router.post('/products/:id/delete-image', async (req, res) => {
  try {
    await ProductImage.destroy({ where: { id: req.body.imageId } });
    res.json({ success: true });
  } catch (error) {
    res.json({ success: false });
  }
});

// ===================== CATEGORIES =====================
router.get('/categories', async (req, res) => {
  try {
    const categories = await Category.findAll({
      include: [{ model: Category, as: 'parent' }, { model: Product }],
      order: [['sortOrder', 'ASC']],
    });
    res.render('admin/categories/index', { title: 'Manage Categories', categories });
  } catch (error) {
    req.flash('error', 'Error loading categories.');
    res.redirect('/admin');
  }
});

router.post('/categories/create', createUploader('categories').single('image'), async (req, res) => {
  try {
    const { name, description, parentId, sortOrder } = req.body;
    const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');
    const image = req.file ? '/uploads/categories/' + req.file.filename : null;
    await Category.create({ name, slug, description, parentId: parentId || null, sortOrder: sortOrder || 0, image });
    req.flash('success', 'Category created.');
    res.redirect('/admin/categories');
  } catch (error) {
    req.flash('error', 'Error creating category.');
    res.redirect('/admin/categories');
  }
});

router.post('/categories/:id/edit', createUploader('categories').single('image'), async (req, res) => {
  try {
    const category = await Category.findByPk(req.params.id);
    if (!category) { req.flash('error', 'Category not found.'); return res.redirect('/admin/categories'); }
    const { name, description, parentId, sortOrder, isActive } = req.body;
    const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');
    const updates = { name, slug, description, parentId: parentId || null, sortOrder: sortOrder || 0, isActive: isActive === 'on' };
    if (req.file) updates.image = '/uploads/categories/' + req.file.filename;
    await category.update(updates);
    req.flash('success', 'Category updated.');
    res.redirect('/admin/categories');
  } catch (error) {
    req.flash('error', 'Error updating category.');
    res.redirect('/admin/categories');
  }
});

router.post('/categories/:id/delete', async (req, res) => {
  try {
    await Category.destroy({ where: { id: req.params.id } });
    req.flash('success', 'Category deleted.');
    res.redirect('/admin/categories');
  } catch (error) {
    req.flash('error', 'Cannot delete category with products.');
    res.redirect('/admin/categories');
  }
});

// ===================== ORDERS =====================
router.get('/orders', async (req, res) => {
  try {
    const { page = 1, status } = req.query;
    const data = await OrderService.getAllOrders(parseInt(page), 20, { status });
    res.render('admin/orders/index', { title: 'Manage Orders', ...data, status });
  } catch (error) {
    req.flash('error', 'Error loading orders.');
    res.redirect('/admin');
  }
});

router.get('/orders/:id', async (req, res) => {
  try {
    const order = await Order.findByPk(req.params.id, {
      include: [{ model: OrderItem, as: 'items' }],
    });
    if (!order) { req.flash('error', 'Order not found.'); return res.redirect('/admin/orders'); }
    res.render('admin/orders/detail', { title: `Order #${order.orderNumber}`, order });
  } catch (error) {
    req.flash('error', 'Error loading order.');
    res.redirect('/admin/orders');
  }
});

router.post('/orders/:id/status', async (req, res) => {
  try {
    await OrderService.updateOrderStatus(req.params.id, req.body.status);
    req.flash('success', 'Order status updated.');
    res.redirect(`/admin/orders/${req.params.id}`);
  } catch (error) {
    req.flash('error', 'Error updating order status.');
    res.redirect(`/admin/orders/${req.params.id}`);
  }
});

router.get('/orders/:id/invoice', async (req, res) => {
  try {
    const order = await Order.findByPk(req.params.id);
    const items = await OrderItem.findAll({ where: { orderId: order.id } });
    const pdf = await InvoiceService.generateInvoice(order, items);
    res.setHeader('Content-Type', 'application/pdf');
    res.setHeader('Content-Disposition', `attachment; filename=invoice-${order.orderNumber}.pdf`);
    res.send(pdf);
  } catch (error) {
    req.flash('error', 'Error generating invoice.');
    res.redirect('/admin/orders');
  }
});

// ===================== USERS =====================
router.get('/users', async (req, res) => {
  try {
    const { page = 1, search } = req.query;
    const limit = 20;
    const offset = (parseInt(page) - 1) * limit;
    const where = {};
    if (search) where.name = { [Op.like]: `%${search}%` };

    const { count, rows: users } = await User.findAndCountAll({
      where,
      order: [['createdAt', 'DESC']],
      limit, offset,
    });

    res.render('admin/users/index', {
      title: 'Manage Users',
      users,
      currentPage: parseInt(page),
      totalPages: Math.ceil(count / limit),
      total: count,
      search,
    });
  } catch (error) {
    req.flash('error', 'Error loading users.');
    res.redirect('/admin');
  }
});

router.post('/users/:id/toggle-admin', async (req, res) => {
  try {
    const user = await User.findByPk(req.params.id);
    if (user) {
      await user.update({ isAdmin: !user.isAdmin });
      req.flash('success', 'User role updated.');
    }
    res.redirect('/admin/users');
  } catch (error) {
    req.flash('error', 'Error updating user.');
    res.redirect('/admin/users');
  }
});

router.post('/users/:id/toggle-active', async (req, res) => {
  try {
    const user = await User.findByPk(req.params.id);
    if (user) {
      await user.update({ isActive: !user.isActive });
      req.flash('success', 'User status updated.');
    }
    res.redirect('/admin/users');
  } catch (error) {
    req.flash('error', 'Error updating user.');
    res.redirect('/admin/users');
  }
});

// ===================== REVIEWS =====================
router.get('/reviews', async (req, res) => {
  try {
    const { status } = req.query;
    const where = {};
    if (status === 'pending') where.isApproved = false;
    if (status === 'approved') where.isApproved = true;

    const reviews = await Review.findAll({
      where,
      include: [{ model: Product, attributes: ['id', 'name'] }, { model: User, attributes: ['id', 'name'] }],
      order: [['createdAt', 'DESC']],
    });
    res.render('admin/reviews/index', { title: 'Manage Reviews', reviews, status });
  } catch (error) {
    req.flash('error', 'Error loading reviews.');
    res.redirect('/admin');
  }
});

router.post('/reviews/:id/approve', async (req, res) => {
  try {
    await Review.update({ isApproved: true }, { where: { id: req.params.id } });
    res.json({ success: true });
  } catch (error) {
    res.json({ success: false });
  }
});

router.post('/reviews/:id/delete', async (req, res) => {
  try {
    await Review.destroy({ where: { id: req.params.id } });
    req.flash('success', 'Review deleted.');
    res.redirect('/admin/reviews');
  } catch (error) {
    req.flash('error', 'Error deleting review.');
    res.redirect('/admin/reviews');
  }
});

// ===================== COUPONS =====================
router.get('/coupons', async (req, res) => {
  try {
    const coupons = await Coupon.findAll({ order: [['createdAt', 'DESC']] });
    res.render('admin/coupons/index', { title: 'Manage Coupons', coupons });
  } catch (error) {
    req.flash('error', 'Error loading coupons.');
    res.redirect('/admin');
  }
});

router.post('/coupons/create', async (req, res) => {
  try {
    const { code, type, value, minOrderAmount, maxDiscountAmount, maxUses, expiresAt, isActive, description } = req.body;
    await Coupon.create({
      code: code.toUpperCase(),
      type, value, minOrderAmount: minOrderAmount || null,
      maxDiscountAmount: maxDiscountAmount || null,
      maxUses: maxUses || null, expiresAt: expiresAt || null,
      isActive: isActive === 'on', description,
    });
    req.flash('success', 'Coupon created.');
    res.redirect('/admin/coupons');
  } catch (error) {
    req.flash('error', 'Error creating coupon.');
    res.redirect('/admin/coupons');
  }
});

router.post('/coupons/:id/toggle', async (req, res) => {
  try {
    const coupon = await Coupon.findByPk(req.params.id);
    if (coupon) await coupon.update({ isActive: !coupon.isActive });
    res.json({ success: true });
  } catch (error) {
    res.json({ success: false });
  }
});

router.post('/coupons/:id/delete', async (req, res) => {
  try {
    await Coupon.destroy({ where: { id: req.params.id } });
    req.flash('success', 'Coupon deleted.');
    res.redirect('/admin/coupons');
  } catch (error) {
    req.flash('error', 'Error deleting coupon.');
    res.redirect('/admin/coupons');
  }
});

// ===================== PAGES =====================
router.get('/pages', async (req, res) => {
  try {
    const pages = await Page.findAll({ order: [['sortOrder', 'ASC']] });
    res.render('admin/pages/index', { title: 'Manage Pages', pages });
  } catch (error) {
    req.flash('error', 'Error loading pages.');
    res.redirect('/admin');
  }
});

router.get('/pages/create', (req, res) => {
  res.render('admin/pages/form', { title: 'Create Page', page: null });
});

router.post('/pages/create', async (req, res) => {
  try {
    const { title, content, metaTitle, metaDescription, isPublished, sortOrder } = req.body;
    const slug = title.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');
    await Page.create({ title, slug, content, metaTitle, metaDescription, isPublished: isPublished === 'on', sortOrder: sortOrder || 0 });
    req.flash('success', 'Page created.');
    res.redirect('/admin/pages');
  } catch (error) {
    req.flash('error', 'Error creating page.');
    res.redirect('/admin/pages/create');
  }
});

router.get('/pages/:id/edit', async (req, res) => {
  try {
    const page = await Page.findByPk(req.params.id);
    if (!page) { req.flash('error', 'Page not found.'); return res.redirect('/admin/pages'); }
    res.render('admin/pages/form', { title: 'Edit Page', page });
  } catch (error) {
    req.flash('error', 'Error loading page.');
    res.redirect('/admin/pages');
  }
});

router.post('/pages/:id/edit', async (req, res) => {
  try {
    const page = await Page.findByPk(req.params.id);
    if (!page) { req.flash('error', 'Page not found.'); return res.redirect('/admin/pages'); }
    const { title, content, metaTitle, metaDescription, isPublished, sortOrder } = req.body;
    const slug = title.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');
    await page.update({ title, slug, content, metaTitle, metaDescription, isPublished: isPublished === 'on', sortOrder: sortOrder || 0 });
    req.flash('success', 'Page updated.');
    res.redirect('/admin/pages');
  } catch (error) {
    req.flash('error', 'Error updating page.');
    res.redirect('/admin/pages');
  }
});

router.post('/pages/:id/delete', async (req, res) => {
  try {
    await Page.destroy({ where: { id: req.params.id } });
    req.flash('success', 'Page deleted.');
    res.redirect('/admin/pages');
  } catch (error) {
    req.flash('error', 'Error deleting page.');
    res.redirect('/admin/pages');
  }
});

// ===================== BANNERS =====================
router.get('/banners', async (req, res) => {
  try {
    const banners = await Banner.findAll({ order: [['sortOrder', 'ASC']] });
    res.render('admin/banners/index', { title: 'Manage Banners', banners });
  } catch (error) {
    req.flash('error', 'Error loading banners.');
    res.redirect('/admin');
  }
});

router.post('/banners/create', createUploader('banners').single('image'), async (req, res) => {
  try {
    const { title, subtitle, link, btnText, sortOrder, isActive } = req.body;
    if (!req.file) { req.flash('error', 'Banner image is required.'); return res.redirect('/admin/banners'); }
    await Banner.create({
      title, subtitle, link, btnText,
      image: '/uploads/banners/' + req.file.filename,
      sortOrder: sortOrder || 0, isActive: isActive === 'on',
    });
    req.flash('success', 'Banner created.');
    res.redirect('/admin/banners');
  } catch (error) {
    req.flash('error', 'Error creating banner.');
    res.redirect('/admin/banners');
  }
});

router.post('/banners/:id/toggle', async (req, res) => {
  try {
    const banner = await Banner.findByPk(req.params.id);
    if (banner) await banner.update({ isActive: !banner.isActive });
    res.json({ success: true });
  } catch (error) {
    res.json({ success: false });
  }
});

router.post('/banners/:id/delete', async (req, res) => {
  try {
    await Banner.destroy({ where: { id: req.params.id } });
    req.flash('success', 'Banner deleted.');
    res.redirect('/admin/banners');
  } catch (error) {
    req.flash('error', 'Error deleting banner.');
    res.redirect('/admin/banners');
  }
});

// ===================== SETTINGS =====================
router.get('/settings', async (req, res) => {
  try {
    const settings = await Setting.findAll();
    const settingsMap = {};
    settings.forEach(s => { settingsMap[s.key] = s.value; });
    res.render('admin/settings/index', { title: 'Store Settings', settings: settingsMap });
  } catch (error) {
    req.flash('error', 'Error loading settings.');
    res.redirect('/admin');
  }
});

router.post('/settings', async (req, res) => {
  try {
    const allowedKeys = ['store_name', 'store_email', 'store_phone', 'store_address', 'currency', 'tax_rate', 'shipping_flat_rate', 'shipping_free_min_amount', 'razorpay_key_id', 'razorpay_key_secret'];
    for (const key of allowedKeys) {
      if (req.body[key] !== undefined) {
        await Setting.upsert({ key, value: req.body[key] });
      }
    }
    req.flash('success', 'Settings saved.');
    res.redirect('/admin/settings');
  } catch (error) {
    req.flash('error', 'Error saving settings.');
    res.redirect('/admin/settings');
  }
});

// ===================== REPORTS =====================
router.get('/reports', async (req, res) => {
  try {
    const stats = await ReportService.getDashboardStats();
    const salesChart = await ReportService.getSalesChartData(30);
    const topProducts = await ReportService.getTopProducts(20);
    res.render('admin/reports/index', {
      title: 'Reports',
      stats,
      salesChart: JSON.stringify(salesChart),
      topProducts,
    });
  } catch (error) {
    req.flash('error', 'Error loading reports.');
    res.redirect('/admin');
  }
});

module.exports = router;
