'use strict';
// Custom session store backed by the same better-sqlite3 instance.
// Avoids pulling in a second SQLite driver (connect-sqlite3 / sqlite3).

const session = require('express-session');

const TTL_SECONDS = 8 * 60 * 60; // 8 hours — matches cookie maxAge

function createSessionStore(db) {
  class SQLiteStore extends session.Store {
    constructor() {
      super();
      // Purge expired sessions every 15 minutes
      setInterval(() => {
        db.prepare('DELETE FROM sessions WHERE expired < ?').run(Math.floor(Date.now() / 1000));
      }, 15 * 60 * 1000).unref();
    }

    get(sid, cb) {
      try {
        const row = db.prepare('SELECT sess, expired FROM sessions WHERE sid = ?').get(sid);
        if (!row) return cb(null, null);
        if (row.expired < Math.floor(Date.now() / 1000)) {
          db.prepare('DELETE FROM sessions WHERE sid = ?').run(sid);
          return cb(null, null);
        }
        cb(null, JSON.parse(row.sess));
      } catch (e) { cb(e); }
    }

    set(sid, sessionData, cb) {
      try {
        const ttl = sessionData.cookie?.maxAge
          ? Math.floor(sessionData.cookie.maxAge / 1000)
          : TTL_SECONDS;
        const expired = Math.floor(Date.now() / 1000) + ttl;
        db.prepare('INSERT OR REPLACE INTO sessions (sid, sess, expired) VALUES (?, ?, ?)')
          .run(sid, JSON.stringify(sessionData), expired);
        cb(null);
      } catch (e) { cb(e); }
    }

    destroy(sid, cb) {
      try {
        db.prepare('DELETE FROM sessions WHERE sid = ?').run(sid);
        cb(null);
      } catch (e) { cb(e); }
    }

    touch(sid, sessionData, cb) {
      try {
        const ttl = sessionData.cookie?.maxAge
          ? Math.floor(sessionData.cookie.maxAge / 1000)
          : TTL_SECONDS;
        const expired = Math.floor(Date.now() / 1000) + ttl;
        db.prepare('UPDATE sessions SET expired = ? WHERE sid = ?').run(expired, sid);
        cb(null);
      } catch (e) { cb(e); }
    }
  }

  return new SQLiteStore();
}

module.exports = { createSessionStore };
