// app/api/access/[memberId]/revoke/route.ts
export const dynamic = "force-dynamic";
import { NextResponse } from "next/server";
import { cookies, headers } from "next/headers";
import { createRouteHandlerClient } from "@supabase/auth-helpers-nextjs";
import { createClient } from "@supabase/supabase-js";
import { sendAccessRevokedEmail } from "@/lib/emailMigrationHelpers";
import { getUserPermissions, canModifyUser } from "@/lib/permissions";

type OrgRecord = { id: string };
type MemberRecord = { role: string; revoked: boolean };

async function resolveOrgId(sb: ReturnType<typeof createRouteHandlerClient>): Promise<string | null> {
  const h = headers();
  const c = cookies();

  // 1) Déterminer l'utilisateur et s'il est staff
  try {
    const { data: { user } } = await sb.auth.getUser();
    if (!user) return null;

    const { data: staffData } = await sb.from('staff_users').select('is_staff').eq('user_id', user.id).maybeSingle();
    const isStaff = !!(staffData as any)?.is_staff;

    if (!isStaff) {
      // Client: utiliser get_my_org (source de vérité)
      try {
        const { data: myOrgRaw } = await sb.rpc('get_my_org').maybeSingle();
        const myOrg = (myOrgRaw as OrgRecord | null) ?? null;
        if (myOrg?.id) return myOrg.id;
      } catch {}
    }
  } catch {}

  // 2) Fallbacks staff et génériques (cookies/headers)
  const serverCookieOrgId = c.get('active_org_id')?.value;
  if (serverCookieOrgId) return serverCookieOrgId;

  const activeOrgKey = c.get('active_org_key')?.value;
  if (activeOrgKey) {
    const { data } = await sb.from('organizations').select('id').eq('structure_api', activeOrgKey).maybeSingle();
    const org = (data as OrgRecord | null) ?? null;
    if (org?.id) return org.id;
  }

  const nameB64 = c.get('active_org_name_b64')?.value;
  if (nameB64) {
    try {
      const decoded = Buffer.from(nameB64, 'base64').toString('utf8');
      const { data } = await sb.from('organizations').select('id').eq('name', decoded).maybeSingle();
      const org = (data as OrgRecord | null) ?? null;
      if (org?.id) return org.id;
    } catch {}
  }

  const fromHeader = h.get('x-active-org-id');
  if (fromHeader) return fromHeader;

  let name = h.get('x-company-name') || '';
  if (!name) {
    const b64 = h.get('x-company-name-b64');
    if (b64) {
      try { name = Buffer.from(b64, 'base64').toString('utf8'); } catch {}
    }
  }
  if (name) {
    const { data } = await sb.from('organizations').select('id').eq('name', name).maybeSingle();
    const org = (data as OrgRecord | null) ?? null;
    if (org?.id) return org.id;
  }

  return null;
}

async function guardRole(sb: ReturnType<typeof createRouteHandlerClient>, org_id: string) {
  const { data: { user } } = await sb.auth.getUser();
  if (!user) return false;
  
  const { data: meRow } = await sb
    .from("organization_members")
    .select("role,revoked")
    .eq("org_id", org_id)
    .eq("user_id", user.id)
    .maybeSingle();
  const me = (meRow as MemberRecord | null) ?? null;
    
  return !!me && !me.revoked && ["ADMIN", "SUPER_ADMIN"].includes(me.role);
}

export async function POST(_req: Request, { params }: { params: { memberId: string } }) {
  console.log("📥 POST revoke - memberId:", params.memberId);
  
  const sb = createRouteHandlerClient({ cookies });
  let org_id = await resolveOrgId(sb);

  // If no org_id resolved, allow staff callers to operate by resolving the member's org.
  if (!org_id) {
    // detect staff
    const { data: { user } } = await sb.auth.getUser();
    if (!user) {
      console.log("❌ Aucun utilisateur authentifié");
      return new NextResponse("Unauthorized", { status: 401 });
    }
    let isStaff = false;
    try {
      const { data: staffData } = await sb.from('staff_users').select('is_staff').eq('user_id', user.id).maybeSingle();
      isStaff = !!staffData?.is_staff;
    } catch {}

    if (!isStaff) {
      console.log("❌ Aucune organisation active");
      return new NextResponse("no_active_org", { status: 400 });
    }

    // Resolve the target member's org
    try {
      const { data: memberRow } = await sb.from('organization_members').select('org_id').eq('user_id', params.memberId).maybeSingle();
      org_id = (memberRow as any)?.org_id || null;
    } catch (e) {
      org_id = null;
    }
  }

  if (!org_id) {
    console.log("❌ Impossible de résoudre l'organisation du membre");
    return new NextResponse("no_active_org", { status: 400 });
  }

  if (!(await guardRole(sb, org_id))) {
    console.log("❌ Accès refusé");
    return new NextResponse("Forbidden", { status: 403 });
  }

  const admin = createClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!, 
    process.env.SUPABASE_SERVICE_ROLE_KEY!, 
    { auth: { autoRefreshToken: false, persistSession: false }}
  );
  
  // Vérifier le rôle de l'utilisateur ciblé pour empêcher ADMIN de révoquer SUPER_ADMIN
  let targetRole: string | null = null;
  try {
    const { data: targetMember } = await admin
      .from('organization_members')
      .select('role')
      .eq('org_id', org_id)
      .eq('user_id', params.memberId)
      .is('revoked', false)
      .maybeSingle();
    targetRole = (targetMember as any)?.role || null;
  } catch {}

  const permissions = await getUserPermissions(sb);
  if (!permissions) {
    return new NextResponse("Unauthorized", { status: 401 });
  }
  
  if (targetRole && !canModifyUser(permissions, targetRole as any)) {
    console.log("❌ Permission refusée: impossible de révoquer un utilisateur", targetRole);
    return new NextResponse("Forbidden - Vous ne pouvez pas révoquer cet utilisateur", { status: 403 });
  }
  
  const { error } = await admin.from("organization_members")
    .update({ revoked: true, revoked_at: new Date().toISOString() })
    .eq("org_id", org_id).eq("user_id", params.memberId);
    
  if (error) {
    console.log("❌ Erreur révocation:", error.message);
    return NextResponse.json({ error: error.message }, { status: 400 });
  }

  // Récupérer email + prénom de l'utilisateur révoqué pour notification
  try {
    const { data: userData } = await admin.auth.admin.getUserById(params.memberId);
    const userEmail = userData?.user?.email || undefined;
    const firstName = userData?.user?.user_metadata?.first_name || undefined;

    // Récupérer nom d'organisation et acteur
    const { data: orgRow } = await admin.from('organizations').select('name').eq('id', org_id).maybeSingle();
    const { data: { user: actor } } = await createRouteHandlerClient({ cookies }).auth.getUser();
    const revokedBy = actor?.email || 'Administrateur';

    if (userEmail) {
      await sendAccessRevokedEmail(userEmail, {
        firstName: firstName || '',
        organizationName: String(orgRow?.name || ''),
        userEmail,
        revocationDate: new Date().toLocaleString('fr-FR'),
        revokedBy,
      });
    }
  } catch (e) {
    console.warn('⚠️ Envoi email révocation échoué (non-bloquant):', (e as any)?.message || e);
  }

  console.log("✅ Utilisateur révoqué");
  return NextResponse.json({ ok: true });
}
