// Zależności
import express, { NextFunction, Request, Response } from 'express'
import path from 'path'
import cookieParser from 'cookie-parser'
import cors from 'cors'
import session from 'express-session'

// Element pośredniczący
import { isConnected } from './lib/middlewares/user'

// Konfiguracja
import config from './config'

// Aplikacja serwera Express
const app = express();
const port = process.env.NODE_PORT || 3000
const DIST_DIR = path.join(__dirname, '../dist')
const HTML_FILE = path.join(DIST_DIR, 'index.html')

// Ustanawianie katalogu dystrybucji katalogiem statycznym
app.use(express.static(DIST_DIR));

// Elementy pośredniczące
app.use(
  session({
    resave: false,
    saveUninitialized: true,
    secret: config.security.secretKey
  })
)
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser(config.security.secretKey))
app.use(cors({ credentials: true, origin: true }))

// Ścieżki
app.get('/dashboard',
  isConnected(
    true,
    ['god', 'admin'], // Są to uprawnienia zapewniające dostęp
    `/login?redirectTo=/dashboard`
  ),
  (req: Request, res: Response, next: NextFunction) => {
    // Jeśli dla użytkownika atrybut isConnected ma wartość true, uzyska dostęp do strony panelu kontrolnego. W przeciwnym razie zostanie on przekierowany do ścieżki /login
    next()
  }
)

// Wymuszanie dostępu do ścieżki /login tylko w wypadku niepołączonych użytkowników
// Jeśli użytkownik, który nawiązał połączenie, próbuje uzyskać dostęp, zostanie przekierowany na stronę główną
app.get('/login', isConnected(false), (req: Request, res: Response, next: NextFunction) => {
  next()
})

app.get(`/logout`, (req: Request, res: Response) => {
  // Spowoduje wyczyszczenie informacji cookie tokenu at i przekierowanie do strony głównej
  res.clearCookie('at')
  res.redirect('/')
})

app.get('*', (req: Request, res: Response) => {
  // Renderowanie aplikacji React
  res.sendFile(HTML_FILE)
})

// Nasłuchiwanie
app.listen(port, () => console.log(`Działa pod adresem http://localhost:${port}`))
