---
import AnnouncementBanner from '../components/AnnouncementBanner.astro'
import BaseHead from '../components/BaseHead.astro'
import Footer from '../components/Footer.astro'
import Header from '../components/Header.astro'
import { cn } from '../lib/cn'
import { prisma } from '../lib/prisma'

import type { AstroChildren } from '../lib/astro'
import type { ComponentProps } from 'astro/types'

import '@fontsource-variable/space-grotesk'
import '../styles/global.css'

type Props = ComponentProps<typeof BaseHead> & {
  children: AstroChildren
  errors?: string[]
  success?: string[]
  className?: {
    body?: string
    main?: string
    footer?: string
  }
  showSplashText?: boolean
  widthClassName?:
    | 'container'
    | 'max-w-none'
    | 'max-w-screen-2xl'
    | 'max-w-screen-lg'
    | 'max-w-screen-md'
    | 'max-w-screen-sm'
    | 'max-w-screen-xl'
    | 'max-w-screen-xs'
}

const {
  errors = [],
  success = [],
  className,
  widthClassName = 'max-w-screen-2xl',
  showSplashText,
  ...baseHeadProps
} = Astro.props

const actualErrors = [...errors, ...Astro.locals.banners.errors]
const actualSuccess = [...success, ...Astro.locals.banners.successes]

const currentDate = new Date()
const announcement = await Astro.locals.banners.try(
  'Unable to load announcements.',
  () =>
    prisma.announcement.findFirst({
      where: {
        isActive: true,
        startDate: { lte: currentDate },
        OR: [{ endDate: null }, { endDate: { gt: currentDate } }],
      },
      select: {
        id: true,
        content: true,
        type: true,
        link: true,
        linkText: true,
        startDate: true,
        endDate: true,
        isActive: true,
      },
      orderBy: [{ type: 'desc' }, { createdAt: 'desc' }],
    }),
  null
)
---

<html lang="en" transition:name="root" transition:animate="none">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <BaseHead {...baseHeadProps} />
  </head>
  <body class={cn('bg-night-700 text-day-300 flex min-h-dvh flex-col *:shrink-0', className?.body)}>
    {announcement && <AnnouncementBanner announcement={announcement} transition:name="header-announcement" />}
    <Header
      classNames={{
        nav: cn(
          (widthClassName === 'max-w-none' || widthClassName === 'max-w-screen-2xl') && 'lg:px-8 2xl:px-12',
          widthClassName
        ),
      }}
      showSplashText={showSplashText}
    />

    {
      actualSuccess.length > 0 && (
        <ul class="container mx-auto my-4 space-y-4 px-4">
          {actualSuccess.map((message) => (
            <li class="font-title rounded-lg border border-green-500/30 bg-green-500/20 px-4 py-3 text-green-400">
              {message}
            </li>
          ))}
        </ul>
      )
    }

    {
      actualErrors.length > 0 && (
        <ul class="container mx-auto my-4 space-y-4 px-4">
          {actualErrors.map((error) => (
            <li class="font-title rounded-lg border border-red-500/30 bg-red-500/20 px-4 py-3 text-red-400">
              {error}
            </li>
          ))}
        </ul>
      )
    }

    <main
      class={cn(
        'container mx-auto mt-4 mb-12 grow px-4',
        className?.main,
        (widthClassName === 'max-w-none' || widthClassName === 'max-w-screen-2xl') && 'lg:px-8 2xl:px-12',
        widthClassName
      )}
    >
      <slot />
    </main>

    <Footer class={className?.footer} />
  </body>
</html>
