import { Injectable } from '@nestjs/common';
import { PrismaService } from '../../prisma/prisma.service';
import { FindAuditLogsDto } from './dto/find-audit-logs.dto';

export interface AuditLogRow {
  id: string;
  userId: string | null;
  clubId: string | null;
  action: string;
  entity: string;
  entityId: string | null;
  oldData: unknown;
  newData: unknown;
  ipAddress: string | null;
  createdAt: Date;
}

@Injectable()
export class AuditService {
  constructor(private readonly prisma: PrismaService) {}

  async findAll(params: FindAuditLogsDto) {
    const { search, userId, clubId, action, limit = 50, offset = 0 } = params;

    await this.prisma.resetTenantId();

    const conditions: string[] = [];
    const values: unknown[] = [];
    let paramIndex = 1;

    if (search) {
      conditions.push(
        `(entity ILIKE $${paramIndex} OR action ILIKE $${paramIndex})`,
      );
      values.push(`%${search}%`);
      paramIndex++;
    }

    if (userId) {
      conditions.push(`"userId" = $${paramIndex}`);
      values.push(userId);
      paramIndex++;
    }

    if (clubId) {
      conditions.push(`"clubId" = $${paramIndex}`);
      values.push(clubId);
      paramIndex++;
    }

    if (action) {
      conditions.push(`action = $${paramIndex}`);
      values.push(action);
      paramIndex++;
    }

    const whereClause =
      conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';

    const countQuery = `SELECT COUNT(*) as total FROM audit_logs ${whereClause}`;
    const countResult = await this.prisma.$queryRawUnsafe<{ total: bigint }[]>(
      countQuery,
      ...values,
    );
    const total = Number(countResult[0]?.total ?? 0);

    const dataQuery = `
      SELECT id, "userId", "clubId", action, entity, "entityId",
             "oldData", "newData", "ipAddress", "createdAt"
      FROM audit_logs
      ${whereClause}
      ORDER BY "createdAt" DESC
      LIMIT $${paramIndex} OFFSET $${paramIndex + 1}
    `;

    const data = await this.prisma.$queryRawUnsafe<AuditLogRow[]>(
      dataQuery,
      ...values,
      limit,
      offset,
    );

    return { data, total };
  }
}
