<script setup lang="ts">
import type { RouterLinkProps } from 'vue-router'
import { useAttrs } from 'vue'

import Layout from '~/components/ui/Layout.vue'
import Spacer from '~/components/ui/Spacer.vue'
import Button from '~/components/ui/Button.vue'
import Link from '~/components/ui/Link.vue'
import Heading from '~/components/ui/Heading.vue'

const actionComponents
  = { Button, Link }

const props = defineProps<{
  [M in 'no-items' | 'tiny-items' | 'small-items' | 'medium-items']?: true }
  & {
    alignLeft?: boolean;
    collapsed?: boolean;
  }
  & { [H in 'h1' | 'h2' | 'h3']?: string }
  & { action?: { text: string } & (RouterLinkProps | { onClick: (...args: any[]) => void | Promise<void> }) }>()

const heading
  = props.h1
    ? ({ h1: props.h1, pageHeading: true }) as const
    : props.h2
      ? ({ h2: props.h2 }) as const
      : ({ h3: props.h3 }) as const

const numberOfColumnsPerItem
  = 'noItems' in props && props.noItems ? 1 : 'tinyItems' in props && props.tinyItems ? 2 : 'smallItems' in props && props.smallItems ? 3 : 4

const { style, ...fallthroughProps } = useAttrs()

const headerGrid
  = `auto / repeat(auto-fit, calc(46px * ${numberOfColumnsPerItem} + 32px * ${numberOfColumnsPerItem - 1}))`
</script>

<template>
  <section style="flex-grow: 1;">
    <Layout
      header
      :grid="headerGrid"
      :style="`${'alignLeft' in props && props.alignLeft ? 'justify-content: start' : ''};
     margin-top: -64px;`"
    >
      <!-- The title row's width is a multiple of the expected items' column span -->
      <Layout
        flex
        no-gap
        style="grid-column: 1 / -1; align-self: baseline;"
      >
        <!-- Set distance between baseline and previous row -->
        <Spacer
          v
          :size="64"
          style="align-self: baseline;"
        />
        <Heading
          v-if="heading"
          v-bind="heading"
          style="align-self: baseline; padding:0  0 24px 0; margin:0;"
        />
        <Spacer grow />
        <!-- Action! You can either specify `to` or `onClick`. -->
        <component
          :is="'onClick' in action ? actionComponents.Button : actionComponents.Link"
          v-if="action"
          ghost
          thin-font
          align-self="baseline"
          :align-text="'collapsed' in props ? 'left' : undefined"
          :aria-pressed="props.collapsed === false || undefined"
          :class="{
            [$style.action]: true,
            [$style.transparent]: 'primary' in props || 'secondary' in props || 'destructive' in props,
            [$style.full]: 'collapsed' in props
          }"
          v-bind="{...fallthroughProps, ...action, ['collapsed' in props ? 'full' : 'min-content']: true}"
        >
          {{ action?.text }}
        </component>
      </Layout>
    </Layout>

    <!-- Love: https://css-tricks.com/css-grid-can-do-auto-height-transitions/ -->

    <Layout
      main
      :inert="'collapsed' in props && props.collapsed"
      :style="`${
        'alignLeft' in props && props.alignLeft
          ? 'justify-content: start;'
          : ''
      }  ${
        'collapsed' in props && props.collapsed
          ? 'grid-template-rows: 0fr; overflow: hidden; max-height: 0;'
          : 'max-height: 4000px;'
      }
        position: relative;
        transition: max-height .5s, grid-template-rows .3s;`
      "
      grid="auto / repeat(auto-fit, 46px)"
    >
      <slot />
    </Layout>
  </section>
</template>

<style module lang="scss">

  .action {
    &.transparent {
    margin-right: 16px;
    }
    &.full {
      min-width: 100%;
    }
  }
</style>
