<script lang="ts">
  import filesize from "filesize";
  import { format, fromUnixTime } from "date-fns";
  import type { Readable } from "svelte/store";
  import type { OrderedListing } from "upend/types";
  import Marquee from "../Marquee.svelte";
  import Address from "../Address.svelte";

  export let attributes: OrderedListing;
  export let editable = false;
  export let reverse = false;

  let newEntryAttribute = "'";
  let newEntryValue = "";

  let currentDisplay = 999;
  const MAX_DISPLAY = 50;

  async function addEntry() {
    // this.$emit("edit", {
    //   type: "create",
    //   attribute: this.newEntryAttribute,
    //   value: this.newEntryValue,
    // } as AttributeChange);
    // this.newEntryAttribute = "";
    // this.newEntryValue = "";
  }
  async function removeEntry(addr: string) {
    // if (confirm("Are you sure you want to remove the attribute?")) {
    //   this.$emit("edit", { type: "delete", addr } as AttributeChange);
    // }
  }
  async function updateEntry(addr: string, attribute: string, value: string) {
    // this.$emit("edit", {
    //   type: "update",
    //   addr,
    //   value
    // } as AttributeChange);
    // this.$emit("edit", {
    //   type: "delete",
    //   addr,
    // } as AttributeChange);
    // this.$emit("edit", {
    //   type: "create",
    //   attribute,
    //   value,
    // } as AttributeChange);
  }

  let resolve = [];

  const ATTRIBUTE_LABELS: { [key: string]: string } = {
    FILE_MIME: "MIME type",
    FILE_MTIME: "Last modified",
    FILE_SIZE: "File size",
  };

  const VALUE_FORMATTERS: { [key: string]: (val: string) => string } = {
    FILE_MTIME: (val) => format(fromUnixTime(parseInt(val, 10)), "PPpp"),
    FILE_SIZE: (val) => filesize(parseInt(val, 10), { base: 2 }),
  };

  function formatAttribute(attribute: string) {
    return ATTRIBUTE_LABELS[attribute];
  }

  function formatValue(value: string, attribute: string): string | undefined {
    const handler = VALUE_FORMATTERS[attribute];
    if (handler) {
      return handler(value);
    }
  }
</script>

<div class="table">
  <table class:reverse>
    <colgroup>
      {#if editable}
        <col class="attr-action-col" />
      {/if}
      <col class="attr-col" />
      <col />
    </colgroup>
    {#if !reverse}
      <tr>
        {#if editable}
          <th />
        {/if}
        <th>Attribute</th>
        <th>Value</th>
      </tr>
      {#each attributes as [id, entry] (id)}
        <tr>
          {#if editable}
            <td class="attr-action">
              <sl-icon-button name="x-circle" on:click={removeEntry(id)} />
            </td>
          {/if}
          <td class:formatted={Boolean(formatAttribute(entry.attribute))}>
            <Marquee>
              {formatAttribute(entry.attribute) || entry.attribute}
            </Marquee>
          </td>
          <td class="value">
            <text-input
              {editable}
              value={entry.value.c}
              on:edit={(val) => updateEntry(id, entry.attribute, val)}
            >
              {#if entry.value.t === "Address"}
                <Address
                  link
                  address={entry.value.c}
                  resolve={Boolean(resolve[id]) || true}
                  data-id={id}
                />
              {:else}
                <div
                  class:formatted={Boolean(
                    formatValue(entry.value.c, entry.attribute)
                  )}
                >
                  <Marquee>
                    {formatValue(entry.value.c, entry.attribute) ||
                      entry.value.c}
                  </Marquee>
                </div>
              {/if}
            </text-input>
          </td>
        </tr>
      {/each}
      {#if attributes.length > currentDisplay}
        <tr>
          <td colspan={editable ? 3 : 2}>
            <sl-button
              class="more-button"
              on:click={(currentDisplay += MAX_DISPLAY)}
            >
              + {attributes.length - currentDisplay} more...
            </sl-button>
          </td>
        </tr>
      {/if}
      {#if editable}
        <tr>
          <td class="attr-action">
            <sl-icon-button name="plus-circle" on:click={addEntry()} />
          </td>
          <td>
            <sl-input v-sl-model:newEntryAttribute size="small" />
          </td>
          <td>
            <sl-input v-sl-model:newEntryValue size="small" />
          </td>
        </tr>
      {/if}
    {:else}
      <tr>
        <th>Entities</th>
        <th>Attribute name</th>
      </tr>
      {#each attributes as [id, entry] (id)}
        <tr>
          <td>
            <Address link address={entry.entity} />
          </td>
          <td>
            <Marquee>
              {entry.attribute}
            </Marquee>
          </td>
        </tr>
      {/each}
    {/if}
  </table>
</div>

<style lang="scss" scoped>
  table {
    width: 100%;
    table-layout: fixed;

    th {
      text-align: left;
    }

    td {
      font-family: var(--monospace-font);
      padding-right: 1em;
      line-height: 1em;
      line-break: anywhere;

      &.attr-action {
        max-width: 1em;
      }

      .formatted {
        font-family: var(--default-font);
      }
    }

    .attr-action-col {
      width: 1.5em;
    }

    .attr-col {
      width: 33%;
    }

    &.reverse .attr-col {
      width: 70%;
    }

    sl-icon-button {
      &::part(base) {
        padding: 2px;
      }
    }

    .more-button {
      width: 100%;
    }
  }
</style>
