import { BannerBlock } from '@/blocks/Banner/Component'
import { CallToActionBlock } from '@/blocks/CallToAction/Component'
import { ContentBlock } from '@/blocks/Content/Component'
import { MediaBlock } from '@/blocks/MediaBlock/Component'
import { ShopArchiveBlock } from '@/blocks/ShopArchive/Component'
import { toKebabCase } from '@/utilities/toKebabCase'
import React, { Fragment } from 'react'

import type { Shop } from '../payload-types'
import type { SearchParams } from '@/utilities/shopParams'

const blockComponents = {
  banner: BannerBlock,
  content: ContentBlock,
  cta: CallToActionBlock,
  mediaBlock: MediaBlock,
  shopArchive: ShopArchiveBlock,
}

export const RenderShopBlocks: React.FC<{
  blocks: NonNullable<Shop['layout']>
  searchParams: SearchParams
}> = ({ blocks, searchParams }) => {
  if (!Array.isArray(blocks) || blocks.length === 0) {
    return null
  }

  return (
    <Fragment>
      {blocks.map((block, index) => {
        const { blockName, blockType } = block

        if (!blockType || !(blockType in blockComponents)) {
          return null
        }

        const Block = blockComponents[blockType]

        if (!Block) {
          return null
        }

        const blockID = blockName ? toKebabCase(blockName) : undefined

        if (blockType === 'shopArchive') {
          const renderedID =
            blockID ??
            (typeof block.id === 'string' || typeof block.id === 'number' ? block.id : undefined)

          return (
            <ShopArchiveBlock key={index} {...block} id={renderedID} searchParams={searchParams} />
          )
        }

        return (
          <div className="my-16" key={index}>
            {/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */}
            {/* @ts-ignore - shared block component unions are wider than this shop block map */}
            <Block id={blockID} {...block} />
          </div>
        )
      })}
    </Fragment>
  )
}
