import { Church, Worship } from '@/payload-types'
import { fetchWorship } from '@/fetch/worship'
import { fetchLastAnnouncements } from '@/fetch/announcement'
import { fetchLastCalendars } from '@/fetch/calendar'
import { perParish } from '@/utils/dto/perParish'
import { Section } from '@/components/Section/Section'
import { Title } from '@/components/Title/Title'
import { MassGrid } from '@/components/MassTable/MassGrid'
import { PopupButton } from '@/components/PopupButton/PopupButton'
import { Button } from '@/components/Button/Button'
import moment from 'moment'
import styles from './massTimesBlock.module.scss'

type MassTimesBlockProps = {
  title?: string | null
  subtitle?: string | null
  range?: 'rolling' | 'week' | null
  churches?: (string | Church)[] | null
}

type LocationGroup = { name: string; masses: Worship[] }

const sortWorship = (worship: Worship[]) => {
  const map = new Map<string, LocationGroup>()

  worship.map((w) => {
    if (typeof w.location === 'object') {
      const { id, name } = w.location

      if (map.has(id)) {
        map.get(id)?.masses.push(w)
      } else {
        map.set(id, { name, masses: [w] })
      }
    }
  })

  return map
}

export async function MassTimesBlock({
  title = 'Nächste Gottesdienste',
  subtitle,
  range,
  churches,
}: MassTimesBlockProps) {
  const fromDate =
    range === 'week' ? moment().isoWeekday(1).startOf('day') : moment()
  const tillDate =
    range === 'week'
      ? moment().isoWeekday(7).endOf('day')
      : moment().add(1, 'week')

  const churchIds = churches
    ?.map((c) => (typeof c === 'object' ? c.id : c))
    .filter((id): id is string => !!id)

  const worship = await fetchWorship({
    fromDate: fromDate.toDate(),
    tillDate: tillDate.toDate(),
    locations: churchIds?.length ? churchIds : undefined,
  })
  const announcements = await fetchLastAnnouncements()
  const calendars = await fetchLastCalendars()

  const worshipDocs = worship?.docs || []
  const announcementsLinks = announcements ? perParish(announcements) : []
  const calendarsLinks = calendars ? perParish(calendars) : []

  const grouped = sortWorship(worshipDocs)

  const worshipPerLocation = churchIds?.length
    ? churchIds
        .map((id) => [id, grouped.get(id)] as const)
        .filter((entry): entry is [string, LocationGroup] => !!entry[1])
    : Array.from(grouped.entries()).sort((a, b) =>
        a[1].name.localeCompare(b[1].name),
      )

  return (
    <Section paddingBottom={'medium'}>
      <Title
        title={title || 'Nächste Gottesdienste'}
        subtitle={subtitle || undefined}
        color={'contrast'}
        align={'center'}
      />

      <Section padding={'small'}>
        <MassGrid
          locations={worshipPerLocation.map(([id, group]) => ({
            id,
            name: group.name,
            masses: group.masses,
          }))}
        />
      </Section>

      <Section padding={'small'}>
        <div className={styles.center}>
          {announcementsLinks.length > 0 && (
            <PopupButton
              text={'Vermeldungen'}
              title={'Vermeldungen'}
              links={announcementsLinks}
              schema={'shade'}
            />
          )}

          {calendarsLinks.length > 0 && (
            <PopupButton
              text={'Liturgischer Kalender'}
              title={'Kalender'}
              links={calendarsLinks}
              schema={'shade'}
            />
          )}

          <Button href={'/gottesdienst'} size={'md'}>
            Alle Gottesdienste
          </Button>
        </div>
      </Section>
    </Section>
  )
}
