/**
 * MVC (ModpackChecker) Licensing API Routes
 *
 * Public endpoints (no session auth — token/order_id based):
 *   POST /api/mvc/activate     — Activate a license on a panel
 *   POST /api/mvc/validate     — 72hr phone-home heartbeat
 *   POST /api/mvc/deactivate   — Release an activation slot
 *   POST /api/mvc/webhook/bbb  — BuiltByBit purchase webhook
 *   GET  /api/mvc/latest-version — Current version for update checks
 */

const express = require('express');
const router = express.Router();
const crypto = require('crypto');
const db = require('../database');

// Current published version — bump when releasing updates
const MVC_CURRENT_VERSION = '1.0.0';

// =============================================================================
// POST /api/mvc/activate
// Body: { order_id, domain, ip }
// =============================================================================

router.post('/activate', async (req, res) => {
    const order_id = req.body.order_id ? req.body.order_id.toString().toUpperCase().trim() : null;
    const { domain, ip } = req.body;

    if (!order_id || !domain) {
        return res.status(400).json({
            error: 'Missing required fields',
            required: ['order_id', 'domain']
        });
    }

    try {
        // Find active license
        const { rows: licenses } = await db.query(
            'SELECT * FROM mvc_licenses WHERE order_id = $1 AND status = $2',
            [order_id, 'active']
        );

        if (licenses.length === 0) {
            return res.status(404).json({ error: 'License not found or inactive' });
        }

        const license = licenses[0];

        // Check existing activations
        const { rows: activations } = await db.query(
            'SELECT * FROM mvc_activations WHERE license_id = $1',
            [license.id]
        );

        // Already activated on this domain? Update last_seen
        const existing = activations.find(a => a.panel_domain === domain);
        if (existing) {
            await db.query(
                'UPDATE mvc_activations SET last_seen = NOW(), panel_ip = $1 WHERE id = $2',
                [ip || existing.panel_ip, existing.id]
            );
            return res.json({
                status: 'active',
                tier: license.tier,
                message: 'Already activated on this domain'
            });
        }

        // Check activation limit
        if (activations.length >= license.max_activations) {
            return res.status(403).json({
                error: 'Activation limit reached',
                max: license.max_activations,
                current: activations.length
            });
        }

        // Create activation
        await db.query(
            `INSERT INTO mvc_activations (license_id, panel_domain, panel_ip)
             VALUES ($1, $2, $3)`,
            [license.id, domain, ip || null]
        );

        console.log(`🔑 [MVC] Activated license ${order_id} on ${domain}`);
        return res.json({
            status: 'active',
            tier: license.tier,
            activations_used: activations.length + 1,
            activations_max: license.max_activations
        });

    } catch (error) {
        console.error('❌ [MVC Activate] Error:', error);
        return res.status(500).json({ error: 'Activation failed' });
    }
});

// =============================================================================
// POST /api/mvc/validate
// Body: { order_id, domain, version, php_version }
// 72hr phone-home heartbeat
// =============================================================================

router.post('/validate', async (req, res) => {
    const order_id = req.body.order_id ? req.body.order_id.toString().toUpperCase().trim() : null;
    const { domain, version, php_version } = req.body;

    if (!order_id || !domain) {
        return res.status(400).json({
            error: 'Missing required fields',
            required: ['order_id', 'domain']
        });
    }

    try {
        const { rows: licenses } = await db.query(
            'SELECT * FROM mvc_licenses WHERE order_id = $1',
            [order_id]
        );

        if (licenses.length === 0) {
            return res.status(404).json({ status: 'invalid', error: 'License not found' });
        }

        const license = licenses[0];

        if (license.status !== 'active') {
            return res.status(403).json({ status: license.status, error: 'License not active' });
        }

        // Update last_seen on matching activation
        const { rowCount } = await db.query(
            `UPDATE mvc_activations SET last_seen = NOW()
             WHERE license_id = $1 AND panel_domain = $2`,
            [license.id, domain]
        );

        if (rowCount === 0) {
            return res.status(404).json({
                status: 'not_activated',
                error: 'No activation found for this domain'
            });
        }

        return res.json({
            status: 'active',
            tier: license.tier,
            latest_version: MVC_CURRENT_VERSION
        });

    } catch (error) {
        console.error('❌ [MVC Validate] Error:', error);
        return res.status(500).json({ error: 'Validation failed' });
    }
});

