import { HandlerContext, Handlers, PageProps } from "$fresh/server.ts";
import { compare } from "https://deno.land/x/bcrypt@v0.4.1/mod.ts";
import { Page } from "@/components/Page.tsx";
import { query } from "@/db/mod.ts";

type UserID = string;

interface LoginError {
  message: string;
}

async function invalidLogin<LoginError>(context: HandlerContext<LoginError>) {
  return await context.render({ message: "Invalid login" } as LoginError);
}

export const handler: Handlers<UserID | LoginError | null> = {
  async POST(request: Request, context) {
    const formData = (await request.formData());
    const username = formData.get("username");
    const password = formData.get("password");
    if (!username) {
      return await context.render({ message: "no username provided" });
    }
    if (!password) {
      return await context.render({ message: "no password provided" });
    }

    const result = await query<
      { id: string; username: string; password_digest: string }
    >(
      `select * from "user" where username = $1`,
      [username],
    );
    if (result == null || result.rows.length < 1) {
      return await invalidLogin(context);
    }
    const { rows: [{ id, password_digest }] } = result;
    if (await compare(password.toString(), password_digest)) {
      return await context.render(id);
    } else {
      return await invalidLogin(context);
    }
  },
};

export default function Login({ data }: PageProps) {
  if (typeof data == "string") {
    return LoginSuccessful(data);
  } else {
    return LoginForm(data);
  }
}

function LoginSuccessful(_userId: UserID) {
  return (
    <Page>
      <p>
        You are now logged in. Let's go to your{" "}
        <a href="/dashboard">dashboard</a>!
      </p>
    </Page>
  );
}

function LoginForm(props?: LoginError | null) {
  return (
    <Page>
      {props != null &&
        (
          <p class="text-red-500">
            <strong>Error</strong>: {props.message}
          </p>
        )}
      <h1 class="text-4xl mb-4 outline-white">
        Log in to your account
      </h1>
      <form class="flex flex-col max-w-lg" method="post">
        <label for="username">Username</label>
        <input type="text" name="username" />
        <label for="password">Password</label>
        <input type="password" name="password" />
        <input class="mt-2" type="submit" value="Login" />
      </form>
    </Page>
  );
}
