import type { Metadata } from 'next'
import { notFound } from 'next/navigation'
import { getFormatter, getTranslations } from 'next-intl/server'
import { ProjectArchive } from '~/components/archive/ProjectArchive'
import {
	listArchiveMonths,
	listPostTypeCounts,
	listPostsForArchive,
	loadArchiveStats,
	loadHighestNumber,
	loadPostCovers,
} from '~/data/repositories/archive'
import { monthYearFormat } from '~/lib/dates'
import { findProjectView } from '~/lib/project-view'
import { perPage, readMonth, readPage, readPostType, readYear, recentDays, type SearchParams } from '~/lib/query'
import type { ViewerScope } from '~/domain/types'

const scope: ViewerScope = 'internal'

const coverCount = 3

type Props = {
	params: Promise<{ project: string, entry: string, month: string }>
	searchParams: Promise<SearchParams>
}

export async function generateMetadata({ params }: Props): Promise<Metadata> {
	const resolved = await params
	const app = await getTranslations('app')
	const year = readYear(resolved.entry)
	const month = readMonth(resolved.month)

	if (year === undefined || month === undefined) {
		const t = await getTranslations('notFound')
		return { title: `${app('name')} - ${t('title')}` }
	}

	const format = await getFormatter()
	const view = await findProjectView(resolved.project, scope)
	const period = format.dateTime(new Date(Date.UTC(year, month - 1, 1)), monthYearFormat)

	return { title: view ? `${period} - ${view.project.name} - ${app('name')}` : app('name') }
}

export default async function MonthPage({ params, searchParams }: Props) {
	const resolved = await params
	const year = readYear(resolved.entry)
	const month = readMonth(resolved.month)

	if (year === undefined || month === undefined) {
		notFound()
	}

	const query = await searchParams
	const page = readPage(query.page)
	const type = readPostType(query.type)
	const view = await findProjectView(resolved.project, scope)

	if (!view) {
		notFound()
	}

	const [stats, months, list, typeCounts, highest] = await Promise.all([
		loadArchiveStats({ scope, projectSlug: resolved.project, recentDays }),
		listArchiveMonths({ scope, projectSlug: resolved.project }),
		listPostsForArchive({ scope, projectSlug: resolved.project, year, month, type, page, perPage }),
		listPostTypeCounts({ scope, projectSlug: resolved.project, year, month }),
		loadHighestNumber({ scope, projectSlug: resolved.project }),
	])

	const covers = await loadPostCovers(list.items.slice(0, coverCount).map(item => item.id))

	return (
		<ProjectArchive
			view={view}
			stats={stats}
			months={months}
			list={list}
			typeCounts={typeCounts}
			page={page}
			covers={covers}
			highest={highest}
			year={year}
			month={month}
			type={type}
		/>
	)
}
