import { cookies } from 'next/headers';
import { eq, count, and, gt } from 'drizzle-orm';
import { db } from '@/db/client';
import { adminUsers, adminSessions, AdminRole } from '@/db/schema';
import { randomBytes } from 'crypto';
import { sha256Hex } from './password';

export type SessionUser = {
  id: number;
  email: string;
  name?: string | null;
  role: AdminRole;
};

const SESSION_COOKIE = 'session';
const SESSION_TTL_DAYS = 7;

export async function hasAnyAdmin(): Promise<boolean> {
  const [row] = await db.select({ c: count() }).from(adminUsers).limit(1);
  return (row?.c ?? 0) > 0;
}

export async function getCurrentUser(): Promise<SessionUser | null> {
  const cookieStore = await cookies();
  const token = cookieStore.get(SESSION_COOKIE)?.value;
  if (!token) return null;
  const tokenHash = sha256Hex(token);
  const now = new Date();
  const rows = await db
    .select({
      id: adminUsers.id,
      email: adminUsers.email,
      name: adminUsers.name,
      role: adminUsers.role,
    })
    .from(adminSessions)
    .innerJoin(adminUsers, eq(adminUsers.id, adminSessions.userId))
    .where(and(eq(adminSessions.tokenHash, tokenHash), gt(adminSessions.expiresAt, now)))
    .limit(1);
  if (!rows.length) return null;
  const u = rows[0];
  return { id: u.id, email: u.email, name: u.name, role: (u.role as AdminRole) };
}

export async function createSession(userId: number) {
  const token = randomBytes(32).toString('hex');
  const tokenHash = sha256Hex(token);
  const expiresAt = new Date(Date.now() + SESSION_TTL_DAYS * 24 * 60 * 60 * 1000);

  await db.insert(adminSessions).values({ userId, tokenHash, expiresAt });

  const cookieStore = await cookies();
  cookieStore.set(SESSION_COOKIE, token, {
    httpOnly: true,
    secure: true,
    sameSite: 'lax',
    path: '/',
    expires: expiresAt,
  });
}

export async function clearSession() {
  const cookieStore = await cookies();
  const token = cookieStore.get(SESSION_COOKIE)?.value;
  if (token) {
    const tokenHash = sha256Hex(token);
    await db.delete(adminSessions).where(eq(adminSessions.tokenHash, tokenHash));
  }
  cookieStore.delete(SESSION_COOKIE);
}

export async function requireAuth(): Promise<SessionUser> {
  const user = await getCurrentUser();
  if (!user) throw new Error('UNAUTHORIZED');
  return user;
}

export async function requireSuperAdmin(): Promise<SessionUser> {
  const user = await requireAuth();
  if (user.role !== 'super') throw new Error('FORBIDDEN');
  return user;
}

