const LuckyWheelHistory = require('../models/luckyWheel.model');
const LuckyWheelConfig = require('../models/luckyWheelConfig.model');
const User = require('../models/users.model');
const Transaction = require('../models/transaction.model');
const { BadRequestError } = require('../core/error.response');

class LuckyWheelService {
    generateCode() {
        const random = Math.random().toString(36).substring(2, 7);
        const time = Date.now().toString().slice(-3);
        return `${random.toUpperCase()}${time}`;
    }

    // Get config (create default if not exists)
    async getConfig() {
        let config = await LuckyWheelConfig.findOne();
        if (!config) {
            // Create default config
            config = await LuckyWheelConfig.create({
                spinCost: 10000,
                prizes: [
                    { label: 'Mất lượt', value: 0, probability: 30, color: '#6B7280' },
                    { label: '5,000đ', value: 5000, probability: 25, color: '#10B981' },
                    { label: '10,000đ', value: 10000, probability: 20, color: '#3B82F6' },
                    { label: '20,000đ', value: 20000, probability: 12, color: '#8B5CF6' },
                    { label: '50,000đ', value: 50000, probability: 8, color: '#F59E0B' },
                    { label: '100,000đ', value: 100000, probability: 4, color: '#EF4444' },
                    { label: '200,000đ', value: 200000, probability: 1, color: '#EC4899' },
                ],
                isActive: true,
                maxSpinsPerDay: 0,
            });
        }
        return config;
    }

    // Admin update config
    async updateConfig(data) {
        let config = await LuckyWheelConfig.findOne();
        if (!config) {
            config = new LuckyWheelConfig(data);
        } else {
            config.spinCost = data.spinCost;
            config.prizes = data.prizes;
            config.isActive = data.isActive;
            config.maxSpinsPerDay = data.maxSpinsPerDay;
        }
        return await config.save();
    }

    // Check spins today
    async getSpinsToday(userId) {
        const startOfDay = new Date();
        startOfDay.setHours(0, 0, 0, 0);

        const count = await LuckyWheelHistory.countDocuments({
            userId,
            createdAt: { $gte: startOfDay },
        });
        return count;
    }

    // Spin the wheel
    async spin(userId) {
        const config = await this.getConfig();

        if (!config.isActive) {
            throw new BadRequestError('Vòng quay đang tạm đóng');
        }

        // Check max spins per day
        if (config.maxSpinsPerDay > 0) {
            const spinsToday = await this.getSpinsToday(userId);
            if (spinsToday >= config.maxSpinsPerDay) {
                throw new BadRequestError(
                    `Bạn đã quay đủ ${config.maxSpinsPerDay} lượt hôm nay. Vui lòng quay lại ngày mai!`,
                );
            }
        }

        const user = await User.findById(userId);
        if (!user) {
            throw new BadRequestError('Không tìm thấy người dùng');
        }

        if (user.balance < config.spinCost) {
            throw new BadRequestError(`Số dư không đủ. Cần ${config.spinCost.toLocaleString()}đ để quay`);
        }

        // Deduct spin cost
        const balanceBefore = user.balance;
        user.balance -= config.spinCost;

        // Random prize based on probability
        const prizeIndex = this.getRandomPrizeIndex(config.prizes);
        const prize = config.prizes[prizeIndex];

        // Add reward
        user.balance += prize.value;
        await user.save();

        // Create history record
        const history = await LuckyWheelHistory.create({
            userId,
            spinCost: config.spinCost,
            reward: prize.value,
            rewardLabel: prize.label,
            rewardIndex: prizeIndex,
            balanceBefore,
            balanceAfter: user.balance,
        });

        // Create transaction logs
        // Deduct transaction
        await Transaction.create({
            userId,
            transCode: `SPIN-${this.generateCode()}`,
            type: 'SPIN',
            amount: -config.spinCost,
            balanceBefore,
            balanceAfter: balanceBefore - config.spinCost,
            content: `Quay vòng may mắn - Phí: ${config.spinCost.toLocaleString()}đ`,
        });

        // Reward transaction (if any)
        if (prize.value > 0) {
            await Transaction.create({
                userId,
                transCode: `REWARD-${this.generateCode()}`,
                type: 'REWARD',
                amount: prize.value,
                balanceBefore: balanceBefore - config.spinCost,
                balanceAfter: user.balance,
                content: `Trúng thưởng vòng quay: ${prize.label}`,
            });
        }

        return {
            prizeIndex,
            prize,
            balanceAfter: user.balance,
            history,
        };
    }

    // Random prize based on probability
    getRandomPrizeIndex(prizes) {
        const totalProbability = prizes.reduce((sum, p) => sum + p.probability, 0);
        const random = Math.random() * totalProbability;

        let cumulative = 0;
        for (let i = 0; i < prizes.length; i++) {
            cumulative += prizes[i].probability;
            if (random <= cumulative) {
                return i;
            }
        }
        return prizes.length - 1;
    }

    // Get user history
    async getHistory(userId) {
        return await LuckyWheelHistory.find({ userId }).sort({ createdAt: -1 }).limit(50);
    }

    // Admin: Get all history
    async getAllHistory() {
        return await LuckyWheelHistory.find().populate('userId', 'fullName email').sort({ createdAt: -1 }).limit(100);
    }
}

module.exports = new LuckyWheelService();
