/**
 * User repository — cloud-agnostic datastore operations.
 */

import { getCollection } from '@/lib/datastore';
import { PRODUCT_ID } from '@/lib/product-config';
import type { BaseDocument, DocumentCollection } from '@bytelyst/datastore';

export interface UserDoc extends BaseDocument {
  email: string;
  name: string;
  passwordHash: string;
  role: 'super_admin' | 'admin' | 'viewer' | 'user';
  plan: 'free' | 'pro' | 'enterprise';
  status: 'active' | 'inactive' | 'suspended';
  createdAt: string;
  lastActive: string;
  totalTokensUsed: number;
  totalRequests: number;
  monthlySpend: number;
}

export type UserResponse = Omit<UserDoc, 'passwordHash'>;

function collection(): DocumentCollection<UserDoc> {
  return getCollection<UserDoc>('users', '/id');
}

function stripPassword(doc: UserDoc): UserResponse {
  const { passwordHash: _hash, ...rest } = doc;
  void _hash;
  return rest;
}

export async function getUserById(id: string): Promise<UserDoc | null> {
  return collection().findById(id, id);
}

export async function getUserByEmail(
  email: string,
  productId = PRODUCT_ID
): Promise<UserDoc | null> {
  return collection().findOne({
    filter: { productId, email: email.toLowerCase() },
  });
}

export async function listUsers(
  limit = 100,
  offset = 0,
  productId = PRODUCT_ID
): Promise<UserResponse[]> {
  const resources = await collection().findMany({
    filter: { productId },
    sort: { createdAt: -1 },
    offset,
    limit,
  });
  return resources.map(stripPassword);
}

export async function createUser(doc: UserDoc): Promise<UserResponse> {
  const resource = await collection().create({
    ...doc,
    email: doc.email.toLowerCase(),
  });
  return stripPassword(resource);
}

export async function updateUser(
  id: string,
  updates: Partial<Omit<UserDoc, 'id' | 'email' | 'passwordHash'>>
): Promise<UserResponse | null> {
  const existing = await getUserById(id);
  if (!existing) return null;

  const updated = await collection().update(id, id, {
    ...updates,
    lastActive: new Date().toISOString(),
  });
  return stripPassword(updated);
}

export async function deleteUser(id: string): Promise<boolean> {
  try {
    await collection().delete(id, id);
    return true;
  } catch {
    return false;
  }
}

export async function countUsers(productId = PRODUCT_ID): Promise<number> {
  return collection().count({ productId });
}

export async function countUsersByPlan(productId = PRODUCT_ID): Promise<Record<string, number>> {
  const resources = await collection().aggregate<{ plan: string; count: number }>({
    groupBy: 'plan',
    aggregations: [{ field: 'id', op: 'count', alias: 'count' }],
    filter: { productId },
  });
  const result: Record<string, number> = { free: 0, pro: 0, enterprise: 0 };
  for (const r of resources) {
    result[r.plan] = r.count;
  }
  return result;
}
