import Header from "@/components/Header";
import Sidebar from "@/components/Sidebar";
import Breadcrumb from "@/components/Breadcrumb";
import { ReactNode } from "react";
import { redirect } from "next/navigation";
// import { getAccessToken } from "@/lib/auth"; // Supprimé, on utilise directement Supabase
import { cookies, headers } from "next/headers";
import { createSbServer } from "@/lib/supabaseServer";
// app/layout.tsx
import "@/styles/cmdk.css";
import { detectDemoModeFromHeaders } from "@/lib/demo-detector";
import { DEMO_USER, DEMO_ORGANIZATION } from "@/lib/demo-data";
import { DemoBanner } from "@/components/DemoBanner";
import { DemoModeProvider } from "@/hooks/useDemoMode";
import { PromoBanner } from "@/components/PromoBanner";

type ClientInfo = {
  id: string;
  name: string;
  api_name?: string;
  user?: {
    id: string;
    email: string;
    display_name?: string;
    first_name?: string;
  } | null;
} | null;

export default async function AppLayout({ children }: { children: ReactNode }) {
  const c = cookies();
  const h = headers();

  // 🎭 Vérification du mode démo AVANT tout traitement d'auth
  const isDemoMode = detectDemoModeFromHeaders(h);
  
  if (isDemoMode) {
    // Mode démo : utiliser des données fictives sans authentification
    const demoClientInfo: ClientInfo = {
      id: DEMO_ORGANIZATION.id,
      name: DEMO_ORGANIZATION.name,
      api_name: DEMO_ORGANIZATION.api_name,
      user: {
        id: DEMO_USER.id,
        email: DEMO_USER.email,
        display_name: DEMO_USER.display_name,
        first_name: DEMO_USER.first_name
      }
    };
    
    console.log("🎭 [LAYOUT] Mode démo actif - Utilisation des données fictives");
    
    return (
      <DemoModeProvider forceDemoMode={true}>
        <div className="min-h-screen">
          {/* Demo Banner */}
          <DemoBanner isDemoMode={true} isPublicDemo={process.env.NODE_ENV === 'production'} />
          
          <div className="min-h-screen md:grid md:grid-cols-[calc(var(--sidebar-w)_+_8px)_1fr]">
            {/* Sidebar flush left */}
            <aside className="hidden md:block sticky top-0 h-screen overflow-y-auto overflow-x-hidden border-r bg-background">
              <Sidebar clientInfo={demoClientInfo} isStaff={false} />
            </aside>

            {/* Main column (header + content) */}
            <div className="flex flex-col min-h-screen min-w-0">
              {/* Header aligned with content column */}
              <header className="m-0 p-0">
                <Header clientInfo={demoClientInfo} isStaff={false} />
              </header>

              {/* Main content area */}
              <main className="p-4 overflow-x-hidden">
                <Breadcrumb />
                {children}
              </main>
            </div>
          </div>
        </div>
      </DemoModeProvider>
    );
  }

  // ⚠️ DEV ONLY : bypass auth si AUTH_BYPASS=1
  if (process.env.NODE_ENV === "development" && process.env.AUTH_BYPASS === "1") {
    // En mode bypass, essayons quand même de récupérer les vraies infos si un utilisateur est connecté
    let realClientInfo: ClientInfo = null;
    let mockIsStaff = false; // Déclarer ici pour qu'elle soit accessible dans tout le bloc
    
    try {
      const sb = createSbServer();
      const { data: { user } } = await sb.auth.getUser();
      
      if (user) {
        // Infos utilisateur (pour afficher le prénom)
        const userInfo = {
          id: user.id,
          email: user.email || '',
          display_name: user.user_metadata?.display_name || user.user_metadata?.full_name || null,
          first_name: user.user_metadata?.first_name || user.user_metadata?.display_name?.split(' ')[0] || null,
        };
        // Vérifier si l'utilisateur est staff
        const { data: staffData } = await sb
          .from("staff_users")
          .select("is_staff")
          .eq("user_id", user.id)
          .maybeSingle();
        
        const isStaff = !!staffData?.is_staff;
        mockIsStaff = isStaff; // Utilise la vraie valeur staff pour le mock
        
        if (isStaff) {
          // Staff : récupérer l'org sélectionnée si disponible
          const activeOrgId = c.get("active_org_id")?.value;
          if (activeOrgId) {
            const { data: org } = await sb
              .from("organizations")
              .select("id, name, structure_api")
              .eq("id", activeOrgId)
              .maybeSingle();
            
            if (org) {
              realClientInfo = {
                id: org.id,
                name: org.name,
                api_name: org.structure_api,
                user: userInfo,
              };
            }
          }
          // Même si aucune organisation active n'est sélectionnée, on veut au moins le prénom
          if (!realClientInfo) {
            realClientInfo = {
              id: "dev-org-id",
              name: "Organisation",
              api_name: undefined,
              user: userInfo,
            };
          }
        } else {
          // Client : récupérer son organisation unique via requête directe
          const { data: memberData, error } = await sb
            .from("organization_members")
            .select(`
              organization:organizations(id, name, structure_api)
            `)
            .eq("user_id", user.id)
            .eq("revoked", false)
            .maybeSingle();
            
          if (!error && memberData?.organization) {
            const org = memberData.organization as any;
            realClientInfo = {
              id: org.id,
              name: org.name,
              api_name: org.structure_api,
              user: userInfo,
            };
          } else {
            // Pas d'organisation associée trouvée, mais on garde le prénom
            realClientInfo = {
              id: "dev-org-id",
              name: "Organisation",
              api_name: undefined,
              user: userInfo,
            };
          }
        }
      }
    } catch (error) {
      console.warn("Impossible de récupérer les vraies infos en mode bypass:", error);
    }
    
    // Utiliser les vraies infos si disponibles, sinon fallback sur le mock
    const mockClientInfo: ClientInfo = realClientInfo || {
      id: "dev-org-id",
      name: "Dev Company",
      api_name: "dev-api",
      user: realClientInfo ? (realClientInfo as any).user : null,
    };
    
    return (
      <div className="min-h-screen md:grid md:grid-cols-[calc(var(--sidebar-w)_+_8px)_1fr]">
        {/* Sidebar flush left */}
        <aside className="hidden md:block sticky top-0 h-screen overflow-y-auto overflow-x-hidden border-r bg-background">
          <Sidebar clientInfo={mockClientInfo} isStaff={mockIsStaff} />
        </aside>

        {/* Main column (header + content) */}
        <div className="flex flex-col min-h-screen min-w-0">
          {/* Header aligned with content column */}
          <header className="m-0 p-0">
            <Header clientInfo={mockClientInfo} isStaff={mockIsStaff} />
          </header>

          {/* Main content area */}
          <main className="p-4 overflow-x-hidden">
            <Breadcrumb />
            {children}
          </main>
        </div>
      </div>
    );
  }

  // Authentification directe via Supabase, sans cookie personnalisé
  const sb = createSbServer();
  const { data: { user } } = await sb.auth.getUser();
  
  if (!user) {
    redirect("/signin");
  }

  // Récupération DIRECTE des infos utilisateur et organisation - 100% server-side
  let isStaff = false;
  let clientInfo: ClientInfo = null;
  let staffOrgInfo: ClientInfo = null;
  
  // Extraire les infos utilisateur pour le partage
  const userInfo = {
    id: user.id,
    email: user.email || '',
    display_name: user.user_metadata?.display_name || user.user_metadata?.full_name || null,
    first_name: user.user_metadata?.first_name || user.user_metadata?.display_name?.split(' ')[0] || null,
  };

  try {
    // 1. Vérifier si l'utilisateur est staff
    const { data: staffData } = await sb
      .from("staff_users")
      .select("is_staff")
      .eq("user_id", user.id)
      .maybeSingle();
    
    isStaff = !!staffData?.is_staff;

    if (isStaff) {
      // Staff : récupérer l'org sélectionnée si disponible
      const activeOrgId = c.get("active_org_id")?.value;
      if (activeOrgId) {
        const { data: org } = await sb
          .from("organizations")
          .select("id, name, structure_api")
          .eq("id", activeOrgId)
          .maybeSingle();
        
        if (org) {
          staffOrgInfo = {
            id: org.id,
            name: org.name,
            api_name: org.structure_api,
            user: userInfo,
          };
        }
      }
      // Si aucune organisation sélectionnée, on passe quand même l'utilisateur pour l'affichage du prénom
      if (!staffOrgInfo) {
        staffOrgInfo = {
          id: "unknown",
          name: "Organisation",
          api_name: undefined,
          user: userInfo,
        };
      }
    } else {
      // Client : récupérer son organisation unique via requête directe
      const { data: memberData, error } = await sb
        .from("organization_members")
        .select(`
          organization:organizations(id, name, structure_api)
        `)
        .eq("user_id", user.id)
        .eq("revoked", false)
        .maybeSingle();
        
      if (!error && memberData?.organization) {
        const org = memberData.organization as any;
        clientInfo = {
          id: org.id,
          name: org.name,
          api_name: org.structure_api,
          user: userInfo,
        };
      } else {
        // Pas d'organisation récupérée, on passe au moins l'utilisateur pour afficher le prénom
        clientInfo = {
          id: "unknown",
          name: "Organisation",
          api_name: undefined,
          user: userInfo,
        };
      }
    }
  } catch (error) {
    console.error("Erreur lors de la récupération des infos organisation:", error);
    // En cas d'erreur, on continue avec des infos nulles
  }

  // Déterminer quelle info afficher
  const displayInfo = isStaff ? staffOrgInfo : clientInfo;

  return (
    <DemoModeProvider forceDemoMode={false}>
      <div className="min-h-screen">
        {/* Bannière promo (hors mode démo) */}
        <PromoBanner />
        
        <div className="min-h-screen md:grid md:grid-cols-[calc(var(--sidebar-w)_+_8px)_1fr]">
          {/* Sidebar flush left */}
          <aside className="hidden md:block sticky top-0 h-screen overflow-y-auto overflow-x-hidden border-r bg-background">
            <Sidebar clientInfo={displayInfo} isStaff={isStaff} />
          </aside>

          {/* Main column (header + content) */}
          <div className="flex flex-col min-h-screen min-w-0">
            {/* Header aligned with content column */}
            <header className="m-0 p-0 sticky top-0 z-40">
              <Header clientInfo={displayInfo} isStaff={isStaff} />
            </header>

            {/* Main content area */}
            <main className="p-4 overflow-x-hidden">
              <Breadcrumb />
              {children}
            </main>
          </div>
        </div>
      </div>
    </DemoModeProvider>
  );
}