const express = require('express');
const router = express.Router();
const Place = require('../models/Place');
const PlaceCategory = require('../models/PlaceCategory');
const Product = require('../models/Product');
const Rating = require('../models/Rating');
const User = require('../models/User');
const { protect } = require('../middleware/authMiddleware');
const { logAdminAction } = require('../utils/adminLogger');
const logger = require('../utils/logger');

// ============================================================
// @route   GET /api/places/categories
// @desc    Get all active categories
// ============================================================
router.get('/categories', async (req, res) => {
    try {
        const categories = await PlaceCategory.find({ isActive: true }).sort({ sortOrder: 1, name: 1 });
        res.json(categories);
    } catch (err) {
        logger.error('Places Categories Error:', err);
        res.status(500).json({ message: 'Server Error' });
    }
});

// ============================================================
// @route   GET /api/places?category_id=X&city=Khartoum
// @desc    Get places for a category, scoped to a city
// ============================================================
router.get('/', async (req, res) => {
    try {
        const { category_id, city } = req.query;
        const query = { isActive: true };
        if (category_id) query.category = category_id;

        // 🌍 City isolation: only return places in the requested city.
        // If city='all', bypass the city filter (useful for admin dashboard).
        // If no city is provided, fall back to Khartoum (safe default for legacy clients).
        if (city === 'all') {
            // No city filter applied
        } else {
            query.city = city || 'Khartoum';
        }

        const places = await Place.find(query).populate('category', 'name icon');

        // زيادة عداد المشاهدات (fire & forget)
        if (places.length > 0) {
            Place.updateMany(
                { _id: { $in: places.map(p => p._id) } },
                { $inc: { viewsCount: 1 } }
            ).catch(() => {});
        }

        // Return with virtuals + ownerId so client can show "Browse Products" button for merchant stores
        res.json(places.map(p => {
            const obj = p.toJSON();
            // Explicitly include ownerId so the client knows if this place has a merchant
            if (p.ownerId) obj.ownerId = p.ownerId;
            return obj;
        }));
    } catch (err) {
        logger.error('Places List Error:', err);
        res.status(500).json({ message: 'Server Error' });
    }
});

// ============================================================
// @route   GET /api/places/:id
// @desc    Get a single place by ID
// ============================================================
router.get('/:id', async (req, res) => {
    try {
        const place = await Place.findById(req.params.id).populate('category', 'name icon');
        if (!place) return res.status(404).json({ message: 'المحل غير موجود' });
        res.json(place.toJSON());
    } catch (err) {
        res.status(500).json({ message: 'Server Error' });
    }
});

// ============================================================
// @route   POST /api/places/categories
// @desc    Admin: Create a category
// ============================================================
router.post('/categories', protect, async (req, res) => {
    try {
        if (req.user.role !== 'admin') return res.status(403).json({ message: 'Admins only' });
        const { name, icon, sortOrder, notes } = req.body;
        if (!name) return res.status(400).json({ message: 'اسم الفئة مطلوب' });
        const cat = await PlaceCategory.create({ name, icon, sortOrder, notes });
        await logAdminAction(req, 'create_category', `إضافة قسم جديد: ${name}`, cat._id, name);
        res.status(201).json(cat);
    } catch (err) {
        res.status(500).json({ message: 'Server Error' });
    }
});

// @route   PUT /api/places/categories/:id
router.put('/categories/:id', protect, async (req, res) => {
    try {
        if (req.user.role !== 'admin') return res.status(403).json({ message: 'Admins only' });
        const cat = await PlaceCategory.findByIdAndUpdate(req.params.id, req.body, { new: true });
        if (!cat) return res.status(404).json({ message: 'غير موجود' });
        await logAdminAction(req, 'update_category', `تعديل قسم: ${cat.name}`, cat._id, cat.name);
        res.json(cat);
    } catch (err) {
        res.status(500).json({ message: 'Server Error' });
    }
});

