'use client';
import { FunctionComponent, useCallback, useMemo } from 'react';
import { Badge, ButtonBase, Stack } from '@mui/material';
import { LinkToPage } from '@/utils';
import { AppIcon } from '@/components';
import { usePathname, useRouter } from '@/i18n/navigation';
import { FLOATING_BAR_SX } from '../config';
import { matchActivePath } from '../matchActivePath';

interface Props {
  items: Array<LinkToPage>;
}

const ICON_SIZE = 23;
/** Comfortable-touch size for an icon-only target (WCAG 2.5.8 asks for ≥24px; 44px is the iOS/Material ask). */
const TAB_SIZE = 44;

/**
 * The app's only navigation surface: a bottom tab bar carrying one destination per top-level
 * area. It replaced the drawer + hamburger outright — on a phone-width frame a drawer hides the
 * whole information architecture behind a tap and gives the top bar a job it doesn't need.
 *
 * **Icon-only.** The caption under each icon is gone: at five tabs inside a 480px frame the
 * Persian labels («حرفهٔ من», «درخواست‌ها») were the widest thing in the bar and forced a two-line
 * bar to carry one line of meaning. The icon set is already distinct, every tab keeps its label as
 * `aria-label`/`title`, and the active tab is unambiguous from the filled pill — so the text was
 * paying rent in the one place vertical space is scarcest.
 *
 * Each tab is a `ButtonBase` (not MUI's `BottomNavigation`) so the whole target IS the indicator: a
 * fixed-size circle that hover, press, focus ring and the active fill all share, rather than a
 * rectangular ripple squaring off against the rounded bar behind it. Circles are laid out with
 * `space-around` instead of `flex: 1` so the target keeps one size whatever the tab count is. The
 * transition reads through `--bal-motion-fast`, so the app-wide reduced-motion gate (globals.css)
 * already collapses it.
 *
 * Locale-aware via the `@/i18n/navigation` wrapper (no manual `/${locale}` prefixing), with the
 * shared `matchActivePath` longest-prefix helper deciding the active tab, so a nested route
 * (`/patients/123`) still lights up its parent.
 * @component BottomBar
 */
const BottomBar: FunctionComponent<Props> = ({ items }) => {
  const router = useRouter();
  const pathname = usePathname();

  // A tab can claim paths outside its own subtree (`matchPaths`), so the longest-prefix match runs
  // over every claimed path and the winner is mapped back to the tab that claimed it.
  const activePath = useMemo(() => {
    const claims = items.flatMap((item) =>
      !item.path ? [] : [item.path, ...(item.matchPaths ?? [])].map((claimed) => ({ claimed, tab: item.path as string }))
    );
    const winner = matchActivePath(pathname, claims.map((claim) => claim.claimed));
    return claims.find((claim) => claim.claimed === winner)?.tab;
  }, [items, pathname]);

  const onSelect = useCallback(
    (item: LinkToPage) => {
      if (item.onSelect) {
        item.onSelect();
        return;
      }
      if (item.path) router.push(item.path);
    },
    [router]
  );

  return (
    // The bar floats: it is inset from the frame edges and fully rounded, so the page background
    // runs behind and around it instead of the bar sealing off the bottom of the screen with an
    // edge-to-edge slab. It is pinned over the scrolling <main> by AppFrame, which reserves exactly
    // `BOTTOM_NAV_HEIGHT` of bottom padding so no screen's content ever ends up underneath it.
    <Stack
      component="nav"
      direction="row"
      sx={{
        mx: 1.5,
        mt: 0.5,
        marginBottom: 'calc(env(safe-area-inset-bottom) + 10px)',
        p: 0.75,
        justifyContent: 'space-around',
        alignItems: 'center',
        ...FLOATING_BAR_SX,
      }}
    >
      {items.map((item) => {
        const isActive = Boolean(item.path) && item.path === activePath;
        return (
          <ButtonBase
            key={`${item.title}-${item.path}`}
            onClick={() => onSelect(item)}
            aria-current={isActive ? 'page' : undefined}
            aria-label={item.title}
            title={item.title}
            sx={{
              flexShrink: 0,
              width: TAB_SIZE,
              height: TAB_SIZE,
              borderRadius: '50%',
              bgcolor: isActive ? 'var(--bal-primary-soft)' : 'transparent',
              transition: 'background-color var(--bal-motion-fast) var(--bal-easing-standard)',
              '&:hover': { bgcolor: 'var(--bal-primary-soft)' },
            }}
          >
            <Badge
              badgeContent={item.badgeCount ?? 0}
              max={99}
              invisible={!item.badgeCount}
              sx={{ '& .MuiBadge-badge': { bgcolor: 'var(--bal-error)', color: 'var(--bal-error-contrast)' } }}
            >
              <AppIcon
                icon={item.icon}
                size={ICON_SIZE}
                color={isActive ? 'var(--bal-primary)' : 'var(--bal-text-secondary)'}
                strokeWidth={isActive ? 2.2 : 1.75}
              />
            </Badge>
          </ButtonBase>
        );
      })}
    </Stack>
  );
};

export default BottomBar;
