'use client';
import { FunctionComponent, ReactNode } from 'react';
import { Box, Stack } from '@mui/material';
import { APP_FRAME_MAX_WIDTH } from './config';

interface AppFrameProps {
  /** Pinned to the top of the frame; never scrolls with the content. */
  header?: ReactNode;
  /** Pinned to the bottom of the frame (the bottom nav); never scrolls with the content. */
  footer?: ReactNode;
  children: ReactNode;
}

/**
 * The one device frame every shell renders inside — a centered, phone-width column on a canvas
 * that absorbs whatever extra viewport there is. Three structural jobs, and it is the only place
 * any of them are solved:
 *
 *  1. **Width is capped everywhere.** No shell stretches a header, a nav bar, or a content column
 *     across a desktop monitor; a wide window gets more canvas, not a wider app.
 *  2. **The frame owns the scroll, not the document.** Header and footer are flex siblings of a
 *     single scrolling `<main>`, so the top bar needs no `position: fixed` and no page needs a
 *     matching top offset (the source of the old per-shell `pt: TOP_BAR_*` math).
 *  3. **Horizontal scroll is structurally impossible.** `overflowX: hidden` + `minWidth: 0` on the
 *     column means an over-wide child clips instead of dragging the whole app sideways; anything
 *     genuinely wide (a data table) scrolls inside its own container.
 * @layout AppFrame
 */
const AppFrame: FunctionComponent<AppFrameProps> = ({ header, footer, children }) => (
  <Box
    sx={{
      height: '100dvh',
      display: 'flex',
      justifyContent: 'center',
      bgcolor: 'var(--bal-frame-canvas)',
      overflow: 'hidden',
    }}
  >
    <Stack
      sx={{
        width: '100%',
        maxWidth: APP_FRAME_MAX_WIDTH,
        minWidth: 0,
        height: '100%',
        bgcolor: 'background.default',
        // Reads as a hairline seam between app and canvas on a wide window; invisible on a phone,
        // where the frame already fills the viewport edge to edge.
        borderInline: '1px solid',
        borderColor: 'divider',
        overflow: 'hidden',
      }}
    >
      {header ? (
        <Box component="header" sx={{ flexShrink: 0, minWidth: 0 }}>
          {header}
        </Box>
      ) : null}

      <Box
        component="main"
        sx={{
          flexGrow: 1,
          minHeight: 0,
          minWidth: 0,
          overflowY: 'auto',
          overflowX: 'hidden',
          // Keeps a rubber-band scroll at the end of a list from chaining out to the canvas.
          overscrollBehaviorY: 'contain',
        }}
      >
        {children}
      </Box>

      {footer ? (
        <Box component="footer" sx={{ flexShrink: 0, minWidth: 0 }}>
          {footer}
        </Box>
      ) : null}
    </Stack>
  </Box>
);

export default AppFrame;
