import express from 'express';
import cors from 'cors';
import helmet from 'helmet';
import rateLimit from 'express-rate-limit';
import path from 'path';
import fs from 'fs';

import { extractUser } from './middleware/authMiddleware.js';

import projectRoutes from './routes/projectRoutes.js';
import partRoutes from './routes/partRoutes.js';
import paintingSchemeRoutes from './routes/paintingSchemeRoutes.js';
import applicationRecordRoutes from './routes/applicationRecordRoutes.js';
import inspectionRoutes from './routes/inspectionRoutes.js';
import analysisRoutes from './routes/analysisRoutes.js';
import dataSheetRoutes from './routes/dataSheetRoutes.js';
import yieldStudyRoutes from './routes/yieldStudyRoutes.js';
import userRoutes from './routes/userRoutes.js';
import systemSettingsRoutes from './routes/systemSettingsRoutes.js';
import geometryTypeRoutes from './routes/geometryTypeRoutes.js';
import stockRoutes from './routes/stockRoutes.js';
import notificationRoutes from './routes/notificationRoutes.js';
import instrumentRoutes from './routes/instrumentRoutes.js';
import messageRoutes from './routes/messageRoutes.js';
import backupRoutes from './routes/backupRoutes.js';

const app = express();

// Security Headers
app.use(helmet({
    contentSecurityPolicy: false, // Pode interferir com o React em dev se não configurado direito
    crossOriginEmbedderPolicy: false
}));

// Rate Limiter
const apiLimiter = rateLimit({
    windowMs: 15 * 60 * 1000, // 15 minutes
    max: 1000, // limit each IP to 1000 requests per windowMs
    message: 'Too many requests from this IP, please try again later.'
});

// Apply rate limiter only to API routes
app.use('/api', apiLimiter);

// CORS
const allowedOrigins = [
    'https://gpi.reifonas.cloud',
    'http://localhost:5173',
    'http://localhost:3000'
];

app.use(cors({
    origin: (origin, callback) => {
        if (!origin || allowedOrigins.includes(origin)) {
            callback(null, true);
        } else {
            callback(new Error('Not allowed by CORS'));
        }
    },
    methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
    allowedHeaders: ['Content-Type', 'Authorization', 'x-organization-id', 'x-organization-name']
}));

app.use(express.json({ limit: '5mb' }));
app.use(express.urlencoded({ limit: '5mb', extended: true }));

// Static Uploads
const uploadsPath = path.join(process.cwd(), 'uploads');
if (!fs.existsSync(uploadsPath)) {
    fs.mkdirSync(uploadsPath, { recursive: true });
}
app.use('/uploads', express.static(uploadsPath));

// Serve frontend static files
const distPath = path.join(process.cwd(), 'dist');
app.use(express.static(distPath));

// API Routes (all API routes pass through extractUser here, avoid duplication in route files)
const apiRouter = express.Router();
apiRouter.use(extractUser);

apiRouter.use('/users', userRoutes);
apiRouter.use('/projects', projectRoutes);
apiRouter.use('/parts', partRoutes);
apiRouter.use('/painting-schemes', paintingSchemeRoutes);
apiRouter.use('/application-records', applicationRecordRoutes);
apiRouter.use('/inspections', inspectionRoutes);
apiRouter.use('/', analysisRoutes);
apiRouter.use('/datasheets', dataSheetRoutes);
apiRouter.use('/yield-studies', yieldStudyRoutes);
apiRouter.use('/system-settings', systemSettingsRoutes);
apiRouter.use('/geometry-types', geometryTypeRoutes);
apiRouter.use('/stock', stockRoutes);
apiRouter.use('/notifications', notificationRoutes);
apiRouter.use('/instruments', instrumentRoutes);
apiRouter.use('/messages', messageRoutes);
apiRouter.use('/backup', backupRoutes);

app.use('/api', apiRouter);

app.get('/health', (req, res) => {
    res.json({ status: 'ok', timestamp: new Date(), auth: 'logto' });
});

// SPA fallback - must be last
app.use((req, res, next) => {
    if (req.path.startsWith('/api')) {
        return next(); // Do not return index.html for API 404s
    }
    res.sendFile(path.join(distPath, 'index.html'));
});

// Error handler
// eslint-disable-next-line @typescript-eslint/no-unused-vars
app.use((err: Error, req: express.Request, res: express.Response, _next: express.NextFunction) => {
    console.error('Express Error:', err);
    if (err.message === 'Not allowed by CORS') {
        return res.status(403).json({ error: 'CORS error' });
    }
    res.status(500).json({ error: 'Internal server error' });
});

export default app;