// @route   DELETE /api/places/categories/:id
router.delete('/categories/:id', protect, async (req, res) => {
    try {
        if (req.user.role !== 'admin') return res.status(403).json({ message: 'Admins only' });
        const cat = await PlaceCategory.findByIdAndUpdate(req.params.id, { isActive: false }, { new: true });
        if (cat) await logAdminAction(req, 'delete_category', `إخفاء قسم: ${cat.name}`, cat._id, cat.name);
        res.json({ message: 'تم إخفاء التصنيف' });
    } catch (err) {
        res.status(500).json({ message: 'Server Error' });
    }
});

// ============================================================
// @route   POST /api/places
// @desc    Admin: Create a place (optionally with a new merchant account)
// ============================================================
router.post('/', protect, async (req, res) => {
    try {
        if (req.user.role !== 'admin') return res.status(403).json({ message: 'Admins only' });

        const {
            name, category, image_url, phone, whatsapp, location, address,
            map_url, workingHours, menu, notes,
            // 👤 بيانات التاجر (اختياري)
            ownerName, ownerPhone, ownerEmail, ownerPassword, ownerBankAccount,
            ownerId // ربط بمستخدم موجود مسبقاً
        } = req.body;

        if (!name || !category || !location) {
            return res.status(400).json({ message: 'الاسم والفئة والموقع مطلوبة' });
        }

        let resolvedOwnerId = ownerId || null;

        // ─── حالة 1: إنشاء حساب تاجر جديد ───────────────────────
        if (ownerName && ownerPhone && ownerPassword && !ownerId) {
            // تحقق من عدم تكرار الهاتف
            const existingUser = await User.findOne({ phone: ownerPhone });
            if (existingUser) {
                return res.status(400).json({ message: `رقم الهاتف ${ownerPhone} مسجّل مسبقاً لمستخدم آخر` });
            }

            const newMerchant = new User({
                name: ownerName,
                phone: ownerPhone,
                email: ownerEmail || undefined,
                password: ownerPassword,
                role: 'merchant',
                approvalStatus: 'approved',
                isVerified: true
            });
            await newMerchant.save();
            resolvedOwnerId = newMerchant._id;

            // حفظ رقم الحساب البنكي في MerchantRequest إن أُرسل
            if (ownerBankAccount) {
                const MerchantRequest = require('../models/MerchantRequest');
                const PlaceCategory = require('../models/PlaceCategory');
                let categoryDoc = null;
                if (require('mongoose').Types.ObjectId.isValid(category)) {
                    categoryDoc = await PlaceCategory.findById(category);
                }
                await MerchantRequest.create({
                    userId: resolvedOwnerId,
                    businessName: name,
                    ownerName,
                    phone: ownerPhone,
                    category: categoryDoc ? categoryDoc.name : '',
                    address: address || '',
                    bankAccount: ownerBankAccount,
                    status: 'approved',
                    logoImage: image_url || ''
                });
            }
        }

        // ─── حالة 2: ربط بمستخدم موجود ──────────────────────────
        if (ownerId && !ownerName) {
            // تأكد إن المستخدم موجود وحوّل دوره لتاجر
            await User.findByIdAndUpdate(ownerId, { role: 'merchant', approvalStatus: 'approved' });
        }

        // ─── إنشاء المتجر ─────────────────────────────────────────
        const place = await Place.create({
            name, category, image_url, phone, whatsapp, location, address,
            map_url, workingHours, menu, notes,
            ownerId: resolvedOwnerId,
            city: req.body.city || 'Khartoum', // 🌍 Stamp city; default to Khartoum
            isActive: true,
            isOpenOverride: true,
            deliveryAvailable: true
        });

        res.status(201).json(place.toJSON());
    } catch (err) {
        logger.error('Create Place Error:', err);
        res.status(500).json({ message: err.message || 'Server Error' });
    }
});

