import React, { Children } from 'react'
import { View } from '../view'
import { Slot } from '../component-slots'
import { ContentHeader } from '../content-header'
import { PageSection } from '../page-section'
import { PAGE_LAYOUT_REGIONS } from '../component-slots/pageSlotKeys.js'

/**
 * Split page children into layout-region fallbacks (`region="header"`, …) vs
 * unslotted body content for `page.content`.
 *
 * @param {import('react').ReactNode} children
 */
function partitionPageChildren (children) {
  /** @type {Record<string, import('react').ReactNode>} */
  const slotted = Object.fromEntries(PAGE_LAYOUT_REGIONS.map((region) => [region, null]))
  /** @type {import('react').ReactNode[]} */
  const content = []

  Children.forEach(children, (child) => {
    if (child == null || child === false) return
    const region = child.props?.region ?? child.props?.['data-region']
    if (typeof region === 'string' && Object.prototype.hasOwnProperty.call(slotted, region)) {
      slotted[region] = child
      return
    }
    content.push(child)
  })

  return { slotted, content }
}

/**
 * Standard in-app page body inside the shell content slot.
 * Registered `page.*` slots override; otherwise built-in header props and
 * unslotted children are used as fallbacks (see design-system README).
 */
export const Page = ({
  layout = 'page',
  maxWidth,
  scroll = false,
  surface = 'primary',
  inset = 's',
  gap = 's',
  title,
  description,
  near,
  far,
  header,
  children,
  style,
  contentStyle,
  ...viewProps
}) => {
  const { slotted, content } = partitionPageChildren(children)

  const hasBuiltInHeader =
    header != null ||
    title != null ||
    description != null ||
    near != null ||
    far != null

  const headerFallback =
    slotted.header ??
    header ??
    (hasBuiltInHeader ? (
      <ContentHeader
        inset="none"
        title={title}
        description={description}
        near={near}
        far={far}
      />
    ) : null)

  let contentFallback = null
  if (content.length > 0) {
    contentFallback = maxWidth ? (
      <PageSection maxWidth={maxWidth} gap={gap}>
        {content}
      </PageSection>
    ) : (
      content
    )
  }

  return (
    <View
      surface={surface}
      layout={layout}
      inset={inset}
      gap={gap}
      data-page-scroll={scroll ? 'internal' : 'external'}
      style={{
        ...(scroll
          ? {
              // Fill workspace (or any height-locked) <main> — page owns nested scroll.
              flex: '1 1 0%',
              height: '100%',
              width: '100%',
              minHeight: 0,
              overflow: 'hidden',
            }
          : { minHeight: '100%' }),
        ...style,
      }}
      {...viewProps}
    >
      <Slot region="header" view="page.header" fallback={headerFallback} />
      <Slot region="sidebar-primary" view="page.sidebar-primary" fallback={slotted['sidebar-primary']} />
      <Slot region="sidebar-secondary" view="page.sidebar-secondary" fallback={slotted['sidebar-secondary']} />
      <Slot
        region="content"
        view="page.content"
        fallback={contentFallback}
        style={{
          ...(scroll ? { overflow: 'auto', minHeight: 0 } : undefined),
          ...contentStyle,
        }}
      />
      <Slot region="footer" view="page.footer" fallback={slotted.footer} />
    </View>
  )
}
