const express = require('express');
const parser = require('cookie-parser');
const jwt = require('jsonwebtoken');

const app = express();
const PORT = process.env.PORT;

const version = process.env.VERSION;
const vBuild = process.env.VERSION_BUILD;
const vState = process.env.VERSION_STATE;

app.use(express.json());
app.use(parser());

// CORS per permettere chiamate cross-origin dalla console
app.use((req, res, next) => {
    const origin = req.headers.origin;
    const allowed = (process.env.CORS_ORIGINS || '').split(',').map(s => s.trim()).filter(Boolean);
    // Accetta origini nella whitelist, oppure tutte in dev
    if (allowed.length === 0 || allowed.includes(origin)) {
        res.setHeader('Access-Control-Allow-Origin', origin || '*');
    }
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS');
    res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, x-api-key');
    res.setHeader('Access-Control-Allow-Credentials', 'true');
    if (req.method === 'OPTIONS') return res.sendStatus(204);
    next();
});

app.get('/', (req, res) => {
    res.redirect('/health');
});

app.get('/health', async (req, res) => {
    const postgres = await require('./storage/postgres').checkPostgres();
    const influx = await require('./storage/influx').checkInflux();
    const minio = await require('./storage/minio').checkMinio();

    const allOk = Object.values(postgres).every(s => s === 'connected') && influx && minio;

    console.log("Health check results:", { postgres, influx: influx ? 'connected' : 'disconnected', minio: minio ? 'connected' : 'disconnected' });

    res.json({ 
        status: allOk ? "ok" : "degraded",
        service: "api",
        databases: postgres,
        influx: influx ? 'connected' : 'disconnected',
        minio: minio ? 'connected' : 'disconnected',
        version: version,
        build_number: vBuild,
        version_state: vState
    });
});

// Route pubblica: autenticazione tramite SENSOR_CODE (per il plugin)
const paramsSensorRoutes = require('./routes/params.sensor');
app.use('/params/sensor', paramsSensorRoutes);

// Middleware di autenticazione per le API
app.use((req, res, next) => {
    if (req.path === '/health' || req.path === '/') return next();

    // 1. Service-to-service: x-api-key header
    const apiKey = req.headers['x-api-key'];
    if (apiKey && apiKey === process.env.INTERNAL_API_KEY) {
        req.internal = true;
        return next();
    }

    // 2. User auth: cookie o Authorization header
    const token = req.cookies?.auth_token
        || (req.headers.authorization?.startsWith('Bearer ') && req.headers.authorization.slice(7));

    if (!token) {
        return res.status(401).json({ error: 'Unauthorized: Nessun token di autenticazione fornito' });
    }

    try {
        const payload = jwt.verify(token, process.env.JWT_SECRET, { algorithms: ['HS256'] });
        req.user = payload;
        next();
    } catch (err) {
        return res.status(401).json({ error: 'Unauthorized: Token non valido o scaduto' });
    }
});

const dataRoutes = require('./routes/data');
app.use('/data', dataRoutes);

const storageRoutes = require('./routes/storage')
app.use('/storage', storageRoutes)

const paramsRoutes = require('./routes/params')
app.use('/params', paramsRoutes)

const settingsRoutes = require('./routes/settings')
app.use('/settings', settingsRoutes)

const sessionsRoutes = require('./routes/sessions')
app.use('/sessions', sessionsRoutes)

app.listen(PORT, '0.0.0.0', () => {
    console.log(`Started on port ${PORT}`);
});
