const crypto = require('crypto');
const fs = require('fs');
const path = require('path');

let db;
const DEFAULT_SETTINGS = {
    review_code: 'GUEST2026',
    review_min_length: '20',
    review_ip_cooldown_minutes: '5',
    hotel_phone_primary: '89409270080',
    hotel_phone_additional: '',
    hotel_whatsapp_num: '89409270080',
    hotel_whatsapp_active: 'true',
    hotel_telegram_id: '+89409270080',
    hotel_telegram_active: 'true',
    hotel_max_link: 'kalugin66',
    hotel_max_active: 'true',
    hotel_instagram_id: '',
    hotel_instagram_active: 'true'
};

function init(database) {
    db = database;
    initDefaultSettings();
}

function initDefaultSettings() {
    Object.entries(DEFAULT_SETTINGS).forEach(([key, value]) => {
        db.run(`INSERT OR IGNORE INTO settings (key, value) VALUES (?, ?)`, [key, value], (err) => {
            if (err) console.error('Settings init error:', err);
        });
    });
}

function get(key, callback) {
    db.get(`SELECT value FROM settings WHERE key = ?`, [key], (err, row) => {
        if (err) return callback(err, null);
        callback(null, row ? row.value : null);
    });
}

function set(key, value, callback) {
    db.run(
        `INSERT INTO settings (key, value, updated_at) VALUES (?, ?, CURRENT_TIMESTAMP)
         ON CONFLICT(key) DO UPDATE SET value = ?, updated_at = CURRENT_TIMESTAMP`,
        [key, value, value],
        function(err) {
            if (err) return callback(err);
            callback(null);
        }
    );
}

function getAll(callback) {
    db.all(`SELECT * FROM settings`, [], (err, rows) => {
        if (err) return callback(err, null);
        const settings = {};
        rows.forEach(row => { settings[row.key] = row.value; });
        callback(null, settings);
    });
}

function getReviewCode(callback) {
    get('review_code', callback);
}

function setReviewCode(value, callback) {
    set('review_code', value, callback);
}

function checkIpCooldown(ip, callback) {
    const cooldownMinutes = 5;
    const cutoffTime = new Date(Date.now() - cooldownMinutes * 60 * 1000).toISOString();
    db.get(
        `SELECT id FROM reviews WHERE ip_address = ? AND created_at > ? LIMIT 1`,
        [ip, cutoffTime],
        (err, row) => {
            if (err) return callback(err, false);
            callback(null, !!row);
        }
    );
}

function maskValue(val) {
    if (!val || val.length <= 4) return '****';
    return '****' + val.slice(-4);
}

