/**
 * More info about this file:
 * https://v2.quasar.dev/quasar-cli-vite/developing-ssr/ssr-webserver
 *
 * Runs in Node context.
 */

/**
 * Make sure to yarn add / npm install (in your project root)
 * anything you import here (except for express and compression).
 */
import dotenv from 'dotenv';
import express from 'express';
import compression from 'compression';
import session from 'express-session';
import { PrismaSessionStore } from '@quixo3/prisma-session-store';
import { PrismaClient } from '@prisma/client';
import { v4 as uuidv4 } from 'uuid';
import pino from 'pino';
import pinoHttp from 'pino-http';
import apiRoutes from './routes/api.js';
import authRoutes from './routes/auth.js';
import chatRoutes from './routes/chat.js';
import settingsRoutes from './routes/settings.js';
import userPreferencesRoutes from './routes/userPreferences.js';
import cron from 'node-cron';
import { generateAndStoreMantisSummary } from './services/mantisSummarizer.js';
import { requireAuth } from './middlewares/authMiddleware.js';

dotenv.config();

// Initialize Pino logger
const targets = [];

// Console logging (pretty-printed in development)
if (process.env.NODE_ENV !== 'production')
{
  targets.push({
    target: 'pino-pretty',
    options: {
      colorize: true
    },
    level: process.env.LOG_LEVEL || 'info'
  });
}
else
{
  // Basic console logging in production
  targets.push({
    target: 'pino/file', // Log to stdout in production
    options: { destination: 1 }, // 1 is stdout
    level: process.env.LOG_LEVEL || 'info'
  });
}

// Database logging via custom transport
targets.push({
  target: './utils/prisma-pino-transport.js', // Path to the custom transport
  options: {}, // No specific options needed for this transport
  level: process.env.DB_LOG_LEVEL || 'info' // Separate level for DB logging if needed
});

const logger = pino({
  level: process.env.LOG_LEVEL || 'info', // Overall minimum level
  transport: {
    targets: targets
  }
});

// Initialize pino-http middleware
const httpLogger = pinoHttp({ logger });

// Define Relying Party details (Update with your actual details)
export const rpID = process.env.NODE_ENV === 'production' ? 'stylepoint.uk' : 'localhost';
export const rpName = 'StylePoint';
export const origin = process.env.NODE_ENV === 'production' ? `https://${rpID}` : `http://${rpID}:9000`;

// In-memory store for challenges (Replace with a persistent store in production)
export const challengeStore = new Map();

const prisma = new PrismaClient();

const app = express();

// Add pino-http middleware
app.use(httpLogger);

if(!process.env.SESSION_SECRET)
{
  logger.error('SESSION_SECRET environment variable is not set. Please set it to a strong secret key.');
  process.exit(1); // Exit the process if the secret is not set
}

// Session middleware configuration
app.use(session({
  genid: (req) => uuidv4(), // Use UUIDs for session IDs
  secret: process.env.SESSION_SECRET, // Use an environment variable for the secret
  resave: false,
  saveUninitialized: false, // Changed to false as recommended for session stores
  store: new PrismaSessionStore( // Use PrismaSessionStore
    prisma,
    {
      checkPeriod: 2 * 60 * 1000,  //ms
      dbRecordIdIsSessionId: true,
      dbRecordIdFunction: undefined,
    }
  ),
  cookie: {
    secure: process.env.NODE_ENV === 'production', // Use secure cookies in production
    httpOnly: true,
    maxAge: 1000 * 60 * 60 * 24 // 1 day
  }
}));

// Schedule the Mantis summary task
// Run daily at 1:00 AM server time (adjust as needed)
cron.schedule('0 1 * * *', async() =>
{
  try
  {
    await generateAndStoreMantisSummary();
    logger.info('Scheduled Mantis summary task completed successfully.');
  }
  catch (error)
  {
    logger.error({ error }, 'Error running scheduled Mantis summary task');
  }
}, {
  scheduled: true,
  timezone: 'Europe/London' // Example: Set to your server's timezone
});

// attackers can use this header to detect apps running Express
// and then launch specifically-targeted attacks
app.disable('x-powered-by');

// Add JSON body parsing middleware
app.use(express.json());

// Add API routes
app.use('/api/auth', authRoutes);
app.use('/api/chat', requireAuth, chatRoutes);
app.use('/api/user-preferences', requireAuth, userPreferencesRoutes);
app.use('/api/settings', requireAuth, settingsRoutes);
app.use('/api', requireAuth, apiRoutes);

if (process.env.PROD)
{
  app.use(compression());
}

app.use(express.static('public', { index: false }));

app.listen(8000, () =>
{
  logger.info('Server is running on http://localhost:8000');
});