import { NextResponse } from "next/server";
import { createHash } from "crypto";
import { getServiceSupabase } from "@/lib/supabase/client";

export const runtime = "nodejs";

function hashToken(token: string): string {
  return createHash("sha256").update(token).digest("hex");
}

export async function POST(request: Request) {
  try {
    const body = (await request.json()) as {
      token?: string;
      email?: string;
      password?: string;
    };

    const token = body.token || "";
    const email = (body.email || "").trim().toLowerCase();
    const password = body.password || "";

    if (!token || !email || !password) {
      return NextResponse.json(
        { error: "Token, email, and password are required" },
        { status: 400 }
      );
    }

    if (password.length < 8) {
      return NextResponse.json(
        { error: "Password must be at least 8 characters" },
        { status: 400 }
      );
    }

    const supabase = getServiceSupabase();
    const tokenHash = hashToken(token);
    const now = new Date().toISOString();

    // Find valid token with user info
    const { data: resetTokenRaw } = await supabase
      .from("password_reset_tokens")
      .select("id, user_id, users(email, name)")
      .eq("token_hash", tokenHash)
      .eq("used", false)
      .gt("expires_at", now)
      .maybeSingle();

    const resetToken = resetTokenRaw as
      | {
          id: string;
          user_id: string;
          users?:
            | {
                email?: string;
                name?: string;
              }
            | Array<{
                email?: string;
                name?: string;
              }>;
        }
      | null;

    if (!resetToken) {
      return NextResponse.json(
        { error: "Invalid or expired reset token" },
        { status: 400 }
      );
    }

    // Get user email from the nested users object
    const userEmail = Array.isArray(resetToken.users)
      ? resetToken.users[0]?.email
      : resetToken.users?.email;
    const userName = Array.isArray(resetToken.users)
      ? resetToken.users[0]?.name
      : resetToken.users?.name;

    if (userEmail?.toLowerCase() !== email) {
      return NextResponse.json({ error: "Invalid reset token" }, { status: 400 });
    }

    // Update Supabase Auth password. If auth user doesn't exist yet (legacy migration),
    // create it with the same UUID so app foreign keys remain valid.
    const { error: updateError } = await supabase.auth.admin.updateUserById(resetToken.user_id, {
      password,
    });

    if (updateError) {
      const updateMessage = updateError.message || "";
      if (updateMessage.toLowerCase().includes("not found")) {
        const { error: createError } = await supabase.auth.admin.createUser({
          id: resetToken.user_id,
          email,
          password,
          email_confirm: true,
          user_metadata: {
            name: typeof userName === "string" && userName.trim().length > 0 ? userName : undefined,
          },
        });
        if (createError) throw createError;
      } else {
        throw updateError;
      }
    }

    // Mark token as used
    await supabase
      .from("password_reset_tokens")
      .update({ used: true })
      .eq("id", resetToken.id);

    // Delete all sessions for this user (force re-login)
    await supabase.from("sessions").delete().eq("user_id", resetToken.user_id);

    return NextResponse.json({
      success: true,
      message: "Password reset successfully",
    });
  } catch (error) {
    console.error("Reset password error:", error);
    return NextResponse.json({ error: "Failed to reset password" }, { status: 500 });
  }
}
