import express from 'express';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { createWikiAuth } from './wiki-auth.mjs';
import { PUBLISH_ROOT_DIR } from './user-publish.mjs';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const PORT = Number(process.env.WIKI_PORT ?? 3000);
const app = express();

app.set('trust proxy', 1);
const auth = createWikiAuth(path.join(__dirname, PUBLISH_ROOT_DIR, 'wiki-db'));
const jsonBody = express.json({ limit: '1mb' });

function parseCookies(header = '') {
  return Object.fromEntries(
    header.split(';').map(p => p.trim()).filter(Boolean).map(p => {
      const idx = p.indexOf('=');
      return idx < 0 ? [p, ''] : [decodeURIComponent(p.slice(0, idx)), decodeURIComponent(p.slice(idx + 1))];
    }),
  );
}

function requireAuth(req, res, next) {
  const cookies = parseCookies(req.get('cookie'));
  const token = cookies[auth.COOKIE_NAME];
  const session = auth.verify(token);
  if (!session) {
    return res.status(401).json({ message: '未登录' });
  }
  req.user = session;
  next();
}

// ============ Auth Routes ============

app.post('/api/auth/register', jsonBody, (req, res) => {
  const { username, password, displayName } = req.body || {};
  if (!username || !password) {
    return res.status(400).json({ message: '用户名和密码不能为空' });
  }
  if (username.length < 2 || username.length > 20) {
    return res.status(400).json({ message: '用户名长度2-20个字符' });
  }
  if (password.length < 4) {
    return res.status(400).json({ message: '密码至少4个字符' });
  }
  const result = auth.register(username, password, displayName);
  if (!result.ok) {
    return res.status(409).json({ message: result.message });
  }
  res.json({ ok: true, user: result.user });
});

app.post('/api/auth/login', jsonBody, (req, res) => {
  const { username, password } = req.body || {};
  if (!username || !password) {
    return res.status(400).json({ message: '用户名和密码不能为空' });
  }
  const result = auth.login(username, password);
  if (!result.ok) {
    return res.status(401).json({ message: result.message });
  }
  const isSecure = req.secure || req.get('x-forwarded-proto')?.split(',')[0]?.trim() === 'https';
  res.set('Set-Cookie', `${auth.COOKIE_NAME}=${encodeURIComponent(result.token)}; Path=/; HttpOnly; SameSite=Lax; Max-Age=604800${isSecure ? '; Secure' : ''}`);
  res.json({ ok: true, user: result.user });
});

app.post('/api/auth/logout', (req, res) => {
  const cookies = parseCookies(req.get('cookie'));
  auth.revoke(cookies[auth.COOKIE_NAME]);
  const isSecure = req.secure || req.get('x-forwarded-proto')?.split(',')[0]?.trim() === 'https';
  res.set('Set-Cookie', `${auth.COOKIE_NAME}=; Path=/; HttpOnly; SameSite=Lax; Max-Age=0${isSecure ? '; Secure' : ''}`);
  res.json({ ok: true });
});

app.get('/api/auth/me', (req, res) => {
  const cookies = parseCookies(req.get('cookie'));
  const session = auth.verify(cookies[auth.COOKIE_NAME]);
  if (!session) return res.json({ authenticated: false });
  const user = auth.getUser(session.username);
  res.json({ authenticated: true, user });
});

// ============ Page Routes ============

app.get('/api/pages', requireAuth, (req, res) => {
  const { q } = req.query;
  if (q) {
    return res.json(auth.searchPages(req.user.username, q));
  }
  res.json(auth.listPages(req.user.username));
});

app.get('/api/pages/:slug', requireAuth, (req, res) => {
  const page = auth.getPage(req.user.username, req.params.slug);
  if (!page) return res.status(404).json({ message: '页面不存在' });
  res.json(page);
});

app.post('/api/pages/:slug', requireAuth, jsonBody, (req, res) => {
  const { title, content, tags } = req.body || {};
  const slug = req.params.slug;
  const page = auth.savePage(req.user.username, slug, title, content, tags);
  res.json(page);
});

app.delete('/api/pages/:slug', requireAuth, (req, res) => {
  auth.deletePage(req.user.username, req.params.slug);
  res.json({ ok: true });
});

// ============ Static Files ============

app.use('/wiki', express.static(path.join(__dirname, PUBLISH_ROOT_DIR, 'wiki')));
app.get('/wiki/*', (req, res) => {
  res.sendFile(path.join(__dirname, PUBLISH_ROOT_DIR, 'wiki', 'index.html'));
});

app.listen(PORT, '0.0.0.0', () => {
  console.log(`📚 Wiki系统运行中 @ http://0.0.0.0:${PORT}/wiki`);
  console.log(`   数据目录: ${path.join(__dirname, PUBLISH_ROOT_DIR, 'wiki-db')}`);
});
