import { Hono } from 'hono';
import type { Env } from './env';
import { requestLogger } from './middleware/logger';
import { sessionMiddleware } from './middleware/session';
import { csrfMiddleware, HttpError } from './middleware/csrf';
import { pages } from './routes/pages';
import { api } from './routes/api';
import { admin } from './routes/admin';
import { audit } from './db/queries';
import { nowSeconds } from './utils/time';

const app = new Hono<Env>();

app.use('*', requestLogger);
app.use('*', sessionMiddleware);
app.use('/api/*', csrfMiddleware);
app.use('/admin/api/*', csrfMiddleware);

app.route('/api', api);
app.route('/admin', admin);
app.route('/', pages);

app.notFound((c) => {
  if (c.req.path.startsWith('/api') || c.req.path.startsWith('/admin/api')) {
    return c.json({ success: false, message: '资源不存在', code: 'NOT_FOUND' }, 404);
  }
  return c.text('Not Found', 404);
});

app.onError(async (error, c) => {
  const status = 'status' in error && typeof error.status === 'number' ? error.status : 500;
  const code = 'code' in error && typeof error.code === 'string' ? error.code : status >= 500 ? 'INTERNAL_ERROR' : 'BAD_REQUEST';
  const message = error instanceof HttpError || status < 500 ? error.message : '服务器暂时不可用';

  if (status >= 500) {
    console.error(error);
    await audit(c.env.DB, {
      actorId: c.get('currentUser')?.id,
      action: 'error.500',
      target: c.req.path,
      detail: { message: error.message, requestId: c.get('requestId') },
      ip: c.req.header('cf-connecting-ip') || '',
      createdAt: nowSeconds()
    }).catch(() => undefined);
  }

  if (c.req.path.startsWith('/api') || c.req.path.startsWith('/admin/api')) {
    return c.json({ success: false, message, code }, status as never);
  }
  return c.text(message, status as never);
});

export default app;
