require('dotenv').config();
const express = require('express');
const helmet = require('helmet');
const cookieParser = require('cookie-parser');
const session = require('express-session');
const cors = require('cors');
var path = require('path');
const sequelize = require('./config/db.js');
const testConnection = sequelize.testConnection;

const myApp = express();
const port = 5000;

const authRouter = require('./routes/authentication.js');
const bankRouter = require('./routes/bank.js');
const branchRouter = require('./routes/branch.js');
const accountRouter = require('./routes/account.js');
const entityRouter = require('./routes/entity.js');
const pentityRouter = require('./routes/p_entity.js');
const billableRouter = require('./routes/billable.js'); 
const taxRouter = require('./routes/tax.js');
const invTempRouter = require('./routes/inv_temp.js');
const invoiceRouter = require('./routes/invoice.js');
const changeLogRouter = require('./routes/change_logs.js');
const userRouter = require('./routes/user.js');
const entityHeaderRouter = require('./routes/entity_header.js');

myApp.use(helmet());
myApp.use(express.static(__dirname+'/htdocs'));
myApp.use(express.json());
myApp.use(express.urlencoded({extended: true}));
myApp.use(cookieParser());

var corsOptions = {
    credentials: true,     
    AccessControlAllowOrigin: true,  
    origin: ['http://10.20.40.105:8080'],  
    methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
    optionsSuccessStatus: 200 
}

myApp.use(session(    
    { 
        secret: process.env.SESSION_SECRET || (() => { throw new Error('SESSION_SECRET env variable is not set'); })(),
        resave: false,  
        saveUninitialized: false,
        cookie: {
            secure: process.env.NODE_ENV === 'production',
            maxAge: 600000,
            httpOnly: true,
            sameSite: 'lax'
        },
        unset: 'destroy',
        name: 'sessionId',
        exposedHeaders: ['Set-Cookie']
    }
)); 

myApp.use(cors(corsOptions));
myApp.options('*', cors(corsOptions));

myApp.set('views', path.join(__dirname, 'views'));
myApp.set('view engine', 'ejs');

myApp.use(express.static('frontend'));

myApp.use("/authentication", authRouter)

myApp.use("/bank", bankRouter);

myApp.use("/branch", branchRouter);

myApp.use("/bankaccount", accountRouter);

myApp.use("/entity", entityRouter);

myApp.use("/pentity", pentityRouter);

myApp.use("/billable", billableRouter);

myApp.use("/tax", taxRouter);

myApp.use("/invtemp", invTempRouter);

myApp.use("/invoice", invoiceRouter);

myApp.use("/changelog", changeLogRouter);

myApp.use("/user", userRouter);

myApp.use("/entityheader", entityHeaderRouter);

myApp.get('/test', (req, res) => {
    res.send("test Okay");
});

myApp.get('/', (req, res) => {
    res.redirect('/frontend/')
});

let server = null;

const startServer = async () => {
    try {
        await testConnection();
        server = myApp.listen(
            port,
            () => {
                console.log(`The server is running on http://localhost:${port}`);
            }
        );
    } catch (err) {
        console.error('Server startup aborted due to DB connection error.');
        process.exit(1);
    }
};

const shutdown = async (signal) => {
    console.log(`${signal} signal received: closing HTTP server`);

    if (server) {
        await new Promise((resolve) => {
            server.close(() => {
                console.log('HTTP server closed');
                resolve();
            });
        });
    }

    try {
        await sequelize.close();
        console.log('Database pool closed');
    } catch (err) {
        console.error('Error while closing database pool', err);
    }
};

process.on('SIGTERM', async () => {
    await shutdown('SIGTERM');
    process.exit(0);
});

process.on('SIGINT', async () => {
    await shutdown('SIGINT');
    process.exit(0);
});

startServer();