import { redirect } from 'next/navigation';
import { headers } from 'next/headers';
import { eq } from 'drizzle-orm';

import { auth } from '@/lib/auth';
import { db } from '@/lib/db';
import { ports as portsTable } from '@/lib/db/schema/ports';
import { userPortRoles, userProfiles } from '@/lib/db/schema/users';
import { QueryProvider } from '@/providers/query-provider';
import { SocketProvider } from '@/providers/socket-provider';
import { PortProvider } from '@/providers/port-provider';
import { PermissionsProvider } from '@/providers/permissions-provider';
import { AppShell } from '@/components/layout/app-shell';
import { RealtimeToasts } from '@/components/shared/realtime-toasts';
import { WebVitalsReporter } from '@/components/shared/web-vitals-reporter';
import { classifyFormFactor } from '@/lib/form-factor';

export default async function DashboardLayout({ children }: { children: React.ReactNode }) {
  const headerList = await headers();
  const session = await auth.api.getSession({ headers: headerList });
  if (!session?.user) redirect('/login');

  // Super admins have implicit access to every port; everyone else only sees
  // ports they have an explicit user_port_roles row for.
  const profile = await db.query.userProfiles.findFirst({
    where: eq(userProfiles.userId, session.user.id),
  });

  const portRoles = await db.query.userPortRoles.findMany({
    where: eq(userPortRoles.userId, session.user.id),
    with: { port: true, role: true },
  });

  const ports = profile?.isSuperAdmin
    ? await db.query.ports.findMany({ orderBy: portsTable.name })
    : portRoles.map((pr) => pr.port);

  const initialFormFactor = classifyFormFactor(headerList.get('user-agent'));
  const user = {
    name: profile?.displayName ?? session.user.name ?? session.user.email,
    email: session.user.email,
  };

  return (
    <QueryProvider>
      <PortProvider ports={ports} defaultPortId={ports[0]?.id ?? null}>
        <PermissionsProvider>
          <SocketProvider>
            <RealtimeToasts />
            <WebVitalsReporter />
            {/* #26: AppShell mounts ONE responsive tree (desktop OR
             *  mobile) per render — never both — so pages don't pay the
             *  double-state, double-fetch, double-Tabs-provider tax. */}
            <AppShell
              portRoles={portRoles}
              isSuperAdmin={profile?.isSuperAdmin ?? false}
              user={user}
              ports={ports}
              initialFormFactor={initialFormFactor}
            >
              {children}
            </AppShell>
          </SocketProvider>
        </PermissionsProvider>
      </PortProvider>
    </QueryProvider>
  );
}
