using System.ComponentModel;
using System.Linq.Expressions;
using System.Text.Json;
using e_suite.API.Common;
using e_suite.API.Common.models;
using e_suite.API.Common.repository;
using e_suite.Database.Audit.Tables.Audit;
using e_suite.Utilities.Pagination;

namespace e_suite.Modules.AuditLog;

public class AuditLog : IAuditLog
{
    private readonly IAuditLogRepository _auditLogRepository;

    public AuditLog(IAuditLogRepository auditLogRepository)
    {
        _auditLogRepository = auditLogRepository;
    }

    public async Task<IPaginatedData<AuditLogEntry>> GetAuditLogEntries(Paging paging, string? logEntry, bool primaryOnly, CancellationToken cancellationToken)
    {
        AuditParams? auditParams = null;
        if (logEntry != null)
        {
            var buffer = Convert.FromBase64String(logEntry);
            auditParams = JsonSerializer.Deserialize<AuditParams>(buffer);
        }

        var auditEntries = _auditLogRepository.GetAuditEntries(auditParams, primaryOnly);

        var paginatedData =
            await PaginatedData.Paginate<AuditEntry, AuditLogEntry>(auditEntries, paging, KeySelector, cancellationToken);
        return paginatedData;
    }
    
    private Expression<Func<AuditEntry, object>> KeySelector(string? sortKey)
    {
        return sortKey?.ToLowerInvariant() switch
        {
            "id" => x => x.Id,
            "userid" => x => x.AuditLog.UserId,
            "userdisplayname" => x => x.AuditLog.UserDisplayName,
            "type" => x => x.AuditLog.Type,
            "datetime" => x => x.AuditLog.DateTime,
            "fields" => x => x.AuditLog.Fields,
            "comment" => x => x.AuditLog.Comment,
            "entityname" => x => x.EntityName,
            "primarykey" => x => x.PrimaryKey,
            "displayname" => x => x.DisplayName!,
            _ => x => x.AuditLog.DateTime
        };
    }
}