import moment from 'moment'
import { fetchUpcomingOccurrences } from '@/fetch/eventOccurrences'
import { fetchGroup, fetchAllGroups } from '@/fetch/group'
import { fetchParish, fetchAllParishes } from '@/fetch/parish'
import { transformOccurrences } from '@/utils/dto/events'
import { PageHeader } from '@/compositions/PageHeader/PageHeader'
import { Section } from '@/components/Section/Section'
import { Container } from '@/components/Container/Container'
import { EventRow } from '@/components/EventRow/EventRow'
import { NextPrevButtons } from '@/components/NextPrevButtons/NextPrevButtons'
import { EventFilterBar } from '@/compositions/EventFilterBar/EventFilterBar'
import { AdminMenu } from '@/components/AdminMenu/AdminMenu'
import Error from '@/components/Error/Error'
import { isAuthenticated } from '@/utils/auth'
import { Title } from '@/components/Title/Title'
import { HR } from '@/components/HorizontalRule/HorizontalRule'
import { P } from '@/components/Text/Paragraph'

const DATE_FMT = 'YYYY-MM-DD'
const PAGE_SIZE = 10

type Query = {
  group?: string
  parish?: string
  from?: string
  to?: string
  page?: string
}

const parseDate = (value: string | undefined): Date | undefined => {
  if (!value) return undefined
  const m = moment(value, DATE_FMT, true)
  return m.isValid() ? m.toDate() : undefined
}

const buildHref = (q: Query, page: number): string => {
  const params = new URLSearchParams()
  if (q.group) params.set('group', q.group)
  if (q.parish) params.set('parish', q.parish)
  if (q.from) params.set('from', q.from)
  if (q.to) params.set('to', q.to)
  if (page > 1) params.set('page', String(page))
  const qs = params.toString()
  return qs ? `/veranstaltungen?${qs}` : '/veranstaltungen'
}

export default async function EventsOverviewPage({
  searchParams,
}: {
  searchParams: Promise<Query>
}) {
  const authenticated = await isAuthenticated()
  const query = await searchParams

  const fromDate = parseDate(query.from) ?? moment().startOf('day').toDate()
  const toDate = parseDate(query.to)

  const parsedPage = parseInt(query.page ?? '1', 10)
  const page = Number.isFinite(parsedPage) && parsedPage > 0 ? parsedPage : 1

  const [allGroups, allParishes, groupDoc, parishDoc] = await Promise.all([
    fetchAllGroups(),
    fetchAllParishes(),
    query.group ? fetchGroup(query.group) : Promise.resolve(null),
    query.parish ? fetchParish(query.parish) : Promise.resolve(null),
  ])

  const paginated = await fetchUpcomingOccurrences({
    limit: PAGE_SIZE,
    page,
    fromDate,
    toDate,
    groupId: groupDoc?.id,
    parishId: parishDoc?.id,
  })

  if (!paginated) {
    return <Error statusCode={503} message={'Veranstaltungen konnten nicht geladen werden.'} />
  }

  const events = transformOccurrences(paginated.docs)

  const initial = {
    group: groupDoc?.slug ?? undefined,
    parish: parishDoc?.slug ?? undefined,
    from: query.from && parseDate(query.from) ? query.from : undefined,
    to: query.to && parseDate(query.to) ? query.to : undefined,
  }

  return (
    <>
      <Section paddingBottom={"small"}>
        <Container>
          <Title
            title={`Veranstaltungen`}
            size={"lg"}
            color={"contrast"}
          />
          <P width={"3/4"}>
            Entdecken Sie unsere kommenden Veranstaltungen und seien Sie dabei! Hier finden Sie alle Termine, Informationen und Highlights auf einen Blick.
          </P>
          <EventFilterBar
            groups={allGroups.docs.map((g) => ({ slug: g.slug, name: g.name }))}
            parishes={allParishes.docs.map((p) => ({ slug: p.slug, name: p.name }))}
            initial={initial}
          />
        </Container>
        <HR />
      </Section>

      <Section padding={'small'} paddingBottom={'large'}>
        <Container>
          {events.map((e) => (
            <EventRow
              key={e.id}
              date={e.date}
              end={e.end}
              title={e.title}
              href={e.href}
              location={e.location}
              cancelled={e.cancelled}
            />
          ))}

          {events.length === 0 && <p>Keine Veranstaltungen gefunden</p>}
        </Container>
      </Section>

      <AdminMenu collection={'event'} isAuthenticated={authenticated} />

      {(paginated.hasPrevPage || paginated.hasNextPage) && (
        <Section padding={'small'}>
          <NextPrevButtons
            prev={
              paginated.hasPrevPage && paginated.prevPage
                ? { href: buildHref(query, paginated.prevPage), text: 'Vorige Seite' }
                : undefined
            }
            next={
              paginated.hasNextPage && paginated.nextPage
                ? { href: buildHref(query, paginated.nextPage), text: 'Nächste Seite' }
                : undefined
            }
          />
        </Section>
      )}
    </>
  )
}
