import express from 'express';
import bodyParser from 'body-parser';
import cors from 'cors';
import dotenv from 'dotenv';
import { expressSession, keycloak } from './keycloak.js';
import { dbConnect } from './database/mongo.js';
import {
  authRoutes,
  userRoutes,
  fileRoutes,
  printerRoutes,
  jobRoutes,
  subJobRoutes,
  gcodeFileRoutes,
  filamentRoutes,
  spotlightRoutes,
  partRoutes,
  productRoutes,
  vendorRoutes,
  materialRoutes,
  partStockRoutes,
  filamentStockRoutes,
  purchaseOrderRoutes,
  orderItemRoutes,
  shipmentRoutes,
  stockAuditRoutes,
  stockEventRoutes,
  auditLogRoutes,
  noteTypeRoutes,
  noteRoutes,
  hostRoutes,
  documentSizesRoutes,
  documentTemplatesRoutes,
  documentPrintersRoutes,
  documentJobsRoutes,
  courierRoutes,
  courierServiceRoutes,
  taxRateRoutes,
  taxRecordRoutes,
} from './routes/index.js';
import path from 'path';
import * as fs from 'fs';
import log4js from 'log4js';
import { populateUserMiddleware } from './services/misc/auth.js';
import { natsServer } from './database/nats.js';
import { initializeBuckets } from './services/storage/ceph.js';

dotenv.config();

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

const logger = log4js.getLogger('App');
logger.level = process.env.LOG_LEVEL;

app.use(log4js.connectLogger(logger, { level: 'trace' }));

const whitelist = [process.env.APP_URL_CLIENT, process.env.APP_URL_ELECTRON_CLIENT];
const corsOptions = {
  origin: function (origin, callback) {
    if (!origin || whitelist.indexOf(origin) !== -1) {
      callback(null, true);
    } else {
      callback(new Error('Not allowed by CORS'));
    }
  },
  credentials: true,
};

// Initialize application
async function initializeApp() {
  try {
    // Connect to database
    dbConnect();

    // Connect to NATS
    natsServer.connect();
    logger.info('Connected to NATS');

    // Initialize Ceph buckets
    try {
      await initializeBuckets();
      logger.info('Ceph buckets initialized successfully');
    } catch (err) {
      logger.error('Failed to initialize Ceph buckets:', err);
      // Don't throw error - allow app to start without Ceph for development
    }

    // Start server
    app.listen(PORT, () => logger.info(`Server listening to port ${PORT}`));
  } catch (err) {
    logger.error('Failed to initialize application:', err);
    process.exit(1);
  }
}

// Configure middleware
app.use(cors(corsOptions));
app.use(bodyParser.json({ type: 'application/json', strict: false, limit: '50mb' }));
app.use(express.json());
app.use(expressSession);
app.use(keycloak.middleware());
app.use(populateUserMiddleware);

app.get('/', function (req, res) {
  const __dirname = fs.realpathSync('.');
  res.sendFile(path.join(__dirname, '/src/landing/index.html'));
});

app.use('/auth', authRoutes);
app.use('/users', userRoutes);
app.use('/files', fileRoutes);
app.use('/spotlight', spotlightRoutes);
app.use('/printers', printerRoutes);
app.use('/hosts', hostRoutes);
app.use('/jobs', jobRoutes);
app.use('/subjobs', subJobRoutes);
app.use('/gcodefiles', gcodeFileRoutes);
app.use('/filaments', filamentRoutes);
app.use('/parts', partRoutes);
app.use('/products', productRoutes);
app.use('/vendors', vendorRoutes);
app.use('/materials', materialRoutes);
app.use('/partstocks', partStockRoutes);
app.use('/filamentstocks', filamentStockRoutes);
app.use('/purchaseorders', purchaseOrderRoutes);
app.use('/orderitems', orderItemRoutes);
app.use('/shipments', shipmentRoutes);
app.use('/stockevents', stockEventRoutes);
app.use('/stockaudits', stockAuditRoutes);
app.use('/auditlogs', auditLogRoutes);
app.use('/notetypes', noteTypeRoutes);
app.use('/documentsizes', documentSizesRoutes);
app.use('/documenttemplates', documentTemplatesRoutes);
app.use('/documentprinters', documentPrintersRoutes);
app.use('/documentjobs', documentJobsRoutes);
app.use('/couriers', courierRoutes);
app.use('/courierservices', courierServiceRoutes);
app.use('/taxrates', taxRateRoutes);
app.use('/taxrecords', taxRecordRoutes);
app.use('/notes', noteRoutes);

// Start the application
initializeApp();
