import { ApiKeyRepository } from '../models/repositories/ApiKeyRepository';
import { AppError } from '../utils/AppError';
import { generateUuid } from '../utils/uuid';
import { generateToken, hashSha256 } from '../utils/crypto';

export class ApiKeyService {
  constructor(private apiKeyRepo = new ApiKeyRepository()) {}

  async list(userId: string) {
    const keys = await this.apiKeyRepo.findByUserId(userId);
    return keys.map((k) => ({
      id: k.id,
      name: k.name,
      keyPrefix: k.keyPrefix,
      scopes: k.scopes,
      expiresAt: k.expiresAt?.toISOString() ?? null,
      lastUsedAt: k.lastUsedAt?.toISOString() ?? null,
      createdAt: k.createdAt.toISOString(),
    }));
  }

  async create(userId: string, name: string, scopes: string[], expiresAt?: Date) {
    const rawKey = `cal_live_${generateToken(24)}`;
    const keyHash = hashSha256(rawKey);
    const keyPrefix = rawKey.slice(0, 12);

    const apiKey = await this.apiKeyRepo.create({
      id: generateUuid(),
      userId,
      name,
      keyPrefix,
      keyHash,
      scopes,
      expiresAt: expiresAt ?? null,
      isActive: true,
    });

    return { apiKey, rawKey };
  }

  async revoke(userId: string, id: string) {
    const keys = await this.apiKeyRepo.findByUserId(userId);
    const key = keys.find((k) => k.id === id);
    if (!key) throw new AppError('not_found', 404, 'API key not found.');
    await this.apiKeyRepo.revoke(id);
  }
}
