/**
 * Login Session Creation Test
 * Verifies that user sessions are created and appear in Security tab
 */

import { prisma } from "@/lib/db";
import { createSession, getUserSessions } from "@/lib/services/session-manager";

// Requires live database and session service - skip in unit test environment
describe.skip("Login Session Creation", () => {
  const testUserId = "test-user-id-" + Date.now();
  const testEmail = `test-${Date.now()}@example.com`;

  beforeAll(async () => {
    // Create test user
    await prisma.users.create({
      data: {
        id: testUserId,
        email: testEmail,
        name: "Test User",
        password: "hashed-password",
      },
    });
  });

  afterAll(async () => {
    // Cleanup
    await prisma.user_sessions.deleteMany({
      where: { userId: testUserId },
    });
    await prisma.users.delete({
      where: { id: testUserId },
    });
  });

  afterEach(async () => {
    // Clean up sessions after each test
    await prisma.user_sessions.deleteMany({
      where: { userId: testUserId },
    });
  });

  test("should create session on password login", async () => {
    const token = "test-token-123";
    const ipAddress = "192.168.1.100";
    const userAgent =
      "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 Chrome/120.0.0.0";

    // Create session (simulates what happens in login API)
    await createSession(testUserId, token, ipAddress, userAgent);

    // Verify session was created
    const sessions = await getUserSessions(testUserId);

    expect(sessions).toHaveLength(1);
    expect(sessions[0]).toMatchObject({
      userId: testUserId,
      token,
      ipAddress,
      deviceType: "desktop",
    });
    expect(sessions[0].deviceName).toContain("Chrome");
    expect(sessions[0].deviceName).toContain("macOS");
  });

  test("should create session on OTP login", async () => {
    const token = "otp-token-456";
    const ipAddress = "10.0.0.50";
    const userAgent =
      "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) Safari/604.1";

    await createSession(testUserId, token, ipAddress, userAgent);

    const sessions = await getUserSessions(testUserId);

    expect(sessions).toHaveLength(1);
    expect(sessions[0]).toMatchObject({
      userId: testUserId,
      token,
      ipAddress,
      deviceType: "mobile",
    });
    expect(sessions[0].deviceName).toContain("Safari");
    expect(sessions[0].deviceName).toContain("iOS");
  });

  test("should list multiple active sessions", async () => {
    // Create multiple sessions
    await createSession(
      testUserId,
      "token-1",
      "192.168.1.1",
      "Chrome on Windows",
    );
    await createSession(
      testUserId,
      "token-2",
      "192.168.1.2",
      "Safari on macOS",
    );
    await createSession(
      testUserId,
      "token-3",
      "192.168.1.3",
      "Firefox on Linux",
    );

    const sessions = await getUserSessions(testUserId);

    expect(sessions).toHaveLength(3);
    expect(sessions.map((s) => s.token)).toEqual(
      expect.arrayContaining(["token-1", "token-2", "token-3"]),
    );
  });

  test("should limit to 10 sessions per user", async () => {
    // Create 12 sessions (exceeds limit of 10)
    for (let i = 1; i <= 12; i++) {
      await createSession(
        testUserId,
        `token-${i}`,
        `192.168.1.${i}`,
        "Test Browser",
      );
    }

    const sessions = await getUserSessions(testUserId);

    // Should only have 10 sessions (oldest ones deleted)
    expect(sessions.length).toBeLessThanOrEqual(10);
  });

  test("should include location data when available", async () => {
    const token = "token-with-location";
    const ipAddress = "8.8.8.8"; // Google DNS - will have location data
    const userAgent = "Chrome on macOS";

    await createSession(testUserId, token, ipAddress, userAgent);

    const sessions = await getUserSessions(testUserId);

    expect(sessions).toHaveLength(1);
    // Location might be populated depending on geolocation service
    expect(sessions[0]).toHaveProperty("location");
    expect(sessions[0]).toHaveProperty("country");
    expect(sessions[0]).toHaveProperty("city");
  });

  test("should track last active time", async () => {
    const token = "active-session";
    const ipAddress = "192.168.1.100";
    const userAgent = "Test Browser";

    await createSession(testUserId, token, ipAddress, userAgent);

    const sessions = await getUserSessions(testUserId);

    expect(sessions).toHaveLength(1);
    expect(sessions[0].lastActive).toBeInstanceOf(Date);

    // Verify lastActive is recent (within last minute)
    const timeDiff = Date.now() - new Date(sessions[0].lastActive).getTime();
    expect(timeDiff).toBeLessThan(60000); // Less than 1 minute
  });
});
