import type { AuditLog } from '@prisma/client';
import type { IAuditLogRepository, AuditLogFilter } from '../repositories/interfaces.js';
import { NotFoundError } from './mcp-server.service.js';

export interface AuditLogQueryParams {
  userId?: string;
  action?: string;
  resource?: string;
  resourceId?: string;
  since?: string;
  until?: string;
  limit?: number;
  offset?: number;
}

/** Default retention: 90 days */
const DEFAULT_RETENTION_DAYS = 90;

export class AuditLogService {
  constructor(
    private readonly repo: IAuditLogRepository,
    private readonly retentionDays: number = DEFAULT_RETENTION_DAYS,
  ) {}

  async list(params?: AuditLogQueryParams): Promise<{ logs: AuditLog[]; total: number }> {
    const filter = this.buildFilter(params);
    const [logs, total] = await Promise.all([
      this.repo.findAll(filter),
      this.repo.count(filter),
    ]);
    return { logs, total };
  }

  async getById(id: string): Promise<AuditLog> {
    const log = await this.repo.findById(id);
    if (!log) {
      throw new NotFoundError(`Audit log '${id}' not found`);
    }
    return log;
  }

  async create(data: {
    userId: string;
    action: string;
    resource: string;
    resourceId?: string;
    details?: Record<string, unknown>;
  }): Promise<AuditLog> {
    return this.repo.create(data);
  }

  async purgeExpired(): Promise<number> {
    const cutoff = new Date();
    cutoff.setDate(cutoff.getDate() - this.retentionDays);
    return this.repo.deleteOlderThan(cutoff);
  }

  private buildFilter(params?: AuditLogQueryParams): AuditLogFilter | undefined {
    if (!params) return undefined;
    const filter: AuditLogFilter = {};

    if (params.userId !== undefined) filter.userId = params.userId;
    if (params.action !== undefined) filter.action = params.action;
    if (params.resource !== undefined) filter.resource = params.resource;
    if (params.resourceId !== undefined) filter.resourceId = params.resourceId;
    if (params.since !== undefined) filter.since = new Date(params.since);
    if (params.until !== undefined) filter.until = new Date(params.until);
    if (params.limit !== undefined) filter.limit = params.limit;
    if (params.offset !== undefined) filter.offset = params.offset;

    return filter;
  }
}
