<script setup lang="ts">
/**
 * IndexPage — top-level templating consumer for list views.
 *
 * Accepts a `config` JSON object plus an `items` data model and
 * renders:
 *   - page header (title, breadcrumbs, section, optional Create button)
 *   - a single DataTableCard wired from `config.headers`, `config.options`,
 *     `config.listKey`
 *
 * Event handlers passed in `config.eventHandlers` are exposed to all
 * nested elements/cards via Vue's provide/inject under
 * `PAGE_EVENT_HANDLERS_KEY` so deep children can `inject` and emit
 * named page-level events without prop-drilling.
 */
import { computed, provide } from "vue"
import type {
  DataTableCard as DataTableCardDef,
  DataTableColumn,
  DataTableOptions,
} from "@/definitions/cards/DataTableCard"
import type { CreateConfig } from "@/definitions/shared/crud"
import CardRenderer from "@/engine/CardRenderer.vue"
import { Button } from "@/components/ui/button"
import { PAGE_EVENT_HANDLERS_KEY } from "./ShowPage.vue"

export interface BreadCrumb {
  title: string
}

export interface IndexPageConfig {
  title: string
  breadCrumbs?: BreadCrumb[]
  section?: string
  headers?: DataTableColumn[]
  options?: DataTableOptions
  listKey?: string
  createConfig?: CreateConfig
  eventHandlers?: Record<string, (...args: unknown[]) => void>
}

export interface IndexPageProps {
  config: IndexPageConfig
  /**
   * The data model passed through to the DataTableCard as `item`. Typically
   * an object containing the row source under `config.listKey`.
   */
  items?: Record<string, unknown>
}

const props = withDefaults(defineProps<IndexPageProps>(), {
  items: () => ({}),
})

const emit = defineEmits<{
  (e: "create"): void
}>()

provide(
  PAGE_EVENT_HANDLERS_KEY,
  computed(() => props.config.eventHandlers ?? {}).value,
)

const breadCrumbs = computed<BreadCrumb[]>(
  () => props.config.breadCrumbs ?? [],
)

const showCreateButton = computed<boolean>(() => {
  const c = props.config.createConfig
  return Boolean(c) && c?.hideButton !== true
})

const createButtonText = computed<string>(
  () => props.config.createConfig?.buttonText ?? "Create",
)

const dataTableCard = computed<DataTableCardDef>(() => ({
  id: "index-page-data-table",
  cardType: "datatable",
  headers: props.config.headers ?? [],
  listKey: props.config.listKey,
  options: props.config.options,
}))

function onCreate(): void {
  const handler = props.config.eventHandlers?.create
  if (typeof handler === "function") {
    handler()
  }
  emit("create")
}
</script>

<template>
  <div class="gxp-index-page flex flex-col gap-4" data-testid="index-page">
    <header class="flex flex-col gap-2" data-testid="index-page-header">
      <nav
        v-if="breadCrumbs.length"
        aria-label="Breadcrumb"
        class="text-sm text-muted-foreground"
        data-testid="index-page-breadcrumbs"
      >
        <ol class="flex flex-wrap items-center gap-1">
          <li
            v-for="(crumb, index) in breadCrumbs"
            :key="`${crumb.title}-${index}`"
            class="flex items-center gap-1"
          >
            <span>{{ crumb.title }}</span>
            <span
              v-if="index < breadCrumbs.length - 1"
              aria-hidden="true"
              class="opacity-60"
            >
              /
            </span>
          </li>
        </ol>
      </nav>
      <div class="flex items-center justify-between gap-3">
        <div class="flex flex-col gap-0.5">
          <p
            v-if="config.section"
            class="text-xs font-medium uppercase tracking-wide text-muted-foreground"
            data-testid="index-page-section"
          >
            {{ config.section }}
          </p>
          <h1
            class="text-2xl font-semibold tracking-tight"
            data-testid="index-page-title"
          >
            {{ config.title }}
          </h1>
        </div>
        <Button
          v-if="showCreateButton"
          data-testid="index-page-create-button"
          @click="onCreate"
        >
          {{ createButtonText }}
        </Button>
      </div>
    </header>

    <section class="gxp-index-page__body" data-testid="index-page-body">
      <CardRenderer :card="dataTableCard" :item="items" />
    </section>
  </div>
</template>
