import { NextResponse } from "next/server";
import { cookies } from "next/headers";
import { createRouteHandlerClient } from "@supabase/auth-helpers-nextjs";
import { createClient } from "@supabase/supabase-js";
import { sendInvitationWithActivationEmail } from "@/lib/emailMigrationHelpers";

const ROLES = ["SUPER_ADMIN","ADMIN","AGENT","COMPTA"] as const;
type Role = typeof ROLES[number];

export async function POST(req: Request) {
  try {
    const sb = createRouteHandlerClient({ cookies });
    const { data: { user } } = await sb.auth.getUser();
    if (!user) return new NextResponse("Unauthorized", { status: 401 });

    const { data: staff } = await sb
      .from("staff_users")
      .select("is_staff")
      .eq("user_id", user.id)
      .maybeSingle();

    if (!staff?.is_staff) return new NextResponse("Forbidden", { status: 403 });

    const body = await req.json();
    const email = String(body.email || "").trim().toLowerCase();
    const firstName = String(body.firstName || "").trim();
    const orgId = String(body.orgId || "").trim();
    const role = String(body.role || "").trim().toUpperCase() as Role;

    if (!email || !orgId || !ROLES.includes(role)) {
      return NextResponse.json({ error: "invalid_input" }, { status: 400 });
    }

    const { data: org } = await sb
      .from("organizations")
      .select("id,name,structure_api")
      .eq("id", orgId)
      .maybeSingle();
    if (!org) return NextResponse.json({ error: "org_not_found" }, { status: 404 });

    const admin = createClient(
      process.env.NEXT_PUBLIC_SUPABASE_URL!,
      process.env.SUPABASE_SERVICE_ROLE_KEY!,
      { auth: { autoRefreshToken: false, persistSession: false } }
    );

    const origin = process.env.NEXT_PUBLIC_BASE_URL || "https://paie.odentas.fr";
    const signinUrl = `${origin}/signin`;

    // Metadata partagée côté auth
    const metadata = {
      first_name: firstName || null,
      role,
      org_id: org.id,
      org_name: org.name,
      structure_api: org.structure_api ?? null,
    };

    // Vérifier si l'utilisateur existe déjà (RPC utilitaire find_user_by_email)
    const { data: existingUserRow } = await admin
      .rpc("find_user_by_email", { email_param: email })
      .maybeSingle();

    let newUserId: string | undefined = (existingUserRow as any)?.id;

    if (newUserId) {
      // Mettre à jour les métadonnées et marquer comme vérifié
      await admin.auth.admin.updateUserById(newUserId, {
        email_confirm: true,
        user_metadata: { ...(((existingUserRow as any)?.user_metadata) || {}), ...metadata },
      });
    } else {
      const { data: createData, error: createError } = await admin.auth.admin.createUser({
        email,
        email_confirm: true,
        user_metadata: metadata,
      });

      if (createError || !createData?.user?.id) {
        return NextResponse.json({ error: createError?.message || "create_failed" }, { status: 400 });
      }
      newUserId = createData.user.id;
    }

    const { error: memberErr } = await admin
      .from("organization_members")
      .upsert({ org_id: orgId, user_id: newUserId, role }, { onConflict: "org_id,user_id" });
    if (memberErr) {
      return NextResponse.json({ error: memberErr.message }, { status: 400 });
    }

    await admin
      .from("user_auth_prefs")
      .upsert({ user_id: newUserId, allow_magic_link: true, allow_password: false });

    try {
      const inviterName = (user.user_metadata as any)?.first_name || user.email || 'Administrateur';
      const inviterStatus = staff?.is_staff ? 'Staff' : 'Utilisateur';

      await sendInvitationWithActivationEmail(email, {
        firstName: firstName || undefined,
        organizationName: org.name,
        activationUrl: signinUrl,
        role,
        inviterName,
        inviterStatus,
      });
    } catch (emailErr) {
      console.warn('⚠️ Envoi email invitation échoué (non-bloquant):', (emailErr as any)?.message || emailErr);
    }

    return NextResponse.json({
      ok: true,
      user_id: newUserId,
      email,
      org: { id: org.id, name: org.name },
      role,
    });
  } catch (e: any) {
    return new NextResponse(e?.message || "Internal Server Error", { status: 500 });
  }
}