// =============================================================================
// POST /api/mvc/deactivate
// Body: { order_id, domain }
// =============================================================================

router.post('/deactivate', async (req, res) => {
    const order_id = req.body.order_id ? req.body.order_id.toString().toUpperCase().trim() : null;
    const { domain } = req.body;

    if (!order_id || !domain) {
        return res.status(400).json({
            error: 'Missing required fields',
            required: ['order_id', 'domain']
        });
    }

    try {
        const { rows: licenses } = await db.query(
            'SELECT id FROM mvc_licenses WHERE order_id = $1',
            [order_id]
        );

        if (licenses.length === 0) {
            return res.status(404).json({ error: 'License not found' });
        }

        const { rowCount } = await db.query(
            `DELETE FROM mvc_activations
             WHERE license_id = $1 AND panel_domain = $2`,
            [licenses[0].id, domain]
        );

        if (rowCount === 0) {
            return res.status(404).json({ error: 'No activation found for this domain' });
        }

        console.log(`🔓 [MVC] Deactivated ${order_id} from ${domain}`);
        return res.json({ status: 'deactivated', domain });

    } catch (error) {
        console.error('❌ [MVC Deactivate] Error:', error);
        return res.status(500).json({ error: 'Deactivation failed' });
    }
});

// =============================================================================
// POST /api/mvc/webhook/bbb
// BuiltByBit purchase webhook — auto-provisions license
// =============================================================================

router.post('/webhook/bbb', async (req, res) => {
    // Verify webhook signature if secret is configured
    const secret = process.env.BBB_WEBHOOK_SECRET;
    if (secret && !secret.startsWith('PLACEHOLDER')) {
        const signature = req.headers['x-bbb-signature'];
        if (!signature) {
            return res.status(401).json({ error: 'Missing signature' });
        }
        const expected = crypto
            .createHmac('sha256', secret)
            .update(JSON.stringify(req.body))
            .digest('hex');
        if (signature !== expected) {
            return res.status(401).json({ error: 'Invalid signature' });
        }
    }

    const order_id = req.body.order_id ? req.body.order_id.toString().toUpperCase().trim() : null;
    const { buyer_id, resource_id } = req.body;

    if (!order_id || !resource_id) {
        return res.status(400).json({
            error: 'Missing required fields',
            required: ['order_id', 'resource_id']
        });
    }

    // Determine tier from resource_id
    const standardId = process.env.BBB_STANDARD_RESOURCE_ID;
    const proId = process.env.BBB_PRO_RESOURCE_ID;
    let tier;

    if (String(resource_id) === String(proId)) {
        tier = 'professional';
    } else if (String(resource_id) === String(standardId)) {
        tier = 'standard';
    } else {
        console.warn(`⚠️ [MVC Webhook] Unknown resource_id: ${resource_id}`);
        return res.status(400).json({ error: 'Unknown resource_id' });
    }

    const maxActivations = tier === 'professional' ? 5 : 2;

    try {
        await db.query(
            `INSERT INTO mvc_licenses (order_id, buyer_id, tier, max_activations)
             VALUES ($1, $2, $3, $4)
             ON CONFLICT (order_id) DO UPDATE SET
                tier = EXCLUDED.tier,
                max_activations = EXCLUDED.max_activations`,
            [String(order_id), String(buyer_id || ''), tier, maxActivations]
        );

        console.log(`🛒 [MVC Webhook] Provisioned ${tier} license: order ${order_id}`);
        return res.json({ status: 'provisioned', tier, order_id });

    } catch (error) {
        console.error('❌ [MVC Webhook] Error:', error);
        return res.status(500).json({ error: 'Failed to provision license' });
    }
});

// =============================================================================
// GET /api/mvc/latest-version
// Returns current version for update checks (no auth required)
// =============================================================================

router.get('/latest-version', (req, res) => {
    res.json({
        version: MVC_CURRENT_VERSION,
        download_url: 'https://builtbybit.com/resources/PLACEHOLDER'
    });
});

module.exports = router;
