const axios = require('axios');
const { pool } = require('../db');
const cron = require('node-cron');

class ExchangeRateCronService {
    constructor() {
        this.pdfUrl = 'https://www.backend-rates.bazg.admin.ch/pdf?activeSearchType=yesterday&locale=fr';
        this.cronSchedule = '0 2 * * 1-5'; // Lundi à vendredi à 2h00
    }

    /**
     * Parse le PDF des taux de change et extrait les données
     */
    async fetchAndParseRates() {
        try {
            console.log('[EXCHANGE-CRON] Début récupération des taux de change...');
            
            // Télécharger le PDF
            const response = await axios.get(this.pdfUrl, {
                responseType: 'arraybuffer',
                timeout: 30000
            });

            const pdfBuffer = Buffer.from(response.data);
            console.log('[EXCHANGE-CRON] PDF téléchargé, taille:', pdfBuffer.length, 'bytes');

            // Parser le PDF avec pdf-parse
            const pdfParse = require('pdf-parse');
            const pdfData = await pdfParse(pdfBuffer);
            const text = pdfData.text;

            console.log('[EXCHANGE-CRON] PDF parsé, extraction des taux...');

            // Extraction des taux via regex
            // Format attendu: "EUR 1.0458" ou "USD 0.9123" etc.
            const rateRegex = /([A-Z]{3})\s+([\d.]+)/g;
            const rates = [];
            let match;

            while ((match = rateRegex.exec(text)) !== null) {
                const currency = match[1];
                const rate = parseFloat(match[2]);
                
                // Filtrer les faux positifs (codes qui ne sont pas des devises)
                if (rate > 0 && rate < 1000 && currency.length === 3) {
                    rates.push({ currency, rate });
                }
            }

            console.log(`[EXCHANGE-CRON] ${rates.length} taux extraits`);

            if (rates.length === 0) {
                throw new Error('Aucun taux de change extrait du PDF');
            }

            // Sauvegarder en base de données
            await this.saveRatesToDatabase(rates);

            console.log('[EXCHANGE-CRON] ✓ Mise à jour des taux terminée avec succès');
            return rates;

        } catch (error) {
            console.error('[EXCHANGE-CRON] Erreur:', error);
            throw error;
        }
    }

    /**
     * Sauvegarde les taux en base de données (UPDATE ou INSERT)
     */
    async saveRatesToDatabase(rates) {
        const conn = await pool.getConnection();
        try {
            await conn.beginTransaction();

            for (const { currency, rate } of rates) {
                // UPDATE si existe, sinon INSERT
                await conn.execute(`
                    INSERT INTO daily_exchange_rates (currency_code, rate_to_chf, rate_date)
                    VALUES (?, ?, CURDATE())
                    ON DUPLICATE KEY UPDATE 
                        rate_to_chf = VALUES(rate_to_chf),
                        rate_date = VALUES(rate_date)
                `, [currency, rate]);
            }

            await conn.commit();
            console.log(`[EXCHANGE-CRON] ${rates.length} taux sauvegardés en BDD`);

        } catch (error) {
            await conn.rollback();
            console.error('[EXCHANGE-CRON] Erreur sauvegarde BDD:', error);
            throw error;
        } finally {
            conn.release();
        }
    }

    /**
     * Démarre le CRON job
     */
    start() {
        console.log('[EXCHANGE-CRON] Démarrage du CRON (lun-ven à 2h00)');
        
        cron.schedule(this.cronSchedule, async () => {
            console.log('[EXCHANGE-CRON] Déclenchement du CRON');
            try {
                await this.fetchAndParseRates();
            } catch (error) {
                console.error('[EXCHANGE-CRON] Échec du CRON:', error.message);
            }
        });

        // Exécution immédiate au démarrage (optionnel, commentez si non souhaité)
        // this.fetchAndParseRates().catch(err => console.error('[EXCHANGE-CRON] Erreur init:', err));
    }
}

module.exports = new ExchangeRateCronService();