// ============================================================
// @route   PUT /api/places/:id
// @desc    Admin: Update a place
// ============================================================
router.put('/:id', protect, async (req, res) => {
    try {
        if (req.user.role !== 'admin') return res.status(403).json({ message: 'Admins only' });
        const place = await Place.findByIdAndUpdate(req.params.id, req.body, { new: true });
        if (!place) return res.status(404).json({ message: 'غير موجود' });
        await logAdminAction(req, 'update_store', `تعديل متجر: ${place.name}`, place._id, place.name);
        res.json(place.toJSON());
    } catch (err) {
        res.status(500).json({ message: 'Server Error' });
    }
});

// ============================================================
// @route   DELETE /api/places/:id
// @desc    Admin: Delete/deactivate a place
// ============================================================
router.delete('/:id', protect, async (req, res) => {
    try {
        if (req.user.role !== 'admin') return res.status(403).json({ message: 'Admins only' });
        
        const place = await Place.findById(req.params.id);
        if (!place) return res.status(404).json({ message: 'المتجر غير موجود' });

        const ownerId = place.ownerId;
        const placeName = place.name;

        // 1. Delete the Place and its Products
        await Place.findByIdAndDelete(req.params.id);
        
        const Product = require('../models/Product');
        await Product.deleteMany({ placeId: req.params.id });

        if (ownerId) {
            // 2. Delete the associated MerchantRequest so it disappears from the requests page
            const MerchantRequest = require('../models/MerchantRequest');
            await MerchantRequest.findOneAndDelete({ userId: ownerId });

            // 3. Check if user has other places, if not, revert role to client
            const otherPlaces = await Place.countDocuments({ ownerId: ownerId });
            if (otherPlaces === 0) {
                const User = require('../models/User');
                await User.findByIdAndUpdate(ownerId, { role: 'client' });
            }
        }

        res.json({ message: 'تم حذف المتجر وبياناته ومزامنته بنجاح' });
    } catch (err) {
        res.status(500).json({ message: 'Server Error' });
    }
});

// ============================================================
// @route   POST /api/places/seed-demo
// @desc    Admin: Seed demo categories & places for testing
// ============================================================
router.post('/seed-demo', protect, async (req, res) => {
    try {
        if (req.user.role !== 'admin') return res.status(403).json({ message: 'Admins only' });

        // Clear existing
        await PlaceCategory.deleteMany({});
        await Place.deleteMany({});

        const categories = await PlaceCategory.insertMany([
            { name: 'صيدليات', icon: 'bi-capsule-pill', sortOrder: 1 },
            { name: 'مطاعم', icon: 'bi-cup-hot-fill', sortOrder: 2 },
            { name: 'سوبرماركت', icon: 'bi-cart-fill', sortOrder: 3 },
            { name: 'مخابز', icon: 'bi-egg-fried', sortOrder: 4 },
            { name: 'إلكترونيات', icon: 'bi-phone-fill', sortOrder: 5 },
            { name: 'ملابس', icon: 'bi-bag-fill', sortOrder: 6 },
        ]);

        const pharma = categories[0]._id;
        const restaurants = categories[1]._id;
        const supermarket = categories[2]._id;
        const bakery = categories[3]._id;

        // Demo places around Khartoum
        await Place.insertMany([
            {
                name: 'صيدلية النيل', category: pharma,
                image_url: 'https://images.unsplash.com/photo-1631549916768-4119b2e5f926?w=400',
                phone: '0912345678', whatsapp: '249912345678',
                location: { lat: 15.5010, lng: 32.5590 },
                workingHours: { open: '08:00', close: '22:00', days: [0, 1, 2, 3, 4, 5, 6] }
            },
            {
                name: 'صيدلية الخرطوم', category: pharma,
                image_url: 'https://images.unsplash.com/photo-1582281298055-e25b84a30b0b?w=400',
                phone: '0922345678', whatsapp: '249922345678',
                location: { lat: 15.5050, lng: 32.5630 },
                workingHours: { open: '09:00', close: '21:00', days: [1, 2, 3, 4, 5, 6] }
            },
            {
                name: 'مطعم البيت السوداني', category: restaurants,
                image_url: 'https://images.unsplash.com/photo-1567620905732-2d1ec7ab7445?w=400',
                phone: '0933345678', whatsapp: '249933345678',
                location: { lat: 15.4980, lng: 32.5570 },
                workingHours: { open: '07:00', close: '23:00', days: [0, 1, 2, 3, 4, 5, 6] }
            },
            {
                name: 'مطعم شاورما بيروت', category: restaurants,
                image_url: 'https://images.unsplash.com/photo-1529006557810-274b9b2fc783?w=400',
                phone: '0944345678', whatsapp: '249944345678',
                location: { lat: 15.5035, lng: 32.5615 },
                workingHours: { open: '11:00', close: '02:00', days: [0, 1, 2, 3, 4, 5, 6] }
            },
            {
                name: 'سوبرماركت الفردوس', category: supermarket,
                image_url: 'https://images.unsplash.com/photo-1604719312566-8912e9227c6a?w=400',
                phone: '0955345678', whatsapp: '249955345678',
                location: { lat: 15.5020, lng: 32.5600 },
                workingHours: { open: '07:00', close: '23:00', days: [0, 1, 2, 3, 4, 5, 6] }
            },
            {
                name: 'مخبز الأمل', category: bakery,
                image_url: 'https://images.unsplash.com/photo-1509440159596-0249088772ff?w=400',
                phone: '0966345678', whatsapp: '249966345678',
                location: { lat: 15.4995, lng: 32.5580 },
                workingHours: { open: '05:00', close: '20:00', days: [0, 1, 2, 3, 4, 5, 6] }
            }
        ]);

        res.json({
            message: 'تم إدراج البيانات التجريبية بنجاح ✅',
            categories: categories.length,
            places: 6
        });

    } catch (err) {
        logger.error('Seed Error:', err);
        res.status(500).json({ message: err.message });
    }
});

