const express = require('express');
const { Voucher } = require('../models');
const { authenticateToken } = require('../middleware/auth');
const { Op } = require('sequelize');
const router = express.Router();

// Get all vouchers (Public or User?) - Let's make it public for now or user specific?
// Usually there is a "My Vouchers" page or "Available Vouchers" list
router.get('/', async (req, res) => {
    try {
        const vouchers = await Voucher.findAll({
            where: {
                status: 'Active',
                expiryDate: { [Op.gt]: new Date() }
            }
        });
        res.json(vouchers);
    } catch (error) {
        res.status(500).json({ message: 'Server error', error: error.message });
    }
});

// Check Voucher Validity
router.post('/check', authenticateToken, async (req, res) => {
    try {
        const { code, totalAmount } = req.body;

        if (!code) {
            return res.status(400).json({ valid: false, message: 'Code is required' });
        }

        const voucher = await Voucher.findOne({
            where: { code: code }
        });

        if (!voucher) {
            return res.status(404).json({ valid: false, message: 'Voucher tidak ditemukan' });
        }

        // Checks
        if (voucher.status !== 'Active') {
            return res.status(400).json({ valid: false, message: 'Voucher tidak aktif' });
        }

        if (new Date(voucher.expiryDate) < new Date()) {
            return res.status(400).json({ valid: false, message: 'Voucher sudah kadaluarsa' });
        }

        if (voucher.usageLimit > 0 && voucher.usedCount >= voucher.usageLimit) {
            return res.status(400).json({ valid: false, message: 'Kuota voucher habis' });
        }

        if (parseFloat(totalAmount) < parseFloat(voucher.minPurchase)) {
            return res.status(400).json({ 
                valid: false, 
                message: `Minimal pembelian Rp ${parseInt(voucher.minPurchase).toLocaleString('id-ID')}` 
            });
        }

        // Calculate Discount
        let discount = 0;
        let eligibleAmount = parseFloat(totalAmount);

        // Filter by tags if applicable
        let voucherTags = voucher.applicable_tags;
        // Parse if string (handling potential JSON string from DB or raw text)
        if (typeof voucherTags === 'string') {
            try { 
                // Try JSON parse first
                voucherTags = JSON.parse(voucherTags); 
            } catch(e) { 
                // If not JSON, maybe comma separated?
                voucherTags = [];
            }
        }

        if (voucherTags && Array.isArray(voucherTags) && voucherTags.length > 0 && req.body.items) {
            const lowerVoucherTags = voucherTags.map(t => t.toString().toLowerCase().trim());

            // Recalculate eligible amount based on items with matching tags
            eligibleAmount = req.body.items.reduce((sum, item) => {
                // Check if item has tags and matches
                let itemTags = item.tags || (item.Book && item.Book.tags) || [];
                
                // Parse item tags if string
                if (typeof itemTags === 'string') {
                     try { 
                        itemTags = JSON.parse(itemTags); 
                     } catch (e) { 
                        // If plain string like "Fiksi, Novel", split it
                        itemTags = itemTags.split(',').map(t => t.trim());
                     }
                }
                
                if (!Array.isArray(itemTags)) itemTags = [];

                const hasTag = itemTags.some(tag => lowerVoucherTags.includes(tag.toString().toLowerCase().trim()));
                return hasTag ? sum + (item.price * item.quantity) : sum;
            }, 0);

            if (eligibleAmount === 0) {
                 return res.status(400).json({ 
                    valid: false, 
                    message: `Voucher ini hanya berlaku untuk produk dengan tag: ${voucherTags.join(', ')}` 
                });
            }
        }

        if (voucher.type === 'Fixed') {
            discount = parseFloat(voucher.discount);
        } else {
            discount = (eligibleAmount * parseFloat(voucher.discount)) / 100;
        }

        // Max Discount Cap
        if (voucher.maxDiscount && discount > parseFloat(voucher.maxDiscount)) {
            discount = parseFloat(voucher.maxDiscount);
        }

        // Ensure discount doesn't exceed total
        if (discount > parseFloat(totalAmount)) {
            discount = parseFloat(totalAmount);
        }

        res.json({
            valid: true,
            discount: discount,
            voucher: {
                id: voucher.id, // Important for Order
                code: voucher.code,
                type: voucher.type,
                discountValue: voucher.discount
            }
        });

    } catch (error) {
        res.status(500).json({ message: 'Server error', error: error.message });
    }
});

module.exports = router;
