<script lang="typescript" context="module">
  import type { AppSession, PageData, PreloadContext } from "src/utils/session";
  import type { Option } from "@shared/common/async_utils";
  import type { MDText } from "./md";
  import type { VerifyInfo } from "./verify";

  export async function preload(
    this: PreloadContext,
    { path }: PageData,
    session: AppSession
  ) {
    const mdResult = await this.fetch("/rules/md", { credentials: "include" });
    const md = (await mdResult.json()) as Option<MDText, { error: string }>;

    const verifyReusult = await this.fetch("/rules/verify", { credentials: "include" });
    const verify = (await verifyReusult.json()) as VerifyInfo;
    return {
      rulesText: md.ok ? md.text : "",
      sitekey: verify.captchaSitekey,
      verified: verify.userVerified,
    };
  }
</script>

<script lang="typescript">
  import { Converter } from "showdown";
  import Icon from "svelte-awesome/components/Icon.svelte";
  import { faSpinner } from "@fortawesome/free-solid-svg-icons";
  import { fade } from "svelte/transition";
  import type { VerifyRequest } from "./verify";

  export let rulesText: string = "";
  export let sitekey: string = "";
  export let verified!: boolean;
  let showVerify: boolean = false;
  const spinner = (faSpinner as unknown) as undefined;
  let htmlContent = new Converter().makeHtml(rulesText);

  enum State {
    None,
    Verify,
    Error,
    Message,
  }

  let state: State = State.None;
  let message: string = "";
  async function onVerified(e: { key: string }) {
    state = State.Verify;
    const result = await fetch("/rules/verify", {
      credentials: "include",
      method: "post",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ captchaResponse: e.key } as VerifyRequest),
    });
    const opt = (await result.json()) as Option<unknown, { error: string }>;
    if (!opt.ok) {
      state = State.Error;
      message = opt.error;
    } else {
      state = State.Message;
      message = "Verification done! Welcome to the server!";
    }
  }

  function onExpired() {
    state = State.Error;
    message = "Captcha expired, please solve it again";
  }

  function onError(error: string) {
    state = State.Error;
    message = `${error}; Please try refreshing the page.`;
  }
</script>

<style>
  @import "./markdown-dark.css";

  .message {
    @apply text-white;
  }

  .error {
    @apply text-red-600;
  }
</style>

<svelte:head>
  <title>Rules</title>
</svelte:head>

<div class="viewport md-dark md-body">
  <div>
    {@html htmlContent}
  </div>
  {#if !verified}
    <div class="flex flex-col flex-wrap items-center">
      <form class="py-4">
        <input type="checkbox" id="show-verify" bind:checked={showVerify} disabled={state != State.None} />
        <label for="show-verify">I understand these rules and agree to abide to
          them</label>
      </form>
      {#if showVerify}
        <!-- <a href="asd" on:click|preventDefault={() => onVerified({ key: 'wew' })}>Verify test</a> -->
        <h-captcha site-key={sitekey} dark on:verified={onVerified} on:expired={onExpired} on:error={onError} />  
      {/if}
      <div class="py-2 pointer-events-none select-none">
        {#if state == State.Verify}
          <span transition:fade={{ duration: 50 }}><Icon data={spinner} spin />
            Verifying</span>
        {:else if state == State.Error || state == State.Message}
          <span
            class:message={state == State.Message}
            class:error={state == State.Error}>{message}</span>
        {/if}
      </div>
    </div>
  {/if}
</div>
