<script lang="ts">
  import browser from "webextension-polyfill";
  import type { VaultInfo } from "upend/types";
  import { cleanInstanceUrl, instanceUrlStore } from "./common";
  import { onMount } from "svelte";
  import "./main.scss";

  let opening = false;
  let openError: string | undefined;

  let instanceUrl: string;
  $: instanceUrl = $instanceUrlStore;
  let instanceUrlModified = false;
  $: instanceUrlModified = $instanceUrlStore !== instanceUrl;

  let instanceVersion: string;
  let instanceVersionError: string;
  $: Boolean($instanceUrlStore) && updateVersion();

  async function updateVersion() {
    instanceVersion = undefined;
    instanceVersionError = undefined;

    try {
      const vaultInfo = (await (
        await fetch(`${$cleanInstanceUrl}/api/info`)
      ).json()) as VaultInfo;

      instanceVersion = vaultInfo.version;
    } catch (err: unknown) {
      instanceVersionError = processError(err);
    }
  }

  let currentUrl: string | undefined;
  let contentType: string | undefined;
  onMount(async () => {
    const currentTab = (
      await browser.tabs.query({
        active: true,
        currentWindow: true,
      })
    )[0];

    currentUrl = currentTab.url;

    contentType = (await browser.tabs.executeScript(currentTab.id, {
      code: "document.contentType",
    })) as unknown as string | undefined;
  });

  function visit(address: string) {
    browser.tabs.create({ url: `${$cleanInstanceUrl}/#/browse/${address}` });
    window.close();
  }

  async function openAsUrl() {
    opening = true;
    try {
      const address = (await (
        await fetch(`${$cleanInstanceUrl}/api/address?url=${currentUrl}`)
      ).json()) as string;
      visit(address);
    } catch (err) {
      openError = processError(err);
    }
  }

  async function openContent() {
    opening = true;
    try {
      const address = (await (
        await fetch(
          `${$cleanInstanceUrl}/api/address?url_content=${currentUrl}`
        )
      ).json()) as string;
      visit(address);
    } catch (err) {
      openError = processError(err);
    }
  }

  let primaryAction: [string, () => void] | undefined;
  $: primaryAction =
    contentType &&
    (contentType == "text/html"
      ? ["Open as URL", openAsUrl]
      : ["Open Content", openContent]);

  $: primaryActionLabel = primaryAction ? primaryAction[0] : "...";
  function performPrimaryAction() {
    console.log({ primaryAction });
    primaryAction[1]();
  }

  function processError(err: unknown): string {
    if (err instanceof Error) {
      if (err.message.includes("NetworkError")) {
        return "Network Error. Is UpEnd running?";
      } else {
        return err.message;
      }
    } else {
      return String(err);
    }
  }
</script>

<main>
  <div class="primary-controls">
    <button
      class="button"
      disabled={!Boolean(primaryAction)}
      on:click={performPrimaryAction}
    >
      {primaryActionLabel}
    </button>
    <div class="label">Content type: {contentType || "???"}</div>
  </div>
  <div class="controls row">
    <button class="button" on:click={openAsUrl}>Open as URL</button>
    <button class="button" on:click={openContent}>Open Content</button>
  </div>
  {#if opening && !openError}
    <div class="status-label">Opening, please wait...</div>
  {/if}
  {#if openError}
    <div class="status-label error">{openError}</div>
  {/if}
  <hr />
  <div class="row">
    <label>
      Instance URL
      <input
        class="instance-input"
        type="url"
        bind:value={instanceUrl}
        class:modified={instanceUrlModified}
      />
    </label>
    <button class="button" on:click={() => ($instanceUrlStore = instanceUrl)}>
      Save
    </button>
  </div>
  <div class="version">
    Status: {#if !instanceVersionError}
      {`OK, v.${instanceVersion}` || "???"}
    {:else}
      <div class="error">{instanceVersionError}</div>
    {/if}
  </div>
</main>

<style lang="scss">
  @use "../../webui/src/styles/colors";

  main {
    padding: 1em;
  }

  input {
    background: var(--background);
    color: var(--foreground);
    border: 1px solid var(--foreground);
    border-radius: 2px;
  }

  input[type="url"] {
    font-family: var(--monospace-font);

    &:focus-visible {
      outline: 1px solid var(--primary-lighter);
    }

    &:invalid {
      color: colors.$red;
      outline: 2px solid colors.$red;
    }
  }

  .instance-input.modified {
    color: colors.$yellow;
  }

  hr {
    margin: 1rem 0;
  }

  .controls {
    display: flex;
    justify-content: space-evenly;
  }

  .primary-controls {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.25rem;

    margin-bottom: 1rem;
    .button {
      font-size: 1.5rem;
    }
    .label {
      font-size: 0.75rem;
    }
  }

  .row {
    display: flex;
    align-items: center;
    gap: 1rem;
  }

  .status-label {
    margin-top: 1rem;
    text-align: center;
  }

  .error {
    color: colors.$red;
  }

  .version .error {
    display: inline;
  }
</style>
