'use server';

import { cookies } from 'next/headers';
import { revalidatePath } from 'next/cache';
import { getCurrentUser } from '@/lib/auth';
import { prisma } from '@/lib/prisma';

export interface SessionRow {
  id: string;
  tokenSuffix: string;
  isCurrent: boolean;
  createdAt: string;
  expiresAt: string;
}

/**
 * List the current user's active (unexpired) sessions. Tokens are
 * hashed-by-truncation in the response: we expose only the last 8 hex
 * characters so the user can identify "the one I'm on right now"
 * without us having to round-trip the full opaque token to the
 * browser. The current-session flag is the authoritative way to tell
 * which row is "this device" — the suffix is just a UX hint.
 */
export async function listMySessions(): Promise<SessionRow[]> {
  const user = await getCurrentUser();
  if (!user) return [];

  const cookieStore = await cookies();
  const currentToken = cookieStore.get('sessionToken')?.value ?? null;

  const rows = await prisma.session.findMany({
    where: { userId: user.id, expiresAt: { gt: new Date() } },
    orderBy: { createdAt: 'desc' },
    select: {
      id: true,
      token: true,
      createdAt: true,
      expiresAt: true,
    },
  });

  return rows.map((r) => ({
    id: r.id,
    tokenSuffix: r.token.slice(-8),
    isCurrent: r.token === currentToken,
    createdAt: r.createdAt.toISOString(),
    expiresAt: r.expiresAt.toISOString(),
  }));
}

/**
 * Revoke a single session by id. Refused if the target id is the
 * actor's current session — use `signOut` for that flow instead.
 */
export async function revokeSession(
  sessionId: string,
): Promise<{ success?: true; error?: string }> {
  const user = await getCurrentUser();
  if (!user) return { error: 'Not signed in.' };

  const cookieStore = await cookies();
  const currentToken = cookieStore.get('sessionToken')?.value ?? null;

  const target = await prisma.session.findUnique({
    where: { id: sessionId },
    select: { userId: true, token: true },
  });
  if (!target) return { error: 'Session not found.' };
  if (target.userId !== user.id) return { error: 'Not your session.' };
  if (target.token === currentToken) {
    return {
      error:
        'Cannot revoke your current session this way. Use Sign out instead.',
    };
  }

  await prisma.session.delete({ where: { id: sessionId } });
  revalidatePath('/main/settings');
  return { success: true };
}

/** Revoke every session for the current user except the current one. */
export async function revokeAllOtherSessions(): Promise<{
  success?: true;
  error?: string;
  revoked?: number;
}> {
  const user = await getCurrentUser();
  if (!user) return { error: 'Not signed in.' };

  const cookieStore = await cookies();
  const currentToken = cookieStore.get('sessionToken')?.value ?? null;

  const result = await prisma.session.deleteMany({
    where: {
      userId: user.id,
      ...(currentToken ? { NOT: { token: currentToken } } : {}),
    },
  });
  revalidatePath('/main/settings');
  return { success: true, revoked: result.count };
}
