import { createMiddleware } from "hono/factory";
import { verify } from "hono/jwt";
import { apiError } from "../lib/errors";
import type { AppEnv, SiteRow } from "../types";

export const siteAuth = createMiddleware<AppEnv>(async (c, next) => {
  const header = c.req.header("authorization");
  if (!header || !header.startsWith("Bearer ")) {
    return apiError(c, 401, "unauthorized", "Missing bearer token");
  }

  let payload: { sub?: unknown; ver?: unknown };
  try {
    payload = (await verify(header.slice(7), c.env.JWT_SECRET, "HS256")) as {
      sub?: unknown;
      ver?: unknown;
    };
  } catch {
    return apiError(c, 401, "unauthorized", "Invalid or expired token");
  }
  if (typeof payload.sub !== "string" || typeof payload.ver !== "number") {
    return apiError(c, 401, "unauthorized", "Invalid token claims");
  }

  const site = await c.env.DB.prepare(
    "SELECT id, license_key, site_url, bucket_id, token_version, storage_bytes_used FROM sites WHERE id = ?",
  )
    .bind(payload.sub)
    .first<SiteRow>();
  if (!site || site.token_version !== payload.ver) {
    return apiError(c, 401, "unauthorized", "Token has been rotated");
  }

  c.set("site", site);
  await next();
});