function setupRoutes(app, authenticateToken, requireAdmin) {
    app.get('/api/admin/settings', authenticateToken, requireAdmin, (req, res) => {
        getAll((err, settings) => {
            if (err) return res.status(500).json({ error: 'Database error' });
            if (settings.review_code) {
                settings.review_code_masked = maskValue(settings.review_code);
            }
            res.json(settings);
        });
    });

    app.get('/api/admin/settings/review-code', authenticateToken, requireAdmin, (req, res) => {
        getReviewCode((err, code) => {
            if (err) return res.status(500).json({ error: 'Database error' });
            res.json({ code: code });
        });
    });

    app.put('/api/admin/settings/review-code', authenticateToken, requireAdmin, (req, res) => {
        const { code } = req.body;
        if (!code || code.length < 3) {
            return res.status(400).json({ error: 'Code must be at least 3 characters' });
        }
        setReviewCode(code, (err) => {
            if (err) return res.status(500).json({ error: 'Database error' });
            res.json({ message: 'Review code updated', code: code });
        });
    });

    app.get('/api/admin/security', authenticateToken, requireAdmin, (req, res) => {
        const jwtSecret = process.env.JWT_SECRET || '';
        const hotelKey = process.env.HOTEL777KEY || '';
        res.json({
            jwt_secret_masked: maskValue(jwtSecret),
            hotel777key_masked: maskValue(hotelKey)
        });
    });

    app.post('/api/admin/security/regenerate', authenticateToken, requireAdmin, (req, res) => {
        const { type } = req.body;
        if (!['jwt', 'hotel777key'].includes(type)) {
            return res.status(400).json({ error: 'Type must be "jwt" or "hotel777key"' });
        }
        
        const secret = crypto.randomBytes(32).toString('hex');
        const envVarName = type === 'jwt' ? 'JWT_SECRET' : 'HOTEL777KEY';
        const envPath = path.join(__dirname, '..', '..', '.env');

        let envContent = '';
        if (fs.existsSync(envPath)) {
            envContent = fs.readFileSync(envPath, 'utf8');
        }
        if (envContent.includes(`${envVarName}=`)) {
            envContent = envContent.replace(new RegExp(`${envVarName}=.*`, 'g'), `${envVarName}=${secret}`);
        } else {
            envContent += `\n${envVarName}=${secret}\n`;
        }
        fs.writeFileSync(envPath, envContent);
        process.env[envVarName] = secret;

        console.log(`🔐 ${envVarName} regenerated by admin`);

        const jwtWarning = type === 'jwt' ? ' Все ранее выданные токены доступа стали недействительными. Пользователям потребуется войти заново.' : '';

        res.json({
            message: `${envVarName} перегенерирован. НЕОБХОДИМО перезапустить сервер для применения нового ключа.${jwtWarning}`,
            warning: 'Ключ сохранён в .env. После перезапуска сервера старый ключ перестанет работать.'
        });
    });

    app.get('/api/admin/settings/email', authenticateToken, requireAdmin, (req, res) => {
        getAll((err, settings) => {
            if (err) return res.status(500).json({ error: 'Database error' });
            res.json({
                smtp_host: settings.smtp_host || '',
                smtp_port: settings.smtp_port || '587',
                smtp_secure: settings.smtp_secure || 'false',
                smtp_user: settings.smtp_user || '',
                smtp_pass_masked: settings.smtp_pass ? maskValue(settings.smtp_pass) : '',
                smtp_from: settings.smtp_from || '',
                email_notifications_enabled: settings.email_notifications_enabled || 'false',
                admin_email: settings.admin_email || ''
            });
        });
    });

    app.put('/api/admin/settings/email', authenticateToken, requireAdmin, (req, res) => {
        const { smtp_host, smtp_port, smtp_secure, smtp_user, smtp_pass, smtp_from, email_notifications_enabled, admin_email } = req.body;
        const updates = [];
        if (smtp_host !== undefined) updates.push(['smtp_host', smtp_host]);
        if (smtp_port !== undefined) updates.push(['smtp_port', smtp_port]);
        if (smtp_secure !== undefined) updates.push(['smtp_secure', smtp_secure]);
        if (smtp_user !== undefined) updates.push(['smtp_user', smtp_user]);
        if (smtp_pass !== undefined && smtp_pass !== '' && !smtp_pass.startsWith('****')) updates.push(['smtp_pass', smtp_pass]);
        if (smtp_from !== undefined) updates.push(['smtp_from', smtp_from]);
        if (email_notifications_enabled !== undefined) updates.push(['email_notifications_enabled', email_notifications_enabled]);
        if (admin_email !== undefined) updates.push(['admin_email', admin_email]);

        let processed = 0;
        if (updates.length === 0) return res.json({ message: 'No changes' });

        updates.forEach(([key, value]) => {
            set(key, value, (err) => {
                if (err) console.error('Email settings update error:', err);
                processed++;
                if (processed === updates.length) {
                    res.json({ message: 'Email settings updated' });
                }
            });
        });
    });

    app.post('/api/admin/settings/email/test', authenticateToken, requireAdmin, (req, res) => {
        const emailModule = require('../email');
        getAll((err, settings) => {
            if (err) return res.status(500).json({ error: 'Database error' });
            const to = settings.admin_email || settings.smtp_user || '';
            if (!to) return res.status(400).json({ error: 'Email получателя не настроен. Укажите admin_email в настройках.' });
            if (!settings.smtp_host) return res.status(400).json({ error: 'SMTP хост не настроен.' });
            emailModule.sendTestEmail(settings, to, (sendErr, info) => {
                if (sendErr) return res.status(500).json({ error: 'Ошибка отправки: ' + sendErr.message });
                res.json({ message: 'Тестовое письмо отправлено на ' + to });
            });
        });
    });

    app.get('/api/admin/settings/phones', authenticateToken, requireAdmin, (req, res) => {
        getAll((err, settings) => {
            if (err) return res.status(500).json({ error: 'Database error' });
            res.json({
                primary: settings.hotel_phone_primary || '',
                additional: settings.hotel_phone_additional || '',
                whatsappNum: settings.hotel_whatsapp_num || '',
                whatsappActive: settings.hotel_whatsapp_active || 'true',
                telegramId: settings.hotel_telegram_id || '',
                telegramActive: settings.hotel_telegram_active || 'true',
                maxLink: settings.hotel_max_link || '',
                maxActive: settings.hotel_max_active || 'true',
                instagramId: settings.hotel_instagram_id || '',
                instagramActive: settings.hotel_instagram_active || 'true'
            });
        });
    });

    app.put('/api/admin/settings/phones', authenticateToken, requireAdmin, (req, res) => {
        const { primary, additional, whatsappNum, whatsappActive, telegramId, telegramActive, maxLink, maxActive, instagramId, instagramActive } = req.body;
        if (!primary || primary.length < 5) {
            return res.status(400).json({ error: 'Основной номер должен содержать минимум 5 цифр' });
        }
        const updates = [];
        updates.push(['hotel_phone_primary', primary]);
        updates.push(['hotel_phone_additional', additional || '']);
        updates.push(['hotel_whatsapp_num', whatsappNum || '']);
        updates.push(['hotel_whatsapp_active', whatsappActive || 'true']);
        updates.push(['hotel_telegram_id', telegramId || '']);
        updates.push(['hotel_telegram_active', telegramActive || 'true']);
        updates.push(['hotel_max_link', maxLink || '']);
        updates.push(['hotel_max_active', maxActive || 'true']);
        updates.push(['hotel_instagram_id', instagramId || '']);
        updates.push(['hotel_instagram_active', instagramActive || 'true']);
        let processed = 0;
        updates.forEach(([key, value]) => {
            set(key, value, (err) => {
                if (err) console.error('Phone settings update error:', err);
                processed++;
                if (processed === updates.length) {
                    res.json({ message: 'Настройки телефонов сохранены' });
                }
            });
        });
    });

    app.get('/api/config', (req, res) => {
        getAll((err, settings) => {
            if (err) return res.status(500).json({ error: 'Database error' });
            res.json({
                phone_primary: settings.hotel_phone_primary || '89409270080',
                phone_additional: settings.hotel_phone_additional || '',
                whatsapp_num: settings.hotel_whatsapp_num || '89409270080',
                whatsapp_active: settings.hotel_whatsapp_active || 'true',
                telegram_id: settings.hotel_telegram_id || '+89409270080',
                telegram_active: settings.hotel_telegram_active || 'true',
                max_link: settings.hotel_max_link || 'kalugin66',
                max_active: settings.hotel_max_active || 'true',
                instagram_id: settings.hotel_instagram_id || '',
                instagram_active: settings.hotel_instagram_active || 'true'
            });
        });
    });
}

module.exports = { init, get, set, getAll, getReviewCode, setReviewCode, checkIpCooldown, setupRoutes };
