import type { ReactNode } from 'react'
import type { ShopFacetCounts } from '@/lib/shop/queryProducts'
import type { ShopFilterLabels } from '@/lib/shop/filterLabels'
import type { ParsedShopSearchParams } from '@/utilities/shopParams'

import { Suspense } from 'react'

import { Search } from '@/components/Search'
import { ShopMobileFilterDrawer } from '@/components/shop/ShopMobileFilterDrawer'
import {
  getLegacySidebarLayout,
  hasConfiguredSidebarLayout,
  type ShopSidebarLayout,
  ShopSidebarControls,
} from '@/components/shop/ShopSidebarControls'
import { cn } from '@/utilities/cn'

type ShopArchiveShellProps = {
  children: ReactNode
  className?: string
  containerWidth?: 'default' | 'full' | 'wide' | null
  desktopSidebarPosition?: 'left' | 'right' | null
  facetCounts?: ShopFacetCounts
  filterLabels?: ShopFilterLabels
  filters?: ParsedShopSearchParams
  showFilters?: boolean | null
  showSearch?: boolean | null
  showSort?: boolean | null
  sidebarEyebrow?: string | null
  sidebarLayout?: null | ShopSidebarLayout
  sidebarTitle?: string | null
  spacing?: 'compact' | 'default' | 'spacious' | null
}

const containerWidthClasses = {
  default: 'container',
  full: 'w-full px-4 md:px-8',
  wide: 'container 2xl:max-w-[96rem]',
}

const spacingClasses = {
  compact: 'gap-6 pb-2',
  default: 'gap-8 pb-4',
  spacious: 'gap-10 pb-8',
}

function SearchFallback() {
  return (
    <div className="relative w-full">
      <div className="h-12 w-full animate-pulse rounded-2xl border bg-neutral-100 dark:border-neutral-800 dark:bg-neutral-900" />
    </div>
  )
}

function MobileFilterDrawerFallback() {
  return (
    <div className="md:hidden">
      <div className="h-12 w-full animate-pulse rounded-xl border bg-neutral-100 dark:border-neutral-800 dark:bg-neutral-900" />
    </div>
  )
}

export function ShopArchiveShell({
  children,
  className,
  containerWidth = 'default',
  desktopSidebarPosition = 'left',
  facetCounts,
  filterLabels,
  filters,
  showFilters = true,
  showSearch = true,
  showSort = true,
  sidebarEyebrow,
  sidebarLayout,
  sidebarTitle,
  spacing = 'default',
}: ShopArchiveShellProps) {
  const hasConfiguredSidebar = hasConfiguredSidebarLayout(sidebarLayout)
  const resolvedSidebarLayout = hasConfiguredSidebar
    ? sidebarLayout
    : getLegacySidebarLayout({
        showFilters,
        showSort,
      })
  const hasSidebar = resolvedSidebarLayout.length > 0
  const resolvedContainerWidth = containerWidth || 'default'
  const resolvedSidebarPosition = desktopSidebarPosition || 'left'
  const resolvedSpacing = spacing || 'default'
  const resolvedSidebarEyebrow = sidebarEyebrow ?? 'Katalog'
  const resolvedSidebarTitle = sidebarTitle?.trim() ? sidebarTitle : 'Filter Produk'
  const shouldRenderLegacyTopSearch = !hasConfiguredSidebar && showSearch !== false
  const renderControls = () => (
    <ShopSidebarControls
      facetCounts={facetCounts}
      filterLabels={filterLabels}
      filters={filters}
      sidebarEyebrow={resolvedSidebarEyebrow}
      sidebarLayout={resolvedSidebarLayout}
      sidebarTitle={resolvedSidebarTitle}
    />
  )

  return (
    <div
      className={cn(
        containerWidthClasses[resolvedContainerWidth],
        'flex flex-col my-16',
        spacingClasses[resolvedSpacing],
        className,
      )}
    >
      {shouldRenderLegacyTopSearch && (
        <Suspense fallback={<SearchFallback />}>
          <Search className="mb-8" />
        </Suspense>
      )}

      {hasSidebar && (
        <Suspense fallback={<MobileFilterDrawerFallback />}>
          <ShopMobileFilterDrawer>{renderControls()}</ShopMobileFilterDrawer>
        </Suspense>
      )}

      <div
        className={cn(
          'flex flex-col items-start justify-between gap-10 md:gap-8',
          hasSidebar ? 'md:flex-row' : 'md:block',
          hasSidebar && resolvedSidebarPosition === 'right' ? 'md:flex-row-reverse' : null,
        )}
      >
        {hasSidebar && (
          <aside className="hidden md:sticky md:top-24 md:block md:w-[15.75rem] md:shrink-0 lg:w-[16.5rem]">
            <div className="overflow-hidden rounded-xl border border-[#dbe8d7] bg-[#fbfcf8] shadow-sm">
              <div className="p-4">{renderControls()}</div>
            </div>
          </aside>
        )}
        <div className="min-h-screen w-full min-w-0 flex-1">{children}</div>
      </div>
    </div>
  )
}