// ============================================================
// ⭐ نظام التقييمات + عداد المشاهدات
// ============================================================

// تسجيل مشاهدة لمتجر (fire & forget)
router.post('/:id/view', async (req, res) => {
    try {
        await Place.findByIdAndUpdate(req.params.id, { $inc: { viewsCount: 1 } });
        res.json({ ok: true });
    } catch (e) {
        res.status(500).json({ message: 'Server Error' });
    }
});

// تسجيل مشاهدة لمنتج (fire & forget)
router.post('/:placeId/products/:productId/view', async (req, res) => {
    try {
        await Product.findByIdAndUpdate(req.params.productId, { $inc: { viewsCount: 1 } });
        res.json({ ok: true });
    } catch (e) {
        res.status(500).json({ message: 'Server Error' });
    }
});

// جلب تقييمات متجر
router.get('/:id/reviews', async (req, res) => {
    try {
        const page  = Math.max(1, parseInt(req.query.page)  || 1);
        const limit = Math.min(50, parseInt(req.query.limit) || 20);

        const [reviews, total] = await Promise.all([
            Rating.find({ targetType: 'place', targetId: req.params.id, isHidden: false })
                .populate('client', 'name')
                .sort({ createdAt: -1 })
                .skip((page - 1) * limit)
                .limit(limit)
                .select('score comment createdAt client'),
            Rating.countDocuments({ targetType: 'place', targetId: req.params.id, isHidden: false })
        ]);

        const place = await Place.findById(req.params.id).select('ratingAvg ratingCount');
        res.json({ reviews, total, page, ratingAvg: place?.ratingAvg || 0, ratingCount: place?.ratingCount || 0 });
    } catch (e) {
        logger.error('Place reviews error:', e);
        res.status(500).json({ message: 'Server Error' });
    }
});

