"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
var AuditService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AuditService = void 0;
const common_1 = require("@nestjs/common");
const typeorm_1 = require("@nestjs/typeorm");
const typeorm_2 = require("typeorm");
const audit_log_entity_1 = require("../database/entities/audit-log.entity");
const api_log_entity_1 = require("../database/entities/api-log.entity");
let AuditService = AuditService_1 = class AuditService {
    constructor(auditLogRepo, apiLogRepo) {
        this.auditLogRepo = auditLogRepo;
        this.apiLogRepo = apiLogRepo;
        this.logger = new common_1.Logger(AuditService_1.name);
    }
    async log(params) {
        const auditLog = this.auditLogRepo.create({
            userId: params.userId || null,
            businessId: params.businessId || null,
            action: params.action,
            entityType: params.entityType,
            entityId: params.entityId || null,
            previousValue: params.previousValue || null,
            newValue: params.newValue || null,
            ipAddress: params.ipAddress || null,
            userAgent: params.userAgent || null,
        });
        this.logger.debug(`Audit log: ${params.action} on ${params.entityType}${params.entityId ? `#${params.entityId}` : ''}`);
        return this.auditLogRepo.save(auditLog);
    }
    async logApi(method, url, statusCode, durationMs, requestBody, responseBody, ipAddress, userAgent, businessId) {
        const apiLog = this.apiLogRepo.create({
            businessId: businessId || null,
            method,
            url: url.length > 500 ? url.substring(0, 500) : url,
            statusCode,
            durationMs,
            requestBody: requestBody || null,
            responseBody: responseBody || null,
            ipAddress: ipAddress || null,
            userAgent: userAgent || null,
        });
        return this.apiLogRepo.save(apiLog);
    }
    async getAuditLogs(filters) {
        const page = filters.page ?? 1;
        const limit = filters.limit ?? 20;
        const where = {};
        if (filters.businessId) {
            where.businessId = filters.businessId;
        }
        if (filters.userId) {
            where.userId = filters.userId;
        }
        if (filters.action) {
            where.action = filters.action;
        }
        if (filters.entityType) {
            where.entityType = filters.entityType;
        }
        if (filters.entityId) {
            where.entityId = filters.entityId;
        }
        if (filters.startDate && filters.endDate) {
            where.createdAt = (0, typeorm_2.Between)(new Date(filters.startDate), new Date(filters.endDate));
        }
        else if (filters.startDate) {
            where.createdAt = (0, typeorm_2.MoreThanOrEqual)(new Date(filters.startDate));
        }
        else if (filters.endDate) {
            where.createdAt = (0, typeorm_2.LessThanOrEqual)(new Date(filters.endDate));
        }
        const [data, total] = await this.auditLogRepo.findAndCount({
            where,
            order: { createdAt: 'DESC' },
            skip: (page - 1) * limit,
            take: limit,
        });
        return { data, total, page, limit, totalPages: Math.ceil(total / limit) };
    }
    async getApiLogs(filters) {
        const page = filters.page ?? 1;
        const limit = filters.limit ?? 20;
        const where = {};
        if (filters.businessId) {
            where.businessId = filters.businessId;
        }
        if (filters.method) {
            where.method = filters.method.toUpperCase();
        }
        if (filters.url) {
            where.url = filters.url;
        }
        if (filters.statusCode) {
            where.statusCode = filters.statusCode;
        }
        if (filters.startDate && filters.endDate) {
            where.createdAt = (0, typeorm_2.Between)(new Date(filters.startDate), new Date(filters.endDate));
        }
        else if (filters.startDate) {
            where.createdAt = (0, typeorm_2.MoreThanOrEqual)(new Date(filters.startDate));
        }
        else if (filters.endDate) {
            where.createdAt = (0, typeorm_2.LessThanOrEqual)(new Date(filters.endDate));
        }
        const [data, total] = await this.apiLogRepo.findAndCount({
            where,
            order: { createdAt: 'DESC' },
            skip: (page - 1) * limit,
            take: limit,
        });
        return { data, total, page, limit, totalPages: Math.ceil(total / limit) };
    }
    async getEntityHistory(entityType, entityId) {
        return this.auditLogRepo.find({
            where: { entityType, entityId },
            order: { createdAt: 'DESC' },
        });
    }
    async cleanOldLogs(days) {
        const cutoffDate = new Date();
        cutoffDate.setDate(cutoffDate.getDate() - days);
        const auditResult = await this.auditLogRepo
            .createQueryBuilder()
            .delete()
            .where('createdAt < :cutoff', { cutoff: cutoffDate })
            .execute();
        const apiResult = await this.apiLogRepo
            .createQueryBuilder()
            .delete()
            .where('createdAt < :cutoff', { cutoff: cutoffDate })
            .execute();
        const deletedAuditLogs = auditResult.affected || 0;
        const deletedApiLogs = apiResult.affected || 0;
        this.logger.log(`Cleaned logs older than ${days} days: ${deletedAuditLogs} audit logs, ${deletedApiLogs} API logs`);
        return { deletedAuditLogs, deletedApiLogs };
    }
};
exports.AuditService = AuditService;
exports.AuditService = AuditService = AuditService_1 = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, typeorm_1.InjectRepository)(audit_log_entity_1.AuditLog)),
    __param(1, (0, typeorm_1.InjectRepository)(api_log_entity_1.ApiLog)),
    __metadata("design:paramtypes", [typeorm_2.Repository,
        typeorm_2.Repository])
], AuditService);
