import { Head, asset } from "$fresh/runtime.ts";
import { HandlerContext, PageProps } from "$fresh/server.ts";
import { setCookie } from "http/cookie.ts";
import { Status } from "http/http_status.ts";
import { connectDB } from "../src/user/db.ts";
import { getUser, verifyUser } from "../src/user/user.ts";
import { create as createJWT } from "djwt";
import { prepareSecretKey } from "../util/secret.ts";
import LoginForm from "../islands/Login.tsx";

async function GET(_req: Request, ctx: HandlerContext) {
  return await ctx.render();
}

async function POST(req: Request, _ctx: HandlerContext): Promise<Response> {
  const url = new URL(req.url);
  const form = await req.formData();
  const username = form.get("username");
  const password = form.get("password");
  if (username && password) {
    const DB = await connectDB();
    const user = await getUser(DB, username.toString());
    if (user) {
      const SECRET_KEY = await prepareSecretKey();
      if (await verifyUser(user, password.toString())) {
        const headers = new Headers();
        const jwt = await createJWT({ alg: "HS512", typ: "JWT" }, {
          username: user.name,
        }, SECRET_KEY);
        setCookie(headers, {
          name: "auth",
          value: jwt,
          httpOnly: true,
          sameSite: "Strict",
          maxAge: 60 * 60 * 24 * 7,
          domain: url.hostname,
          path: "/",
          secure: url.protocol === "https:",
        });

        let redirect = "/";
        if (url.searchParams.has("redirect")) {
          redirect = url.searchParams.get("redirect")!;
        }
        headers.set("Location", redirect);
        return new Response(null, {
          status: Status.SeeOther, // See Other
          headers: headers,
        });
      }
    }
  }

  return new Response(
    `<!DOCTYPE html><html>
<head> <title> Login Failed </title> </head>
<body>
    <h1> Login Failed </h1>
    <p> <a href="/"> Back to Home </a> </p>
    <script>
        document.location.href = "/login?failed=true&redirect=${
      url.searchParams.get("redirect")
    }";
    </script>
</body>
</html>`,
    {
      headers: {
        "Content-Type": "text/html",
      },
      status: Status.Unauthorized,
    },
  );
}

export const handler = {
  GET,
  POST,
};

export default function Login(props: PageProps) {
  const redirect = props.url.searchParams.get("redirect");
  const failed = props.url.searchParams.get("failed") === "true";
  return (
    <>
      <Head>
        <title>Simple file server - Login</title>
        <link rel="stylesheet" href={asset("/base.css")} />
      </Head>
      <div class="">
        <LoginForm redirect={redirect ?? "/"} failed={failed} />
      </div>
    </>
  );
}
