<script lang="ts">
  import { Session, TFAOption, TFAType } from "@hibas123/openauth-internalapi";
  import InternalAPI from "../../../helper/api";
  import Loading from "../Loading.svelte";
  import { onMount } from "svelte";
  import {
    Button,
    Card,
    Input,
    Label,
    Select,
    Heading,
    Spinner,
    Helper,
    Table,
    TableHead,
    TableHeadCell,
    TableBody,
    TableBodyRow,
    TableBodyCell,
    Accordion,
    AccordionItem,
    Alert,
  } from "flowbite-svelte";
  import AddTwoFactor from "./AddTwoFactor.svelte";

  let tokens: Session[];
  let twofactors: TFAOption[];
  let error: string | undefined;
  let loading = true;

  async function load() {
    loading = true;
    try {
      tokens = await InternalAPI.Security.GetSessions();
      twofactors = await InternalAPI.TwoFactor.GetOptions();
    } catch (e) {
      error = e.message;
    } finally {
      loading = false;
    }
  }

  async function reload() {
    try {
      tokens = await InternalAPI.Security.GetSessions();
      twofactors = await InternalAPI.TwoFactor.GetOptions();
    } catch (e) {
      error = e.message;
    }
  }

  onMount(() => {
    load();
  });

  async function revokeToken(id: string) {
    try {
      await InternalAPI.Security.RevokeSession(id);
      await load();
    } catch (e) {
      error = e.message;
    }
  }

  const typeToName = {
    [TFAType.TOTP]: "TOTP",
    [TFAType.WEBAUTHN]: "Security Key (WebAuthn)",
    [TFAType.BACKUP_CODE]: "Backup-Code",
    [TFAType.APP_ALLOW]: "App-Auth",
  };

  let addTwoFactorOpen = false;

  function openAddTwoFactor() {
    addTwoFactorOpen = true;
  }

  async function deleteTwoFactor(id: string) {
    try {
      await InternalAPI.TwoFactor.Delete(id);
      await reload();
    } catch (e) {
      error = e.message;
    }
  }

  let old_pw = "";
  let new_pw = "";
  let new_pw_repeat = "";

  let change_password_success = false;
  let change_password_error: string | undefined;

  function changePassword() {
    change_password_success = false;
    change_password_error = undefined;
    if (new_pw !== new_pw_repeat) {
      change_password_error = "Passwords do not match";
      return;
    }

    InternalAPI.Security.ChangePassword(old_pw, new_pw)
      .then(() => {
        change_password_error = undefined;
        old_pw = "";
        new_pw = "";
        new_pw_repeat = "";
        change_password_success = true;
      })
      .catch((e) => {
        change_password_error = e.message;
      });
  }
</script>

<Loading {loading} {error}>
  <Card size="xl">
    <Heading tag="h5">Active Sessions</Heading>
    <hr class="mb-6" />
    <Table>
      <TableHead>
        <TableHeadCell>Browser</TableHeadCell>
        <TableHeadCell class="w-full">IP</TableHeadCell>
        <TableHeadCell class="material-icons-outlined w-20"
          >delete</TableHeadCell
        >
      </TableHead>
      <TableBody>
        {#each tokens as token}
          <TableBodyRow
            class="bg-yellow-50"
            color={token.isthis ? "custom" : "default"}
          >
            <TableBodyCell>{token.browser}</TableBodyCell>
            <TableBodyCell>{token.ip}</TableBodyCell>
            <TableBodyCell>
              <!-- svelte-ignore a11y-missing-attribute -->
              <!-- svelte-ignore a11y-click-events-have-key-events -->
              <a
                class="font-medium text-red-600 hover:underline dark:text-blue-500"
                on:click={() => revokeToken(token.id)}
              >
                Revoke
              </a>
            </TableBodyCell>
          </TableBodyRow>
        {/each}
      </TableBody>
    </Table>
  </Card>

  <Card size="xl" class="mt-4">
    <Heading tag="h5">Change Password</Heading>
    <hr class="mb-6" />

    {#if change_password_success}
      <Alert color="green">Password changed successfully.</Alert>
    {/if}

    {#if change_password_error}
      <Alert color="red">{change_password_error}</Alert>
    {/if}

    <div class="mb-6">
      <Label for="oldPassword">Old Password</Label>
      <Input type="password" id="oldPassword" bind:value={old_pw} />
    </div>
    <div class="mb-6">
      <Label for="newPassword">New Password</Label>
      <Input type="password" id="newPassword" bind:value={new_pw} />
    </div>
    <div class="mb-6">
      <Label for="newPasswordRepeat">Repeat New Password</Label>
      <Input
        type="password"
        id="newPasswordRepeat"
        bind:value={new_pw_repeat}
      />
    </div>
    <Button class="mt-4" on:click={changePassword}>Change Password</Button>
  </Card>

  <Card size="xl" class="mt-4">
    <Heading tag="h5">Two Factor Auth</Heading>
    <hr class="mb-6" />

    <Accordion>
      {#each twofactors as tfa}
        <AccordionItem>
          <span slot="header">{tfa.name ?? typeToName[tfa.tfatype]}</span>
          <div>
            <Button
              color="red"
              class="mt-4"
              on:click={() => deleteTwoFactor(tfa.id)}>Delete</Button
            >
          </div>
        </AccordionItem>
      {/each}
    </Accordion>
    <Button class="mt-4" on:click={openAddTwoFactor}>Add Option</Button>
  </Card>

  <AddTwoFactor on:reload={reload} bind:open={addTwoFactorOpen} />

  <!-- <Card size="xl" class="mt-4">
    <Heading tag="h5">Delete Account</Heading>
    <hr class="mb-6" />

    <div class="mb-6">
      <Label for="password">Password</Label>
      <Input type="password" id="password" />
    </div>
    <Button class="mt-4">Delete Account</Button>
  </Card> -->
</Loading>
