const express = require('express');
const axios = require('axios');
const app = express();
const PORT = process.env.PORT || 3000;

const NETSIDE_CALENDAR_URL = 'https://serv1.netside-planning.com/mb/peadpbaetb75b/79/dha2bu2wxmuewj7afeqh/en/nspl.ics';

function fixICSForHomeAssistant(icsContent) {
    let lines = icsContent.split(/\r?\n/);
    let fixed = [];
    let inTimezone = false;
    let timezoneMap = new Map();
    let currentTimezone = null;
    
    for (let i = 0; i < lines.length; i++) {
        let line = lines[i].trim();
        
        if (line === 'BEGIN:VTIMEZONE') {
            inTimezone = true;
            currentTimezone = { tzid: null, hasStandard: false, hasDaylight: false };
            continue;
        }
        
        if (line === 'END:VTIMEZONE') {
            inTimezone = false;
            if (currentTimezone && currentTimezone.tzid) {
                timezoneMap.set(currentTimezone.tzid, currentTimezone);
            }
            currentTimezone = null;
            continue;
        }
        
        if (inTimezone && currentTimezone) {
            if (line.startsWith('TZID:')) {
                currentTimezone.tzid = line.substring(5);
            } else if (line === 'BEGIN:STANDARD') {
                currentTimezone.hasStandard = true;
            } else if (line === 'BEGIN:DAYLIGHT') {
                currentTimezone.hasDaylight = true;
            }
        }
    }
    
    console.log(`Timezones détectées: ${Array.from(timezoneMap.keys()).join(', ')}`);
    
    const utcTimezone = [
        'BEGIN:VTIMEZONE',
        'TZID:UTC',
        'BEGIN:STANDARD',
        'DTSTART:19700101T000000',
        'TZOFFSETFROM:+0000',
        'TZOFFSETTO:+0000',
        'TZNAME:UTC',
        'END:STANDARD',
        'END:VTIMEZONE'
    ];
    
    inTimezone = false;
    let inCalendar = false;
    let hasValidTimezone = false;
    
    for (let i = 0; i < lines.length; i++) {
        let line = lines[i].trim();
        
        if (line === 'BEGIN:VCALENDAR') {
            inCalendar = true;
            fixed.push(line);
            continue;
        }
        
        if (inCalendar && !hasValidTimezone && (line.startsWith('VERSION:') || line.startsWith('PRODID:'))) {
            fixed.push(line);
            if (line.startsWith('PRODID:')) {
                fixed.push(...utcTimezone);
                hasValidTimezone = true;
            }
            continue;
        }
        
        if (line === 'BEGIN:VTIMEZONE') {
            inTimezone = true;
            continue;
        }
        
        if (line === 'END:VTIMEZONE') {
            inTimezone = false;
            continue;
        }
        
        if (inTimezone) {
            continue;
        }
        
        if (line.startsWith('DTSTART') || line.startsWith('DTEND')) {
            if (line.includes('TZID=')) {
                const tzidMatch = line.match(/TZID=([^;:]+)/);
                if (tzidMatch) {
                    const originalTzid = tzidMatch[1];
                    line = line.replace(/;TZID=[^;:]+/, '');
                    console.log(`Supprimé TZID ${originalTzid} pour événement multi-jours`);
                }
            }
            
            const dateValueMatch = line.match(/:(\d{8})(?:T(\d{6})Z?)?$/);
            if (dateValueMatch) {
                const dateOnly = dateValueMatch[1];
                const timeOnly = dateValueMatch[2];
                
                if (timeOnly) {
                    if (!line.endsWith('Z')) {
                        line = line.replace(/:(\d{8}T\d{6})$/, ':$1Z');
                    }
                } else {
                    line = line.replace(/:(\d{8})$/, ';VALUE=DATE:$1');
                }
            }
        }

        if (line.includes('TZID=')) {
            const tzidMatch = line.match(/TZID=([^;:]+)/);
            if (tzidMatch) {
                const originalTzid = tzidMatch[1];
                
                if (line.includes('DTSTART') || line.includes('DTEND') || line.includes('DTSTAMP')) {
                    line = line.replace(/TZID=[^;:]+/, 'TZID=UTC');
                    
                    const valueMatch = line.match(/:(\d{8})$/);
                    if (valueMatch) {
                        line = line.replace(/:(\d{8})$/, ':$1T000000Z');
                        line = line.replace(/;TZID=UTC/, '');
                    }
                } else {
                    line = line.replace(/;TZID=[^;:]+/, '');
                }
                
                console.log(`Normalisé timezone ${originalTzid} vers UTC`);
            }
        }
        
        if ((line.startsWith('DTSTART:') || line.startsWith('DTEND:') || line.startsWith('DTSTAMP:')) 
            && line.match(/:\d{8}T\d{6}$/) && !line.endsWith('Z')) {
            line = line + 'Z';
        }
        
        if (line.startsWith('TZID:') && !inTimezone) {
            continue;
        }
        
        if (line === '') {
            continue;
        }
        
        if (line.startsWith('RRULE:')) {
            line = line.replace(/;+/g, ';').replace(/;$/, '');
        }
        
        line = line.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, '');
        
        fixed.push(line);
    }
    
    const result = fixed.join('\n');
    
    if (!result.includes('BEGIN:VCALENDAR')) {
        console.warn('VCALENDAR manquant, ajout...');
        return 'BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//ICS-Gateway//Gateway//EN\n' + 
               utcTimezone.join('\n') + '\n' + result + '\nEND:VCALENDAR';
    }
    
    if (!result.includes('END:VCALENDAR')) {
        console.warn('END:VCALENDAR manquant, ajout...');
        return result + '\nEND:VCALENDAR';
    }
    
    console.log('ICS normalisé avec succès');
    return result;
}

app.get('/calendar.ics', async (req, res) => {
    try {
        console.log('Récupération du calendrier depuis Netside...');
        
        const response = await axios.get(NETSIDE_CALENDAR_URL, {
            timeout: 10000,
            headers: {
                'User-Agent': 'HomeAssistant-Gateway/1.0'
            }
        });
        
        console.log('Calendrier récupéré, correction en cours...');
        
        const fixedICS = fixICSForHomeAssistant(response.data);
        
        res.set({
            'Content-Type': 'text/calendar; charset=utf-8',
            'Content-Disposition': 'inline; filename=calendar.ics',
            'Cache-Control': 'no-cache, no-store, must-revalidate',
            'Pragma': 'no-cache',
            'Expires': '0'
        });
        
        res.send(fixedICS);
        console.log('Calendrier corrigé envoyé avec succès');
        
    } catch (error) {
        console.error('Erreur lors de la récupération du calendrier:', error.message);
        res.status(500).json({ 
            error: 'Impossible de récupérer le calendrier',
            details: error.message 
        });
    }
});

app.get('/health', (req, res) => {
    res.json({ 
        status: 'OK', 
        service: 'ICS Gateway for Home Assistant',
        timestamp: new Date().toISOString()
    });
});

app.get('/debug/original', async (req, res) => {
    try {
        const response = await axios.get(NETSIDE_CALENDAR_URL);
        res.set('Content-Type', 'text/plain');
        res.send(response.data);
    } catch (error) {
        res.status(500).json({ error: error.message });
    }
});

app.listen(PORT, () => {
    console.log(`🚀 Serveur ICS Gateway démarré sur le port ${PORT}`);
    console.log(`📅 Calendrier disponible sur: http://localhost:${PORT}/calendar.ics`);
    console.log(`🔍 Health check: http://localhost:${PORT}/health`);
    console.log(`🐛 Debug (original): http://localhost:${PORT}/debug/original`);
});