const path = require('path')
const fs = require('fs')
const dotenv = require('dotenv')
const express = require('express')
const cors = require('cors')
const session = require('express-session')
const FileStoreFactory = require('session-file-store')

dotenv.config({ path: path.join(__dirname, '..', '.env.production') })

const { ensureData } = require('./src/db')
const authRoutes = require('./src/routes/auth')
const topicsRoutes = require('./src/routes/topics')
const tierListsRoutes = require('./src/routes/tierlists')
const usersRoutes = require('./src/routes/users')
const adminRoutes = require('./src/routes/admin')
const shareRoutes = require('./src/routes/share')

const app = express()
const PORT = process.env.PORT ? Number(process.env.PORT) : 5179
const SESSION_SECRET = process.env.SESSION_SECRET || 'dev-secret-change-me'
const SESSION_COOKIE_SECURE = process.env.SESSION_COOKIE_SECURE === 'true'
const SESSION_COOKIE_SAME_SITE = process.env.SESSION_COOKIE_SAME_SITE || 'lax'
const TRUST_PROXY = process.env.TRUST_PROXY ? Number(process.env.TRUST_PROXY) : 1
const allowedOrigins = (process.env.CORS_ORIGINS || '')
  .split(',')
  .map((origin) => origin.trim())
  .filter(Boolean)

const FileStore = FileStoreFactory(session)

;['uploads/avatars', 'uploads/topics', 'uploads/custom', 'uploads/tierlists', '.sessions'].forEach((relativePath) => {
  fs.mkdirSync(path.join(__dirname, relativePath), { recursive: true })
})

app.set('trust proxy', TRUST_PROXY)
app.use(
  cors({
    origin: (origin, cb) => {
      if (!origin) return cb(null, true)
      if (allowedOrigins.includes(origin)) return cb(null, true)
      if (/^http:\/\/localhost:517\d$/.test(origin)) return cb(null, true) // 5170~5179
      if (/^https?:\/\/127\.0\.0\.1:517\d$/.test(origin)) return cb(null, true)
      if (origin === 'http://localhost:5173') return cb(null, true)
      cb(new Error('not_allowed_by_cors'))
    },
    credentials: true,
  })
)
app.use(express.json({ limit: '10mb' }))
app.use(express.urlencoded({ extended: true }))

app.use(
  session({
    store: new FileStore({
      path: path.join(__dirname, '.sessions'),
      ttl: 60 * 60 * 24 * 30,
      retries: 0,
    }),
    secret: SESSION_SECRET,
    proxy: TRUST_PROXY > 0,
    resave: false,
    saveUninitialized: false,
    cookie: {
      httpOnly: true,
      sameSite: SESSION_COOKIE_SAME_SITE,
      secure: SESSION_COOKIE_SECURE,
      maxAge: 1000 * 60 * 60 * 24 * 30,
    },
  })
)

app.use('/uploads', express.static(path.join(__dirname, 'uploads')))

app.get('/health', (req, res) => res.json({ ok: true }))

app.use(async (req, res, next) => {
  try {
    await ensureData()
    next()
  } catch (e) {
    console.error('[backend] db init failed', e)
    res.status(500).json({ error: 'db_init_failed' })
  }
})

app.use('/api/auth', authRoutes)
app.use('/api/topics', topicsRoutes)
app.use('/api/tierlists', tierListsRoutes)
app.use('/api/users', usersRoutes)
app.use('/api/admin', adminRoutes)
app.use('/share', shareRoutes)

app.listen(PORT, () => {
  console.log(`[backend] listening on http://localhost:${PORT}`)
})
