'use client';

import { useEffect, useState, type ComponentProps, type ReactNode } from 'react';

import { Sidebar } from '@/components/layout/sidebar';
import { Topbar } from '@/components/layout/topbar';
import { MobileLayout } from '@/components/layout/mobile/mobile-layout';

type SidebarProps = ComponentProps<typeof Sidebar>;
type TopbarProps = ComponentProps<typeof Topbar>;

interface AppShellProps {
  portRoles: SidebarProps['portRoles'];
  isSuperAdmin: boolean;
  user: NonNullable<SidebarProps['user']>;
  ports: TopbarProps['ports'];
  /**
   * Server-rendered form-factor hint (from the request User-Agent). The
   * shell mounts the matching tree on first render so we never paint the
   * wrong shell, and only switches if the runtime viewport matchMedia
   * disagrees (e.g. desktop browser resized below lg).
   */
  initialFormFactor: 'mobile' | 'desktop';
  children: ReactNode;
}

const MOBILE_QUERY = '(max-width: 1023.98px)';

/**
 * #26: single-tree responsive shell. Pre-fix the layout mounted BOTH
 * desktop and mobile shells in the DOM and CSS-hid one — doubling React
 * state, fetches, Tabs providers, and a11y landmarks. AppShell decides
 * once per render which tree to mount, so a page only ever runs the
 * effects + queries it actually displays.
 *
 * SSR safety: the server passes its UA-classified hint via `initialFormFactor`;
 * the first client render uses the same value so hydration matches. After
 * mount, a matchMedia subscription overrides if the viewport disagrees.
 */
export function AppShell({
  portRoles,
  isSuperAdmin,
  user,
  ports,
  initialFormFactor,
  children,
}: AppShellProps) {
  const [isMobile, setIsMobile] = useState(initialFormFactor === 'mobile');

  useEffect(() => {
    const mq = window.matchMedia(MOBILE_QUERY);
    const update = () => setIsMobile(mq.matches);
    update();
    mq.addEventListener('change', update);
    return () => mq.removeEventListener('change', update);
  }, []);

  if (isMobile) {
    return <MobileLayout>{children}</MobileLayout>;
  }

  return (
    <div className="flex h-screen overflow-hidden bg-background">
      <Sidebar portRoles={portRoles} isSuperAdmin={isSuperAdmin} user={user} ports={ports} />
      <div className="flex-1 flex flex-col overflow-hidden min-w-0">
        <Topbar ports={ports} user={user} />
        <main className="flex-1 overflow-y-auto bg-background px-6 pt-3 pb-6">{children}</main>
      </div>
    </div>
  );
}
