import type { MiddlewareHandler } from 'hono';
import { getCookie } from 'hono/cookie';
import type { Env } from '../env';
import { CSRF_COOKIE } from './session';

const WRITE_METHODS = new Set(['POST', 'PUT', 'PATCH', 'DELETE']);

export class HttpError extends Error {
  status: number;
  code: string;

  constructor(message: string, status = 400, code = 'BAD_REQUEST') {
    super(message);
    this.status = status;
    this.code = code;
  }
}

export const csrfMiddleware: MiddlewareHandler<Env> = async (c, next) => {
  if (!WRITE_METHODS.has(c.req.method)) {
    await next();
    return;
  }
  const cookieToken = getCookie(c, CSRF_COOKIE);
  const headerToken = c.req.header('X-CSRF-Token');
  if (!cookieToken || !headerToken || cookieToken !== headerToken) {
    throw new HttpError('CSRF token 无效或缺失', 403, 'CSRF_INVALID');
  }
  await next();
};
