import type { Metadata } from 'next/types'

import configPromise from '@payload-config'
import { getPayload } from 'payload'
import { draftMode } from 'next/headers'
import { notFound } from 'next/navigation'
import React, { cache } from 'react'

import { Breadcrumb } from '@/components/Breadcrumb'
import { ChapterReader } from '@/components/ChapterReader'
import { LivePreviewListener } from '@/components/LivePreviewListener'

type Args = {
  params: Promise<{ slug: string; chapterSlug: string }>
}

export default async function Page({ params: paramsPromise }: Args) {
  const { isEnabled: draft } = await draftMode()
  const { slug, chapterSlug } = await paramsPromise

  const story = await queryStoryBySlug({ slug })
  if (!story) return notFound()

  const chapter = await queryChapter({ storyId: story.id, chapterSlug })
  if (!chapter) return notFound()

  const payload = await getPayload({ config: configPromise })

  const [prevResult, nextResult] = await Promise.all([
    (payload as any).find({
      collection: 'chapters',
      where: {
        story: { equals: story.id },
        chapterNumber: { less_than: chapter.chapterNumber },
      },
      sort: '-chapterNumber',
      limit: 1,
      depth: 0,
      overrideAccess: false,
    }),
    (payload as any).find({
      collection: 'chapters',
      where: {
        story: { equals: story.id },
        chapterNumber: { greater_than: chapter.chapterNumber },
      },
      sort: 'chapterNumber',
      limit: 1,
      depth: 0,
      overrideAccess: false,
    }),
  ])

  const prevChapter = prevResult.docs[0] ?? null
  const nextChapter = nextResult.docs[0] ?? null

  return (
    <>
      {draft && <LivePreviewListener />}
      <div className="container pt-8 pb-0">
        <Breadcrumb
          items={[
            { label: 'Trang chủ', href: '/' },
            { label: story.title, href: `/truyen/${slug}` },
            { label: `Chương ${chapter.chapterNumber}` },
          ]}
        />
      </div>
      <ChapterReader
        chapter={chapter}
        storySlug={slug}
        storyTitle={story.title}
        prevChapter={prevChapter}
        nextChapter={nextChapter}
      />
    </>
  )
}

export async function generateMetadata({ params: paramsPromise }: Args): Promise<Metadata> {
  const { slug, chapterSlug } = await paramsPromise

  const story = await queryStoryBySlug({ slug })
  const chapter = story ? await queryChapter({ storyId: story.id, chapterSlug }) : null

  return {
    title:
      chapter && story
        ? `Chương ${chapter.chapterNumber}: ${chapter.title} - ${story.title}`
        : 'Đọc truyện',
  }
}

const queryStoryBySlug = cache(async ({ slug }: { slug: string }) => {
  const payload = await getPayload({ config: configPromise })
  const { isEnabled: draft } = await draftMode()
  const result = await (payload as any).find({
    collection: 'stories',
    where: { slug: { equals: slug } },
    limit: 1,
    depth: 0,
    draft,
    overrideAccess: draft,
  })
  return result.docs[0] ?? null
})

const queryChapter = cache(
  async ({ storyId, chapterSlug }: { storyId: string; chapterSlug: string }) => {
    const payload = await getPayload({ config: configPromise })
    const { isEnabled: draft } = await draftMode()
    const result = await (payload as any).find({
      collection: 'chapters',
      where: { slug: { equals: chapterSlug }, story: { equals: storyId } },
      limit: 1,
      depth: 1,
      draft,
      overrideAccess: draft,
    })
    return result.docs[0] ?? null
  },
)
