const { getClientToken } = require('./graph.service');
const Database = require('better-sqlite3');
const path = require('path');
const fs = require('fs');

const DB_PATH = process.env.DATABASE_PATH || './database.sqlite';

async function syncEntraProfiles() {
    const db = new Database(DB_PATH);
    const startedAt = new Date().toISOString();

    // Log starten
    const logId = db.prepare(`
        INSERT INTO cron_logs (job_name, started_at, status) VALUES (?, ?, 'running')
    `).run('entra_profile_sync', startedAt).lastInsertRowid;

    try {
        const token = await getClientToken();
        const users = db.prepare(`SELECT id, azure_id, username FROM users WHERE azure_id IS NOT NULL AND azure_id != ''`).all();

        let synced = 0, errors = 0, photos = 0;

        for (const user of users) {
            try {
                // Profildaten holen
                const profileRes = await fetch(
                    `https://graph.microsoft.com/v1.0/users/${user.azure_id}?$select=jobTitle,department,mobilePhone,businessPhones,officeLocation,employeeHireDate,displayName,mail,givenName,surname`,
                    { headers: { Authorization: `Bearer ${token}` } }
                );

                if (profileRes.ok) {
                    const p = await profileRes.json();
                    const phone = p.mobilePhone || (p.businessPhones?.[0]) || null;

                    db.prepare(`
                        UPDATE users SET
                            position = COALESCE(?, position),
                            department = COALESCE(?, department),
                            phone = COALESCE(?, phone),
                            location = COALESCE(?, location),
                            joined_date = COALESCE(?, joined_date),
                            first_name = COALESCE(?, first_name),
                            last_name = COALESCE(?, last_name)
                        WHERE id = ?
                    `).run(
                        p.jobTitle || null,
                        p.department || null,
                        phone,
                        p.officeLocation || null,
                        p.employeeHireDate ? p.employeeHireDate.split('T')[0] : null,
                        p.givenName || null,
                        p.surname || null,
                        user.id
                    );
                    synced++;
                }

                // Foto holen
                const photoRes = await fetch(
                    `https://graph.microsoft.com/v1.0/users/${user.azure_id}/photo/$value`,
                    { headers: { Authorization: `Bearer ${token}` } }
                );

                if (photoRes.ok) {
                    const avatarDir = path.join(process.env.UPLOAD_PATH || path.join(__dirname, '../../uploads'), 'avatars');
                    if (!fs.existsSync(avatarDir)) fs.mkdirSync(avatarDir, { recursive: true });

                    const buffer = Buffer.from(await photoRes.arrayBuffer());
                    const filename = `${user.azure_id}.jpg`;
                    fs.writeFileSync(path.join(avatarDir, filename), buffer);

                    db.prepare(`UPDATE users SET avatar_url = ? WHERE id = ?`)
                        .run(`/uploads/avatars/${filename}`, user.id);
                    photos++;
                }

            } catch (err) {
                console.error(`[Entra Sync] Fehler bei User ${user.username}:`, err.message);
                errors++;
            }
        }

        const message = `${synced} Profile synchronisiert, ${photos} Fotos gespeichert, ${errors} Fehler`;
        db.prepare(`UPDATE cron_logs SET status='success', finished_at=?, message=?, details=? WHERE id=?`)
            .run(new Date().toISOString(), message, JSON.stringify({ synced, photos, errors, total: users.length }), logId);

        console.log(`[Entra Sync] ${message}`);
        return { synced, photos, errors };

    } catch (err) {
        db.prepare(`UPDATE cron_logs SET status='error', finished_at=?, message=? WHERE id=?`)
            .run(new Date().toISOString(), err.message, logId);
        throw err;
    } finally {
        db.close();
    }
}

module.exports = { syncEntraProfiles };
