import type { SerializedEditorState } from '@payloadcms/richtext-lexical/lexical'
import type { ShopArchiveBlock as ShopArchiveBlockType } from '@/payload-types'

import configPromise from '@payload-config'
import { getPayload } from 'payload'

import { RichText } from '@/components/RichText'
import { ShopArchiveShell } from '@/components/shop/ShopArchiveShell'
import { ShopProductResults } from '@/components/shop/ShopProductResults'
import { resolveShopFilterLabels } from '@/lib/shop/filterLabels'
import { queryShopProducts } from '@/lib/shop/queryProducts'
import { cn } from '@/utilities/cn'
import { type SearchParams, SHOP_PAGE_SIZE } from '@/utilities/shopParams'

type ShopArchiveBlockProps = {
  className?: string
  containerWidth?: 'default' | 'full' | 'wide' | null
  desktopSidebarPosition?: 'left' | 'right' | null
  id?: number | string
  introContent?: SerializedEditorState | null
  limit?: number | null
  searchParams?: SearchParams
  showFilters?: boolean | null
  showSearch?: boolean | null
  showSort?: boolean | null
  sidebarEyebrow?: string | null
  sidebarLayout?: ShopArchiveBlockType['sidebarLayout']
  sidebarTitle?: string | null
  spacing?: 'compact' | 'default' | 'spacious' | null
}

const resolveLimit = (limit?: number | null): number => {
  if (typeof limit !== 'number' || !Number.isFinite(limit) || limit < 1) {
    return SHOP_PAGE_SIZE
  }

  return Math.floor(limit)
}

export const ShopArchiveBlock: React.FC<ShopArchiveBlockProps> = async (props) => {
  const {
    className,
    containerWidth,
    desktopSidebarPosition,
    id,
    introContent,
    limit: limitFromProps,
    searchParams = {},
    showFilters = true,
    showSearch = true,
    showSort = true,
    sidebarEyebrow,
    sidebarLayout,
    sidebarTitle,
    spacing,
  } = props

  const resolvedSpacing = spacing || 'default'
  const sectionSpacingClass =
    resolvedSpacing === 'compact' ? 'my-8' : resolvedSpacing === 'spacious' ? 'my-24' : 'my-16'
  const introSpacingClass =
    resolvedSpacing === 'compact' ? 'mb-8' : resolvedSpacing === 'spacious' ? 'mb-20' : 'mb-16'

  const payload = await getPayload({ config: configPromise })
  const products = await queryShopProducts({
    limit: resolveLimit(limitFromProps),
    payload,
    searchParams,
  })
  const filterLabels = await resolveShopFilterLabels({
    filters: products.filters,
    payload,
  })

  return (
    <section className={cn(sectionSpacingClass, className)} id={id ? `block-${id}` : undefined}>
      {introContent && (
        <div className={cn('container', introSpacingClass)}>
          <RichText className="ml-0 max-w-3xl" data={introContent} enableGutter={false} />
        </div>
      )}

      <ShopArchiveShell
        className="my-0"
        containerWidth={containerWidth}
        desktopSidebarPosition={desktopSidebarPosition}
        showFilters={showFilters}
        showSearch={showSearch}
        showSort={showSort}
        facetCounts={products.facetCounts}
        filterLabels={filterLabels}
        filters={products.filters}
        sidebarEyebrow={sidebarEyebrow}
        sidebarLayout={sidebarLayout}
        sidebarTitle={sidebarTitle}
        spacing={spacing}
      >
        <ShopProductResults filterLabels={filterLabels} products={products} />
      </ShopArchiveShell>
    </section>
  )
}
