// apps/api/src/controllers/billing.controller.js

const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
const { DatabaseClient } = require('../../../../packages/db/client');
const db = new DatabaseClient();

exports.createCheckoutSession = async (req, res) => {
    try {
        const session = await stripe.checkout.sessions.create({
            payment_method_types: ['card'],
            line_items: [{
                price_data: {
                    currency: 'usd',
                    product_data: { 
                        name: 'AfriIntel Pro Plan',
                        description: 'Unlimited intent signals for 30 days'
                    },
                    unit_amount: 1300, // $10.00 for 30 days
                    recurring: {
                        interval: 'month'
                    }
                },
                quantity: 1,
            }],
            mode: 'subscription',
            success_url: `${process.env.FRONTEND_URL}/billing?success=true&session_id={CHECKOUT_SESSION_ID}`,
            cancel_url: `${process.env.FRONTEND_URL}/billing?canceled=true`,
            customer_email: req.user.email,
            metadata: { 
                userId: req.user.id,
                userEmail: req.user.email
            }
        });
        res.json({ url: session.url });
    } catch (error) {
        console.error('Stripe session error:', error);
        res.status(500).json({ error: 'Failed to create checkout session' });
    }
};

exports.verifyPayment = async (req, res) => {
    try {
        const { session_id } = req.body;
        
        if (!session_id) {
            return res.status(400).json({ error: 'Session ID required' });
        }
        
        const session = await stripe.checkout.sessions.retrieve(session_id);
        
        if (session.payment_status === 'paid') {
            const userId = req.user.id;
            
            // Calculate end date (30 days from now)
            const currentPeriodEnd = new Date();
            currentPeriodEnd.setDate(currentPeriodEnd.getDate() + 30);
            
            await db.run(
                `UPDATE users SET 
                    plan = 'pro', 
                    subscription_status = 'active', 
                    current_period_end = ?,
                    updated_at = datetime('now') 
                 WHERE id = ?`,
                [currentPeriodEnd.toISOString(), userId]
            );
            
            const user = await db.get('SELECT id, email, full_name, role, plan, current_period_end FROM users WHERE id = ?', [userId]);
            
            console.log(`✅ User ${userId} upgraded to Pro until ${currentPeriodEnd.toISOString()}`);
            
            res.json({ 
                success: true, 
                message: 'Account upgraded to Pro',
                user: user
            });
        } else {
            res.status(400).json({ error: 'Payment not completed' });
        }
    } catch (error) {
        console.error('Verify payment error:', error);
        res.status(500).json({ error: 'Failed to verify payment' });
    }
};

exports.webhook = async (req, res) => {
    const sig = req.headers['stripe-signature'];
    let event;
    
    try {
        event = stripe.webhooks.constructEvent(req.body, sig, process.env.STRIPE_WEBHOOK_SECRET);
    } catch (err) {
        console.error(`Webhook signature verification failed: ${err.message}`);
        return res.status(400).send(`Webhook Error: ${err.message}`);
    }
    
    if (event.type === 'checkout.session.completed') {
        const session = event.data.object;
        const userId = session.metadata.userId;
        const subscriptionId = session.subscription;
        
        const subscription = await stripe.subscriptions.retrieve(subscriptionId);
        const currentPeriodEnd = new Date(subscription.current_period_end * 1000).toISOString();
        
        await db.run(
            `UPDATE users SET 
                plan = 'pro', 
                subscription_id = ?, 
                subscription_status = 'active',
                current_period_end = ?,
                updated_at = datetime('now')
             WHERE id = ?`,
            [subscriptionId, currentPeriodEnd, userId]
        );
        
        console.log(`✅ User ${userId} (${session.customer_email}) upgraded to Pro until ${currentPeriodEnd}`);
    }
    
    if (event.type === 'customer.subscription.updated') {
        const subscription = event.data.object;
        const subscriptionId = subscription.id;
        
        await db.run(
            `UPDATE users SET 
                current_period_end = ?,
                subscription_status = ?,
                updated_at = datetime('now')
             WHERE subscription_id = ?`,
            [new Date(subscription.current_period_end * 1000).toISOString(), subscription.status, subscriptionId]
        );
    }
    
    if (event.type === 'customer.subscription.deleted') {
        const subscription = event.data.object;
        const subscriptionId = subscription.id;
        
        await db.run(
            `UPDATE users SET 
                plan = 'free', 
                subscription_status = 'canceled',
                updated_at = datetime('now')
             WHERE subscription_id = ?`,
            [subscriptionId]
        );
        
        console.log(`User subscription canceled, reverted to free plan`);
    }
    
    res.json({ received: true });
};

exports.getSubscriptionStatus = async (req, res) => {
    try {
        const user = await db.get(
            `SELECT plan, subscription_status, current_period_end 
             FROM users WHERE id = ?`,
            [req.user.id]
        );
        
        let daysLeft = null;
        if (user && user.current_period_end) {
            const endDate = new Date(user.current_period_end);
            daysLeft = Math.ceil((endDate - new Date()) / (1000 * 60 * 60 * 24));
        }
        
        res.json({
            plan: user?.plan || 'free',
            status: user?.subscription_status || 'inactive',
            current_period_end: user?.current_period_end || null,
            days_left: daysLeft
        });
    } catch (error) {
        console.error('Get subscription error:', error);
        res.status(500).json({ error: 'Failed to get subscription status' });
    }
};

exports.cancelSubscription = async (req, res) => {
    try {
        const user = await db.get('SELECT subscription_id FROM users WHERE id = ?', [req.user.id]);
        
        if (!user || !user.subscription_id) {
            return res.status(400).json({ error: 'No active subscription found' });
        }
        
        await stripe.subscriptions.update(user.subscription_id, {
            cancel_at_period_end: true
        });
        
        res.json({ message: 'Subscription will be canceled at the end of the billing period' });
    } catch (error) {
        console.error('Cancel subscription error:', error);
        res.status(500).json({ error: 'Failed to cancel subscription' });
    }
};