import express from 'express';
import { readFileSync, existsSync } from 'fs';
import { resolve, dirname } from 'path';
import { fileURLToPath } from 'url';
import type { WordBank } from '@wordle/shared';
import type { CachedResult } from '@wordle/shared';
import { createDailyRouter } from './routes/daily.js';
import { createGuessRouter } from './routes/guess.js';
import { createPlayAgainRouter } from './routes/play-again.js';
import { createValidateRouter } from './routes/validate.js';

const __dirname = dirname(fileURLToPath(import.meta.url));

function loadBank(filename: string): WordBank {
  const path = resolve(__dirname, '../../data', filename);
  return JSON.parse(readFileSync(path, 'utf-8'));
}

// Lazy cache — empty at startup, populated on first API hit for each word.
// Background computation upgrades entries from 3-solver to full 4-solver results.
function createCache(): Map<number, CachedResult> {
  return new Map();
}

function mountApi(prefix: string, bank: WordBank, cache: Map<number, CachedResult>) {
  return [
    [prefix + '/daily', createDailyRouter(bank, cache)],
    [prefix + '/validate', createValidateRouter(bank)],
    [prefix + '/guess', createGuessRouter(bank, cache)],
    [prefix + '/play-again', createPlayAgainRouter(bank, cache)],
  ] as const;
}

const enBank = loadBank('word-bank.json');
const ruBank = loadBank('word-bank-ru.json');

const enCache = createCache();
const ruCache = createCache();

const app = express();
app.use(express.json());

// Mount API routes for both languages
for (const [path, router] of [
  ...mountApi('/api', enBank, enCache),
  ...mountApi('/ru/api', ruBank, ruCache),
]) {
  app.use(path, router);
}

// Serve SPA
const clientDist = (() => {
  if (process.env.STATIC_DIR) return resolve(process.env.STATIC_DIR);
  const devPath = resolve(__dirname, '../../client/dist');
  return existsSync(devPath) ? devPath : resolve(__dirname, '../../client');
})();
app.use(express.static(clientDist));
app.get('/{*path}', (_req, res) => {
  res.sendFile(resolve(clientDist, 'index.html'));
});

const PORT = process.env.PORT ? parseInt(process.env.PORT) : 3000;
app.listen(PORT, () => {
  console.log(`Server listening on port ${PORT} (EN + RU)`);
});

export default app;
