/**
 * User Sessions API
 * GET - List all active sessions for current user
 */

import { NextRequest, NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { convexQuery } from "@/lib/convex-client";
import { applyRateLimit, rateLimiters } from "@/lib/rate-limiter";
import { maskIPAddress } from "@/lib/services/session-manager";
import { getAuthenticatedEmail } from "@/lib/utils/auth-helpers.util";
import { cookies } from "next/headers";
import type {
  ConvexUser,
  ConvexUserSession,
} from "@/lib/types/convex-entities";

/**
 * GET /api/user/sessions
 * Returns all active sessions for the current user
 * Rate limited to 30 requests per 15 minutes
 */
export async function GET(request: NextRequest) {
  try {
    const userEmail = await getAuthenticatedEmail(request, auth);

    if (!userEmail) {
      return NextResponse.json(
        { success: false, error: "Unauthorized" },
        { status: 401 },
      );
    }

    // Get user from Convex
    const user = await convexQuery<ConvexUser>("auth/queries:getUserByEmail", {
      email: userEmail,
    });

    if (!user) {
      return NextResponse.json(
        { success: false, error: "User not found" },
        { status: 404 },
      );
    }

    // Rate limiting (bypass in development to avoid HMR issues)
    const isDevelopment = process.env.NODE_ENV === "development";

    if (!isDevelopment) {
      const rateLimitResponse = await applyRateLimit(
        request,
        rateLimiters.authGeneral,
      );
      if (rateLimitResponse) return rateLimitResponse;
    }

    // Get all sessions from Convex
    const sessions =
      (await convexQuery<ConvexUserSession[]>("auth/queries:listUserSessions", {
        userId: user._id,
      })) ?? [];

    // Get current session token from cookies to identify which session is active
    const cookieStore = await cookies();
    const currentSessionToken =
      cookieStore.get("auth_token")?.value ||
      cookieStore.get("next-auth.session-token")?.value ||
      null;

    // Get current IP to also match by IP if token isn't available
    const currentIp =
      request.headers.get("x-forwarded-for") ||
      request.headers.get("x-real-ip") ||
      "127.0.0.1";

    // Format sessions for response
    const formattedSessions = sessions.map((s, index) => ({
      id: s._id,
      deviceName: s.deviceName,
      deviceType: s.deviceType,
      location: s.location,
      ipAddress: maskIPAddress(s.ipAddress),
      lastActive: s.lastActive,
      createdAt: s.createdAt,
      // Mark as current if token matches OR if it's the most recent session from current IP
      isCurrent:
        (currentSessionToken && s.token === currentSessionToken) ||
        (!currentSessionToken && s.ipAddress === currentIp && index === 0),
    }));

    return NextResponse.json({
      success: true,
      sessions: formattedSessions,
      total: formattedSessions.length,
    });
  } catch (error) {
    console.error("[API] Failed to fetch sessions:", error);
    return NextResponse.json(
      { success: false, error: "Failed to fetch sessions" },
      { status: 500 },
    );
  }
}
