<svelte:options
  customElement={{
    props: {
      columns: { type: "Array" },
      subfilter: { type: "String" },
    },
    shadow: "none",
    tag: "table-viewer",
  }}
/>

<!--
@component
Top-level web component for the tabular viewing and editing interface for
Phonograph portals. Parses HTML attributes, fetches data, and renders the
interactive interface implemented by the `<HydratedTableViewer>` Svelte
component.
-->

<script lang="ts">
  import { z } from "zod";

  import { datum_schema } from "../datum.svelte";
  import { type Row, type FieldInfo, field_info_schema } from "../field.svelte";
  import HydratedTableViewer from "./hydrated-table-viewer.svelte";

  type Props = {
    columns?: {
      name: string;
      regtype: string;
    }[];
    subfilter?: string;
  };

  let { columns = [], subfilter = "" }: Props = $props();

  type LazyData = {
    count: number;
    rows: Row[];
    fields: FieldInfo[];
  };

  let lazy_data = $state<LazyData | undefined>();

  (async function () {
    const get_data_response_schema = z.object({
      count: z.number().int(),
      rows: z.array(
        z.object({
          pkey: z.string(),
          data: z.array(datum_schema),
        }),
      ),
      fields: z.array(field_info_schema),
    });
    const resp = await fetch(
      `get-data?subfilter=${encodeURIComponent(subfilter)}`,
    );
    const body = get_data_response_schema.parse(await resp.json());
    lazy_data = {
      count: body.count,
      fields: body.fields,
      rows: body.rows.map(({ data, pkey }) => ({ data, key: pkey })),
    };
  })().catch(console.error);
</script>

<div class="table-viewer__layout">
  {#if lazy_data}
    <HydratedTableViewer
      {columns}
      fields={lazy_data.fields}
      rows_main={lazy_data.rows}
      subfilter_active={!!subfilter}
      total_count={lazy_data.count}
    />
  {/if}
</div>
