<script lang="ts" context="module">
  export interface WidgetComponent {
    component: ComponentType;
    props: { [key: string]: unknown };
  }

  export interface Widget {
    name: string;
    icon?: string;
    components: (input: {
      entries: UpEntry[];
      group?: string;
      address?: string;
    }) => Array<WidgetComponent>;
  }
</script>

<script lang="ts">
  import EntryList from "./widgets/EntryList.svelte";
  import type { UpEntry } from "@upnd/upend";
  import Icon from "./utils/Icon.svelte";
  import IconButton from "./utils/IconButton.svelte";
  import { createEventDispatcher, type ComponentType } from "svelte";
  import UpObject from "./display/UpObject.svelte";
  import LabelBorder from "./utils/LabelBorder.svelte";
  const dispatch = createEventDispatcher();

  export let entries: UpEntry[];
  export let widgets: Widget[] | undefined = undefined;
  export let initialWidget: string | undefined = undefined;
  export let title: string | undefined = undefined;
  export let group: string | undefined = undefined;
  export let address: string | undefined = undefined;
  export let icon: string | undefined = undefined;
  export let highlighted = false;

  let currentWidget: string | undefined;

  function switchWidget(widget: string) {
    currentWidget = widget;
    dispatch("widgetSwitched", currentWidget);
  }

  let availableWidgets: Widget[] = [];
  $: {
    availableWidgets = [
      {
        name: "Entry List",
        icon: "table",
        components: ({ entries }) => [
          {
            component: EntryList,
            props: { entries, columns: "entity, attribute, value" },
          },
        ],
      },
    ];

    if (widgets?.length) {
      availableWidgets = [...widgets, ...availableWidgets];
    }

    if (availableWidgets.map((w) => w.name).includes(initialWidget)) {
      currentWidget = initialWidget;
    } else {
      currentWidget = availableWidgets[0].name;
    }
  }

  let components: WidgetComponent[] = [];
  $: {
    components = availableWidgets
      .find((w) => w.name === currentWidget)
      .components({ entries, group, address });
  }
</script>

<LabelBorder hide={entries.length === 0}>
  <svelte:fragment slot="header-full">
    <h3 class:highlighted>
      {#if group}
        {#if icon}
          <div class="icon">
            <Icon name={icon} />
          </div>
        {/if}
        <UpObject link address={group} labels={title ? [title] : undefined} />
      {:else}
        {#if icon}
          <div class="icon">
            <Icon name={icon} />
          </div>
        {/if}
        {title || ""}
      {/if}
    </h3>

    {#if currentWidget && availableWidgets.length > 1}
      <div class="views">
        {#each availableWidgets as widget (widget.name)}
          <IconButton
            name={widget.icon || "cube"}
            title={widget.name}
            active={widget.name === currentWidget}
            --active-color="var(--foreground)"
            on:click={() => switchWidget(widget.name)}
          >
            {widget.name}
          </IconButton>
        {/each}
      </div>
    {/if}
  </svelte:fragment>
  {#each components as component}
    <svelte:component
      this={component.component}
      {...component.props || {}}
      on:change
    />
  {/each}
</LabelBorder>

<style scoped lang="scss">
  .icon {
    display: inline-block;
    font-size: 1.25em;
    margin-top: -0.3em;
    position: relative;
    bottom: -2px;
  }

  h3 {
    margin: 0;
    transition: text-shadow 0.2s;

    &.highlighted {
      text-shadow: #cb4b16 0 0 0.5em;
    }
  }

  .views {
    display: flex;
    font-size: 16px;
  }
</style>
