import { NextResponse } from "next/server";
import { createClient } from "@supabase/supabase-js";
import { cookies } from "next/headers";
import { createRouteHandlerClient } from "@supabase/auth-helpers-nextjs";
import { SESClient, SendEmailCommand } from "@aws-sdk/client-ses";
import { promises as fs } from "fs";
import path from "path";

type OrgRow = { id: string; name: string; structure_api?: string | null };
type MemberRow = { role: string; revoked: boolean };

// Types de rôles autorisés (alignés avec public.role)
const ROLES = ["SUPER_ADMIN","ADMIN","AGENT","COMPTA"] as const;
type Role = typeof ROLES[number];

export async function POST(req: Request) {
  console.log("🚀 [API] /api/access/nouveau - Début de la requête");
  
  try {
    // Log des headers de la requête
    console.log("📋 [API] Headers reçus:", {
      'content-type': req.headers.get('content-type'),
      'cookie': req.headers.get('cookie') ? 'Présent' : 'Absent',
      'authorization': req.headers.get('authorization') ? 'Présent' : 'Absent',
    });

    const body = await req.json();
    console.log("📝 [API] Body reçu:", { 
      email: body.email, 
      firstName: body.firstName, 
      orgId: body.orgId, 
      role: body.role 
    });

    const email = String(body.email || "").trim().toLowerCase();
    const firstName = String(body.firstName || "").trim();
    const requestedOrgId = String(body.orgId || "").trim();
    const requestedRole = String(body.role || "").trim().toUpperCase() as Role;

    console.log("🔧 [API] Données normalisées:", {
      email,
      firstName,
      requestedOrgId,
      requestedRole
    });

    if (!email || !requestedRole || !ROLES.includes(requestedRole)) {
      console.log("❌ [API] Validation échouée - données invalides");
      return NextResponse.json({ error: "invalid_input" }, { status: 400 });
    }

    // Vérifier les variables d'environnement
    console.log("🔑 [API] Variables d'environnement:", {
      supabaseUrl: process.env.NEXT_PUBLIC_SUPABASE_URL ? 'Définie' : 'Manquante',
      anonKey: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY ? 'Définie' : 'Manquante',
      serviceKey: process.env.SUPABASE_SERVICE_ROLE_KEY ? 'Définie' : 'Manquante'
    });

    // Utiliser createRouteHandlerClient pour une meilleure compatibilité
    console.log("🔐 [API] Création du client Supabase...");
    const sb = createRouteHandlerClient({ cookies });

    // 1) Auth caller
    console.log("👤 [API] Tentative de récupération de l'utilisateur...");
    const { data: { user }, error: userError } = await sb.auth.getUser();
    
    if (userError) {
      console.log("❌ [API] Erreur lors de la récupération de l'utilisateur:", userError);
      return NextResponse.json({ error: "auth_error", message: userError.message }, { status: 401 });
    }
    
    if (!user) {
      console.log("❌ [API] Aucun utilisateur trouvé dans la session");
      // Essayons de voir s'il y a une session
      const { data: { session }, error: sessionError } = await sb.auth.getSession();
      console.log("🔍 [API] Vérification de la session:", {
        sessionExists: !!session,
        sessionError: sessionError?.message,
        userId: session?.user?.id
      });
      return NextResponse.json({ error: "unauthorized" }, { status: 401 });
    }

    console.log("✅ [API] Utilisateur authentifié:", {
      id: user.id,
      email: user.email,
      metadata: user.user_metadata
    });

    // 2) Is staff?
    console.log("🏢 [API] Vérification du statut staff...");
    const { data: staff, error: staffError } = await sb
      .from("staff_users")
      .select("is_staff")
      .eq("user_id", user.id)
      .maybeSingle();
      
    if (staffError) {
      console.log("❌ [API] Erreur lors de la vérification staff:", staffError);
    }
    
    const isStaff = !!staff?.is_staff;
    console.log("👔 [API] Statut staff:", { isStaff, staffData: staff });

    // 3) Resolve target org
    let targetOrgId = requestedOrgId;
    console.log("🏛️ [API] Résolution de l'organisation cible...");

    if (!isStaff) {
      console.log("🧑‍💼 [API] Utilisateur client - vérification de l'organisation...");
      
      // Pour les clients : utiliser l'orgId demandé s'il est fourni, sinon fallback sur cookie/get_my_org
      if (requestedOrgId) {
        console.log("🎯 [API] Organisation spécifiquement demandée:", requestedOrgId);
        targetOrgId = requestedOrgId;
      } else {
        console.log("🍪 [API] Aucune organisation demandée, utilisation du cookie/get_my_org...");
        // Préférer active_org_id cookie si présent, sinon RPC get_my_org
        const cookiesStore = cookies();
        const cookieOrg = cookiesStore.get("active_org_id")?.value;
        console.log("🍪 [API] Cookie active_org_id:", cookieOrg || "Absent");
        
        if (cookieOrg) targetOrgId = cookieOrg;
        
        if (!targetOrgId) {
          console.log("🔍 [API] Tentative de récupération via get_my_org...");
          const { data: myOrgRaw, error: orgError } = await sb.rpc("get_my_org").maybeSingle();
          const myOrg = (myOrgRaw as OrgRow | null) ?? null;
          
          if (orgError) {
            console.log("❌ [API] Erreur get_my_org:", orgError);
          }
          
          console.log("🏛️ [API] Résultat get_my_org:", myOrg);
          if (myOrg?.id) targetOrgId = myOrg.id;
        }
      }
      
      console.log("🎯 [API] Organisation cible résolue:", targetOrgId);
      
      if (!targetOrgId) {
        console.log("❌ [API] Aucune organisation trouvée pour le client");
        return NextResponse.json({ error: "org_missing", message: "Aucune organisation active" }, { status: 400 });
      }

      // Check membership + role dans l'organisation cible (pas forcément celle du cookie)
      console.log("🔐 [API] Vérification des permissions du membre dans l'organisation:", targetOrgId);
      const { data: memberRow, error: memberError } = await sb
        .from("organization_members")
        .select("role, revoked")
        .eq("user_id", user.id)
        .eq("org_id", targetOrgId)
        .maybeSingle();
      const member = (memberRow as MemberRow | null) ?? null;
        
      if (memberError) {
        console.log("❌ [API] Erreur lors de la vérification du membre:", memberError);
      }
      
      console.log("👥 [API] Données du membre:", member);
        
      if (!member || member.revoked) {
        console.log("❌ [API] Membre non trouvé ou révoqué dans l'organisation:", targetOrgId);
        return NextResponse.json({ error: "forbidden", message: "Pas membre actif de l'organisation demandée" }, { status: 403 });
      }
      
      if (!(member.role === "ADMIN" || member.role === "SUPER_ADMIN")) {
        console.log("❌ [API] Rôle insuffisant:", member.role);
        return NextResponse.json({ error: "forbidden", message: "Rôle insuffisant (ADMIN requis)" }, { status: 403 });
      }
      
      // Non-staff cannot assign SUPER_ADMIN
      if (requestedRole === "SUPER_ADMIN") {
        console.log("❌ [API] Tentative d'assignation SUPER_ADMIN par un client");
        return NextResponse.json({ error: "forbidden_role", message: "SUPER_ADMIN interdit pour les clients" }, { status: 403 });
      }
      
      console.log("✅ [API] Permissions validées pour le client dans l'organisation:", targetOrgId);
    } else {
      console.log("👨‍💼 [API] Utilisateur staff");
      // Staff: require an org id in input
      if (!targetOrgId) {
        console.log("❌ [API] orgId manquant pour le staff");
        return NextResponse.json({ error: "org_required", message: "orgId requis pour le staff" }, { status: 400 });
      }
      console.log("✅ [API] Organisation fournie par le staff:", targetOrgId);
    }

    // 4) Verify organization exists (safe even with RLS)
    console.log("🏢 [API] Vérification de l'existence de l'organisation...");
    const { data: orgRow, error: orgExistsError } = await sb
      .from("organizations")
      .select("id,name,structure_api")
      .eq("id", targetOrgId)
      .maybeSingle();
    const org = (orgRow as OrgRow | null) ?? null;
      
    if (orgExistsError) {
      console.log("❌ [API] Erreur lors de la vérification de l'organisation:", orgExistsError);
    }
    
    console.log("🏛️ [API] Organisation trouvée:", org);
    if (!org) {
      console.log("❌ [API] Organisation non trouvée pour l'ID:", targetOrgId);
      return NextResponse.json({ error: "org_not_found" }, { status: 404 });
    }

    // 5.b) Client admin Supabase (service role) — nécessaire pour generateLink
    console.log("🔧 [API] Création du client admin Supabase (service role)...");
    const admin = createClient(
      process.env.NEXT_PUBLIC_SUPABASE_URL!,
      process.env.SUPABASE_SERVICE_ROLE_KEY!, // server-side only
      { auth: { autoRefreshToken: false, persistSession: false } }
    );
    // 6) Générer un lien d'invitation (sans envoi d'e-mail par Supabase)
    console.log("🔗 [API] Génération du lien d'invitation (Supabase Admin)...");
    const origin = process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000";
    const { data: linkData, error: linkErr } = await (admin.auth.admin as any).generateLink({
      type: "invite",
      email,
      options: { redirectTo: `${origin}/auth/callback` },
      data: {
        first_name: firstName || null,
        role: requestedRole,
        org_id: org.id,
        org_name: org.name,
        structure_api: (org as any).structure_api ?? null,
      },
    });
    if (linkErr) {
      console.log("❌ [API] Erreur generateLink:", linkErr);
      return NextResponse.json({ error: "invite_link_failed", message: linkErr.message }, { status: 400 });
    }

    const actionLink: string | undefined =
      (linkData as any)?.properties?.action_link || (linkData as any)?.action_link;

    if (!actionLink) {
      console.log("❌ [API] Lien d'invitation introuvable dans la réponse generateLink");
      return NextResponse.json({ error: "no_action_link" }, { status: 400 });
    }

    // 6.b) Récupérer / créer l'utilisateur pour attacher l'adhésion
    const newUserId = (linkData as any)?.user?.id;
    if (!newUserId) {
      console.log("❌ [API] ID utilisateur manquant dans generateLink");
      return NextResponse.json({ error: "invite_failed" }, { status: 400 });
    }

    // 6.c) Envoyer l'email via AWS SES (HTML + texte)
    console.log("📧 [API] Envoi de l'e-mail d'invitation via SES...");
    const region = process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION;
    const fromEmail = process.env.AWS_SES_FROM;
    if (!region || !fromEmail) {
      console.log("❌ [API] Config SES manquante", { regionDefined: !!region, fromDefined: !!fromEmail });
      return NextResponse.json({ error: "ses_misconfigured" }, { status: 500 });
    }
    const ses = new SESClient({ region });

    const subject = "Votre accès à l’Espace Paie Odentas";
    const templatePath = path.join(process.cwd(), "templates-mails", "invite.html");
    let htmlBody = await fs.readFile(templatePath, "utf8");
    htmlBody = htmlBody
      .replace(/{{firstName}}/g, firstName || "")
      .replace(/{{orgName}}/g, org.name)
      .replace(/{{email}}/g, email)
      .replace(/{{role}}/g, requestedRole)
      .replace(/{{structureApi}}/g, (org as any).structure_api ?? "-")
      .replace(/{{actionLink}}/g, actionLink);
    const textBody = `Bienvenue sur l’Espace Paie Odentas
- Organisation : ${org.name}
- Structure API : ${(org as any).structure_api ?? "-"}
- Rôle : ${requestedRole}

Activez votre compte : ${actionLink}
`;

    await ses.send(new SendEmailCommand({
      Source: fromEmail,
      Destination: { ToAddresses: [email] },
      Message: {
        Subject: { Data: subject, Charset: "UTF-8" },
        Body: {
          Html: { Data: htmlBody, Charset: "UTF-8" },
          Text: { Data: textBody, Charset: "UTF-8" },
        },
      },
    }));
    console.log("✅ [API] Email d'invitation envoyé via SES");

    // 7) Attach membership
    console.log("👥 [API] Création de l'adhésion à l'organisation...");
    const { error: memberErr } = await admin
      .from("organization_members")
      .insert({ org_id: org.id, user_id: newUserId, role: requestedRole, revoked: false });
      
    if (memberErr) {
      console.log("❌ [API] Erreur lors de la création de l'adhésion:", memberErr);
      return NextResponse.json({ error: "attach_failed", message: memberErr.message }, { status: 400 });
    }
    
    console.log("✅ [API] Adhésion créée avec succès");

    // 8) Default auth prefs
    console.log("⚙️ [API] Configuration des préférences d'authentification...");
    const { error: authPrefsError } = await admin
      .from("user_auth_prefs")
      .upsert({ user_id: newUserId, allow_magic_link: true, allow_password: false });
      
    if (authPrefsError) {
      console.log("⚠️ [API] Erreur lors de la configuration des préférences (non bloquant):", authPrefsError);
    } else {
      console.log("✅ [API] Préférences d'authentification configurées");
    }

    // Build final response payload
    const responsePayload = {
      ok: true,
      user_id: newUserId,
      email,
      org: { id: org.id, name: org.name, structure_api: (org as any).structure_api ?? null },
      role: requestedRole,
    };
    
    console.log("🎉 [API] Succès - Réponse:", responsePayload);
    return NextResponse.json(responsePayload);
  } catch (e: any) {
    console.error("💥 [API] Erreur critique:", {
      message: e?.message,
      stack: e?.stack,
      name: e?.name
    });
    return NextResponse.json({ error: "server_error", message: e?.message || "Internal Server Error" }, { status: 500 });
  }
}