// جلب تقييمات منتج
router.get('/:placeId/products/:productId/reviews', async (req, res) => {
    try {
        const [reviews, total] = await Promise.all([
            Rating.find({ targetType: 'product', targetId: req.params.productId, isHidden: false })
                .populate('client', 'name')
                .sort({ createdAt: -1 })
                .limit(30)
                .select('score comment createdAt client'),
            Rating.countDocuments({ targetType: 'product', targetId: req.params.productId, isHidden: false })
        ]);
        const product = await Product.findById(req.params.productId).select('ratingAvg ratingCount');
        res.json({ reviews, total, ratingAvg: product?.ratingAvg || 0, ratingCount: product?.ratingCount || 0 });
    } catch (e) {
        res.status(500).json({ message: 'Server Error' });
    }
});

// تقييم متجر من عميل
router.post('/:id/rate', protect, async (req, res) => {
    try {
        const { score, comment, orderId } = req.body;
        const placeId = req.params.id;

        if (!score || score < 1 || score > 5) {
            return res.status(400).json({ message: 'التقييم يجب أن يكون بين 1 و 5 نجوم' });
        }

        const place = await Place.findById(placeId);
        if (!place) return res.status(404).json({ message: 'المتجر غير موجود' });

        // منع التقييم المزدوج لنفس الطلب
        if (orderId) {
            const exists = await Rating.findOne({ client: req.user._id, order: orderId, targetType: 'place' });
            if (exists) return res.status(400).json({ message: 'لقد قيّمت هذا المتجر مسبقاً لهذا الطلب' });
        }

        await Rating.create({
            client:     req.user._id,
            targetType: 'place',
            targetId:   placeId,
            order:      orderId || null,
            orderModel: 'ShopOrder',
            score:      Number(score),
            comment:    comment || ''
        });

        // تحديث متوسط التقييم
        const stats = await Rating.aggregate([
            { $match: { targetType: 'place', targetId: place._id, isHidden: false } },
            { $group: { _id: null, avg: { $avg: '$score' }, count: { $sum: 1 } } }
        ]);
        if (stats.length > 0) {
            place.ratingAvg   = Math.round(stats[0].avg * 10) / 10;
            place.ratingCount = stats[0].count;
            await place.save();
        }

        res.status(201).json({ message: 'شكراً على تقييمك!', ratingAvg: place.ratingAvg, ratingCount: place.ratingCount });
    } catch (e) {
        if (e.code === 11000) return res.status(400).json({ message: 'لقد قيّمت هذا المتجر مسبقاً' });
        logger.error('Place rate error:', e);
        res.status(500).json({ message: 'Server Error' });
    }
});

// تقييم منتج من عميل
router.post('/:placeId/products/:productId/rate', protect, async (req, res) => {
    try {
        const { score, comment, orderId } = req.body;
        const productId = req.params.productId;
        const placeId   = req.params.placeId;

        if (!score || score < 1 || score > 5) {
            return res.status(400).json({ message: 'التقييم يجب أن يكون بين 1 و 5 نجوم' });
        }

        const product = await Product.findById(productId);
        if (!product) return res.status(404).json({ message: 'المنتج غير موجود' });

        await Rating.create({
            client:     req.user._id,
            targetType: 'product',
            targetId:   productId,
            place:      placeId,
            order:      orderId || null,
            orderModel: 'ShopOrder',
            score:      Number(score),
            comment:    comment || ''
        });

        // تحديث متوسط تقييم المنتج
        const stats = await Rating.aggregate([
            { $match: { targetType: 'product', targetId: product._id, isHidden: false } },
            { $group: { _id: null, avg: { $avg: '$score' }, count: { $sum: 1 } } }
        ]);
        if (stats.length > 0) {
            product.ratingAvg   = Math.round(stats[0].avg * 10) / 10;
            product.ratingCount = stats[0].count;
            await product.save();
        }

        res.status(201).json({ message: 'شكراً على تقييمك!', ratingAvg: product.ratingAvg });
    } catch (e) {
        if (e.code === 11000) return res.status(400).json({ message: 'لقد قيّمت هذا المنتج مسبقاً' });
        logger.error('Product rate error:', e);
        res.status(500).json({ message: 'Server Error' });
    }
});

module.exports = router;
