import { LayoutProps, MiddlewareHandlerContext } from "$fresh/server.ts";
import { deleteCookie, getCookies } from "$std/http/cookie.ts";
import { getUserFromNonExpiredLoginToken } from "@/db/mod.ts";
import { type ContextState, type PublicUser, type User } from "@/types.ts";
import { log } from "@/log.ts";

function toPublicUser(user: User): PublicUser {
  const {
    createdAt: _createdAt,
    updatedAt: _updatedAt,
    passwordDigest: _passwordDigest,
    ...publicUser
  } = user;
  return publicUser;
}

function Layout({ state, Component }: LayoutProps<ContextState>) {
  return (
    <>
      {state.something
        ? <p>Oh my! You said something!</p>
        : <p>You aren't saying anything.</p>}
      <Component />
    </>
  );
}

async function currentUser(
  request: Request,
  context: MiddlewareHandlerContext<ContextState>,
) {
  context.layout = Layout;
  let hasBadAuthCookie = false;
  const { lsauth } = getCookies(request.headers);
  log.debug("lsauth cookie:", lsauth);
  if (lsauth) {
    const user = await getUserFromNonExpiredLoginToken(lsauth);
    if (!user) hasBadAuthCookie = true;
    else {
      context.state.user = toPublicUser(user);
    }
  }
  const resp = await context.next();
  if (resp) {
    if (hasBadAuthCookie) deleteCookie(resp.headers, "lsauth");
  }
  return resp;
}

export async function serverHeader(
  _request: Request,
  context: MiddlewareHandlerContext<ContextState>,
) {
  const resp = await context.next();
  if (resp) {
    resp.headers.set("server", "fresh server");
  }
  return resp;
}

export async function someState(
  _request: Request,
  context: MiddlewareHandlerContext<ContextState>,
) {
  context.state.something = "I said something!";
  return await context.next();
}

export const handler = [
  someState,
  currentUser,
  serverHeader,
];
