using System.Diagnostics;
using Exilion.TradingAtomics;
using Managing.Application.Abstractions.Repositories;
using Managing.Domain.Backtests;
using Managing.Domain.Bots;
using Managing.Domain.Users;
using Managing.Infrastructure.Databases.PostgreSql.Entities;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;

namespace Managing.Infrastructure.Databases.PostgreSql;

public class PostgreSqlBacktestRepository : IBacktestRepository
{
    private readonly ManagingDbContext _context;

    public PostgreSqlBacktestRepository(ManagingDbContext context)
    {
        _context = context;
    }

    // User-specific operations
    public void InsertBacktestForUser(User user, Backtest result)
    {
        ValidateBacktestData(result);
        result.User = user;
        
        var entity = PostgreSqlMappers.Map(result);
        _context.Backtests.Add(entity);
        _context.SaveChanges();
    }

    /// <summary>
    /// Validates that all numeric fields in the backtest are of the correct type
    /// </summary>
    private void ValidateBacktestData(Backtest backtest)
    {
        // Ensure FinalPnl is a valid decimal
        if (backtest.FinalPnl.GetType() != typeof(decimal))
        {
            throw new InvalidOperationException(
                $"FinalPnl must be of type decimal, but got {backtest.FinalPnl.GetType().Name}");
        }

        // Ensure other numeric fields are correct
        if (backtest.GrowthPercentage.GetType() != typeof(decimal))
        {
            throw new InvalidOperationException(
                $"GrowthPercentage must be of type decimal, but got {backtest.GrowthPercentage.GetType().Name}");
        }

        if (backtest.HodlPercentage.GetType() != typeof(decimal))
        {
            throw new InvalidOperationException(
                $"HodlPercentage must be of type decimal, but got {backtest.HodlPercentage.GetType().Name}");
        }

        if (backtest.Score.GetType() != typeof(double))
        {
            throw new InvalidOperationException(
                $"Score must be of type double, but got {backtest.Score.GetType().Name}");
        }

        if (backtest.WinRate.GetType() != typeof(int))
        {
            throw new InvalidOperationException(
                $"WinRate must be of type int, but got {backtest.WinRate.GetType().Name}");
        }
    }

    public IEnumerable<Backtest> GetBacktestsByUser(User user)
    {
        var entities = _context.Backtests
            .AsNoTracking()
            .Include(b => b.User)
            .Where(b => b.UserId == user.Id)
            .ToList();

        return entities.Select(PostgreSqlMappers.Map);
    }

    public async Task<IEnumerable<Backtest>> GetBacktestsByUserAsync(User user)
    {
        var entities = await _context.Backtests
            .AsNoTracking()
            .Include(b => b.User)
            .Where(b => b.UserId == user.Id)
            .ToListAsync()
            .ConfigureAwait(false);

        return entities.Select(PostgreSqlMappers.Map);
    }

    public IEnumerable<Backtest> GetBacktestsByRequestId(string requestId)
    {
        var entities = _context.Backtests
            .AsNoTracking()
            .Where(b => b.RequestId == requestId)
            .ToList();

        return entities.Select(PostgreSqlMappers.Map);
    }

    public async Task<IEnumerable<Backtest>> GetBacktestsByRequestIdAsync(string requestId)
    {
        var entities = await _context.Backtests
            .AsNoTracking()
            .Where(b => b.RequestId == requestId)
            .ToListAsync()
            .ConfigureAwait(false);

        return entities.Select(PostgreSqlMappers.Map);
    }

    public (IEnumerable<LightBacktest> Backtests, int TotalCount) GetBacktestsByRequestIdPaginated(string requestId,
        int page, int pageSize, string sortBy = "score", string sortOrder = "desc")
    {
        var stopwatch = Stopwatch.StartNew();
        
        var baseQuery = _context.Backtests
            .AsNoTracking()
            .Where(b => b.RequestId == requestId);

        var afterQueryMs = stopwatch.ElapsedMilliseconds;
        var totalCount = baseQuery.Count();
        var afterCountMs = stopwatch.ElapsedMilliseconds;

        // Apply sorting
        IQueryable<BacktestEntity> sortedQuery = sortBy.ToLower() switch
        {
            "score" => sortOrder == "desc" 
                ? baseQuery.OrderByDescending(b => b.Score)
                : baseQuery.OrderBy(b => b.Score),
            "finalpnl" => sortOrder == "desc"
                ? baseQuery.OrderByDescending(b => b.FinalPnl)
                : baseQuery.OrderBy(b => b.FinalPnl),
            "winrate" => sortOrder == "desc"
                ? baseQuery.OrderByDescending(b => b.WinRate)
                : baseQuery.OrderBy(b => b.WinRate),
            "growthpercentage" => sortOrder == "desc"
                ? baseQuery.OrderByDescending(b => b.GrowthPercentage)
                : baseQuery.OrderBy(b => b.GrowthPercentage),
            "hodlpercentage" => sortOrder == "desc"
                ? baseQuery.OrderByDescending(b => b.HodlPercentage)
                : baseQuery.OrderBy(b => b.HodlPercentage),
            _ => sortOrder == "desc"
                ? baseQuery.OrderByDescending(b => b.Score)
                : baseQuery.OrderBy(b => b.Score)
        };

        var afterSortMs = stopwatch.ElapsedMilliseconds;
        var entities = sortedQuery
            .Skip((page - 1) * pageSize)
            .Take(pageSize)
            .ToList();
        var afterToListMs = stopwatch.ElapsedMilliseconds;

        Console.WriteLine(
            $"[PostgreSqlBacktestRepo] Query: {afterQueryMs}ms, Count: {afterCountMs - afterQueryMs}ms, Sort: {afterSortMs - afterCountMs}ms, ToList: {afterToListMs - afterSortMs}ms, Total: {afterToListMs}ms");

        var mappedBacktests = entities.Select(entity => new LightBacktest
        {
            Id = entity.Identifier,
            Config = JsonConvert.DeserializeObject<TradingBotConfig>(entity.ConfigJson),
            FinalPnl = entity.FinalPnl,
            WinRate = entity.WinRate,
            GrowthPercentage = entity.GrowthPercentage,
            HodlPercentage = entity.HodlPercentage,
            StartDate = entity.StartDate,
            EndDate = entity.EndDate,
            MaxDrawdown = !string.IsNullOrEmpty(entity.StatisticsJson) 
                ? JsonConvert.DeserializeObject<PerformanceMetrics>(entity.StatisticsJson)?.MaxDrawdown 
                : null,
            Fees = entity.Fees,
            SharpeRatio = !string.IsNullOrEmpty(entity.StatisticsJson)
                ? JsonConvert.DeserializeObject<PerformanceMetrics>(entity.StatisticsJson)?.SharpeRatio != null 
                    ? (double?)JsonConvert.DeserializeObject<PerformanceMetrics>(entity.StatisticsJson).SharpeRatio 
                    : null
                : null,
            Score = entity.Score,
            ScoreMessage = entity.ScoreMessage ?? string.Empty
        });

        return (mappedBacktests, totalCount);
    }

    public async Task<(IEnumerable<LightBacktest> Backtests, int TotalCount)> GetBacktestsByRequestIdPaginatedAsync(
        string requestId, int page, int pageSize, string sortBy = "score", string sortOrder = "desc")
    {
        var stopwatch = Stopwatch.StartNew();
        
        var baseQuery = _context.Backtests
            .AsNoTracking()
            .Where(b => b.RequestId == requestId);

        var afterQueryMs = stopwatch.ElapsedMilliseconds;
        var totalCount = await baseQuery.CountAsync().ConfigureAwait(false);
        var afterCountMs = stopwatch.ElapsedMilliseconds;

        // Apply sorting
        IQueryable<BacktestEntity> sortedQuery = sortBy.ToLower() switch
        {
            "score" => sortOrder == "desc" 
                ? baseQuery.OrderByDescending(b => b.Score)
                : baseQuery.OrderBy(b => b.Score),
            "finalpnl" => sortOrder == "desc"
                ? baseQuery.OrderByDescending(b => b.FinalPnl)
                : baseQuery.OrderBy(b => b.FinalPnl),
            "winrate" => sortOrder == "desc"
                ? baseQuery.OrderByDescending(b => b.WinRate)
                : baseQuery.OrderBy(b => b.WinRate),
            "growthpercentage" => sortOrder == "desc"
                ? baseQuery.OrderByDescending(b => b.GrowthPercentage)
                : baseQuery.OrderBy(b => b.GrowthPercentage),
            "hodlpercentage" => sortOrder == "desc"
                ? baseQuery.OrderByDescending(b => b.HodlPercentage)
                : baseQuery.OrderBy(b => b.HodlPercentage),
            _ => sortOrder == "desc"
                ? baseQuery.OrderByDescending(b => b.Score)
                : baseQuery.OrderBy(b => b.Score)
        };

        var afterSortMs = stopwatch.ElapsedMilliseconds;
        var entities = await sortedQuery
            .Skip((page - 1) * pageSize)
            .Take(pageSize)
            .ToListAsync()
            .ConfigureAwait(false);
        var afterToListMs = stopwatch.ElapsedMilliseconds;

        Console.WriteLine(
            $"[PostgreSqlBacktestRepo] Query: {afterQueryMs}ms, Count: {afterCountMs - afterQueryMs}ms, Sort: {afterSortMs - afterCountMs}ms, ToList: {afterToListMs - afterSortMs}ms, Total: {afterToListMs}ms");

        var mappedBacktests = entities.Select(entity => new LightBacktest
        {
            Id = entity.Identifier,
            Config = JsonConvert.DeserializeObject<TradingBotConfig>(entity.ConfigJson),
            FinalPnl = entity.FinalPnl,
            WinRate = entity.WinRate,
            GrowthPercentage = entity.GrowthPercentage,
            HodlPercentage = entity.HodlPercentage,
            StartDate = entity.StartDate,
            EndDate = entity.EndDate,
            MaxDrawdown = !string.IsNullOrEmpty(entity.StatisticsJson) 
                ? JsonConvert.DeserializeObject<PerformanceMetrics>(entity.StatisticsJson)?.MaxDrawdown 
                : null,
            Fees = entity.Fees,
            SharpeRatio = !string.IsNullOrEmpty(entity.StatisticsJson)
                ? JsonConvert.DeserializeObject<PerformanceMetrics>(entity.StatisticsJson)?.SharpeRatio != null 
                    ? (double?)JsonConvert.DeserializeObject<PerformanceMetrics>(entity.StatisticsJson).SharpeRatio 
                    : null
                : null,
            Score = entity.Score,
            ScoreMessage = entity.ScoreMessage ?? string.Empty
        });

        return (mappedBacktests, totalCount);
    }

    public Backtest GetBacktestByIdForUser(User user, string id)
    {
        var entity = _context.Backtests
            .AsNoTracking()
            .Include(b => b.User)
            .FirstOrDefault(b => b.Identifier == id && b.UserId == user.Id);

        return entity != null ? PostgreSqlMappers.Map(entity) : null;
    }

    public async Task<Backtest> GetBacktestByIdForUserAsync(User user, string id)
    {
        var entity = await _context.Backtests
            .AsNoTracking()
            .Include(b => b.User)
            .FirstOrDefaultAsync(b => b.Identifier == id && b.UserId == user.Id)
            .ConfigureAwait(false);

        return entity != null ? PostgreSqlMappers.Map(entity) : null;
    }

    public void DeleteBacktestByIdForUser(User user, string id)
    {
        var entity = _context.Backtests
            .AsTracking()
            .FirstOrDefault(b => b.Identifier == id && b.UserId == user.Id);

        if (entity != null)
        {
            _context.Backtests.Remove(entity);
            _context.SaveChanges();
        }
    }

    public async Task DeleteBacktestByIdForUserAsync(User user, string id)
    {
        var entity = await _context.Backtests
            .AsTracking()
            .FirstOrDefaultAsync(b => b.Identifier == id && b.UserId == user.Id)
            .ConfigureAwait(false);

        if (entity != null)
        {
            _context.Backtests.Remove(entity);
            await _context.SaveChangesAsync().ConfigureAwait(false);
        }
    }

    public void DeleteBacktestsByIdsForUser(User user, IEnumerable<string> ids)
    {
        var entities = _context.Backtests
            .AsTracking()
            .Where(b => b.UserId == user.Id && ids.Contains(b.Identifier))
            .ToList();

        if (entities.Any())
        {
            _context.Backtests.RemoveRange(entities);
            _context.SaveChanges();
        }
    }

    public async Task DeleteBacktestsByIdsForUserAsync(User user, IEnumerable<string> ids)
    {
        var entities = await _context.Backtests
            .AsTracking()
            .Where(b => b.UserId == user.Id && ids.Contains(b.Identifier))
            .ToListAsync()
            .ConfigureAwait(false);

        if (entities.Any())
        {
            _context.Backtests.RemoveRange(entities);
            await _context.SaveChangesAsync().ConfigureAwait(false);
        }
    }

    public void DeleteAllBacktestsForUser(User user)
    {
        var entities = _context.Backtests
            .AsTracking()
            .Where(b => b.UserId == user.Id)
            .ToList();

        if (entities.Any())
        {
            _context.Backtests.RemoveRange(entities);
            _context.SaveChanges();
        }
    }

    public void DeleteBacktestsByRequestId(string requestId)
    {
        var entities = _context.Backtests
            .AsTracking()
            .Where(b => b.RequestId == requestId)
            .ToList();

        if (entities.Any())
        {
            _context.Backtests.RemoveRange(entities);
            _context.SaveChanges();
        }
    }

    public async Task DeleteBacktestsByRequestIdAsync(string requestId)
    {
        var entities = await _context.Backtests
            .AsTracking()
            .Where(b => b.RequestId == requestId)
            .ToListAsync()
            .ConfigureAwait(false);

        if (entities.Any())
        {
            _context.Backtests.RemoveRange(entities);
            await _context.SaveChangesAsync().ConfigureAwait(false);
        }
    }

    public (IEnumerable<LightBacktest> Backtests, int TotalCount) GetBacktestsByUserPaginated(User user, int page,
        int pageSize, string sortBy = "score", string sortOrder = "desc")
    {
        var stopwatch = Stopwatch.StartNew();
        
        var baseQuery = _context.Backtests
            .AsNoTracking()
            .Where(b => b.UserId == user.Id);

        var afterQueryMs = stopwatch.ElapsedMilliseconds;
        var totalCount = baseQuery.Count();
        var afterCountMs = stopwatch.ElapsedMilliseconds;

        // Apply sorting
        IQueryable<BacktestEntity> sortedQuery = sortBy.ToLower() switch
        {
            "score" => sortOrder == "desc"
                ? baseQuery.OrderByDescending(b => b.Score)
                : baseQuery.OrderBy(b => b.Score),
            "finalpnl" => sortOrder == "desc"
                ? baseQuery.OrderByDescending(b => b.FinalPnl)
                : baseQuery.OrderBy(b => b.FinalPnl),
            "winrate" => sortOrder == "desc"
                ? baseQuery.OrderByDescending(b => b.WinRate)
                : baseQuery.OrderBy(b => b.WinRate),
            "growthpercentage" => sortOrder == "desc"
                ? baseQuery.OrderByDescending(b => b.GrowthPercentage)
                : baseQuery.OrderBy(b => b.GrowthPercentage),
            "hodlpercentage" => sortOrder == "desc"
                ? baseQuery.OrderByDescending(b => b.HodlPercentage)
                : baseQuery.OrderBy(b => b.HodlPercentage),
            _ => sortOrder == "desc"
                ? baseQuery.OrderByDescending(b => b.Score)
                : baseQuery.OrderBy(b => b.Score)
        };

        var afterSortMs = stopwatch.ElapsedMilliseconds;
        var entities = sortedQuery
            .Skip((page - 1) * pageSize)
            .Take(pageSize)
            .ToList();
        var afterToListMs = stopwatch.ElapsedMilliseconds;

        Console.WriteLine(
            $"[PostgreSqlBacktestRepo] User Query: {afterQueryMs}ms, Count: {afterCountMs - afterQueryMs}ms, Sort: {afterSortMs - afterCountMs}ms, ToList: {afterToListMs - afterSortMs}ms, Total: {afterToListMs}ms");

        var mappedBacktests = entities.Select(entity => new LightBacktest
        {
            Id = entity.Identifier,
            Config = JsonConvert.DeserializeObject<TradingBotConfig>(entity.ConfigJson),
            FinalPnl = entity.FinalPnl,
            WinRate = entity.WinRate,
            GrowthPercentage = entity.GrowthPercentage,
            HodlPercentage = entity.HodlPercentage,
            StartDate = entity.StartDate,
            EndDate = entity.EndDate,
            MaxDrawdown = !string.IsNullOrEmpty(entity.StatisticsJson)
                ? JsonConvert.DeserializeObject<PerformanceMetrics>(entity.StatisticsJson)?.MaxDrawdown
                : null,
            Fees = entity.Fees,
            SharpeRatio = !string.IsNullOrEmpty(entity.StatisticsJson)
                ? JsonConvert.DeserializeObject<PerformanceMetrics>(entity.StatisticsJson)?.SharpeRatio != null
                    ? (double?)JsonConvert.DeserializeObject<PerformanceMetrics>(entity.StatisticsJson).SharpeRatio
                    : null
                : null,
            Score = entity.Score,
            ScoreMessage = entity.ScoreMessage ?? string.Empty
        });

        return (mappedBacktests, totalCount);
    }

    public async Task<(IEnumerable<LightBacktest> Backtests, int TotalCount)> GetBacktestsByUserPaginatedAsync(
        User user, int page, int pageSize, string sortBy = "score", string sortOrder = "desc")
    {
        var stopwatch = Stopwatch.StartNew();
        
        var baseQuery = _context.Backtests
            .AsNoTracking()
            .Where(b => b.UserId == user.Id);

        var afterQueryMs = stopwatch.ElapsedMilliseconds;
        var totalCount = await baseQuery.CountAsync().ConfigureAwait(false);
        var afterCountMs = stopwatch.ElapsedMilliseconds;

        // Apply sorting
        IQueryable<BacktestEntity> sortedQuery = sortBy.ToLower() switch
        {
            "score" => sortOrder == "desc"
                ? baseQuery.OrderByDescending(b => b.Score)
                : baseQuery.OrderBy(b => b.Score),
            "finalpnl" => sortOrder == "desc"
                ? baseQuery.OrderByDescending(b => b.FinalPnl)
                : baseQuery.OrderBy(b => b.FinalPnl),
            "winrate" => sortOrder == "desc"
                ? baseQuery.OrderByDescending(b => b.WinRate)
                : baseQuery.OrderBy(b => b.WinRate),
            "growthpercentage" => sortOrder == "desc"
                ? baseQuery.OrderByDescending(b => b.GrowthPercentage)
                : baseQuery.OrderBy(b => b.GrowthPercentage),
            "hodlpercentage" => sortOrder == "desc"
                ? baseQuery.OrderByDescending(b => b.HodlPercentage)
                : baseQuery.OrderBy(b => b.HodlPercentage),
            _ => sortOrder == "desc"
                ? baseQuery.OrderByDescending(b => b.Score)
                : baseQuery.OrderBy(b => b.Score)
        };

        var afterSortMs = stopwatch.ElapsedMilliseconds;
        var entities = await sortedQuery
            .Skip((page - 1) * pageSize)
            .Take(pageSize)
            .ToListAsync()
            .ConfigureAwait(false);
        var afterToListMs = stopwatch.ElapsedMilliseconds;

        Console.WriteLine(
            $"[PostgreSqlBacktestRepo] User Query: {afterQueryMs}ms, Count: {afterCountMs - afterQueryMs}ms, Sort: {afterSortMs - afterCountMs}ms, ToList: {afterToListMs - afterSortMs}ms, Total: {afterToListMs}ms");

        var mappedBacktests = entities.Select(entity => new LightBacktest
        {
            Id = entity.Identifier,
            Config = JsonConvert.DeserializeObject<TradingBotConfig>(entity.ConfigJson),
            FinalPnl = entity.FinalPnl,
            WinRate = entity.WinRate,
            GrowthPercentage = entity.GrowthPercentage,
            HodlPercentage = entity.HodlPercentage,
            StartDate = entity.StartDate,
            EndDate = entity.EndDate,
            MaxDrawdown = !string.IsNullOrEmpty(entity.StatisticsJson)
                ? JsonConvert.DeserializeObject<PerformanceMetrics>(entity.StatisticsJson)?.MaxDrawdown
                : null,
            Fees = entity.Fees,
            SharpeRatio = !string.IsNullOrEmpty(entity.StatisticsJson)
                ? JsonConvert.DeserializeObject<PerformanceMetrics>(entity.StatisticsJson)?.SharpeRatio != null
                    ? (double?)JsonConvert.DeserializeObject<PerformanceMetrics>(entity.StatisticsJson).SharpeRatio
                    : null
                : null,
            Score = entity.Score,
            ScoreMessage = entity.ScoreMessage ?? string.Empty
        });

        return (mappedBacktests, totalCount);
    }

    // Bundle backtest methods
    public void InsertBundleBacktestRequestForUser(User user, BundleBacktestRequest bundleRequest)
    {
        bundleRequest.User = user;
        var entity = PostgreSqlMappers.Map(bundleRequest);
        
        // Set the UserId by finding the user entity
        var userEntity = _context.Users.FirstOrDefault(u => u.Name == user.Name);
        if (userEntity != null)
        {
            entity.UserId = userEntity.Id;
        }
        
        _context.BundleBacktestRequests.Add(entity);
        _context.SaveChanges();
    }

    public async Task InsertBundleBacktestRequestForUserAsync(User user, BundleBacktestRequest bundleRequest)
    {
        bundleRequest.User = user;
        var entity = PostgreSqlMappers.Map(bundleRequest);
        
        // Set the UserId by finding the user entity
        var userEntity = await _context.Users.FirstOrDefaultAsync(u => u.Name == user.Name);
        if (userEntity != null)
        {
            entity.UserId = userEntity.Id;
        }
        
        await _context.BundleBacktestRequests.AddAsync(entity);
        await _context.SaveChangesAsync();
    }

    public IEnumerable<BundleBacktestRequest> GetBundleBacktestRequestsByUser(User user)
    {
        var entities = _context.BundleBacktestRequests
            .AsNoTracking()
            .Include(b => b.User)
            .Where(b => b.UserId == user.Id)
            .OrderByDescending(b => b.CreatedAt)
            .ToList();

        return entities.Select(PostgreSqlMappers.Map);
    }

    public async Task<IEnumerable<BundleBacktestRequest>> GetBundleBacktestRequestsByUserAsync(User user)
    {
        var entities = await _context.BundleBacktestRequests
            .AsNoTracking()
            .Include(b => b.User)
            .Where(b => b.UserId == user.Id)
            .OrderByDescending(b => b.CreatedAt)
            .ToListAsync()
            .ConfigureAwait(false);

        return entities.Select(PostgreSqlMappers.Map);
    }

    public BundleBacktestRequest? GetBundleBacktestRequestByIdForUser(User user, string id)
    {
        var entity = _context.BundleBacktestRequests
            .AsNoTracking()
            .Include(b => b.User)
            .FirstOrDefault(b => b.RequestId == id && b.UserId == user.Id);

        return entity != null ? PostgreSqlMappers.Map(entity) : null;
    }

    public async Task<BundleBacktestRequest?> GetBundleBacktestRequestByIdForUserAsync(User user, string id)
    {
        var entity = await _context.BundleBacktestRequests
            .AsNoTracking()
            .Include(b => b.User)
            .FirstOrDefaultAsync(b => b.RequestId == id && b.UserId == user.Id)
            .ConfigureAwait(false);

        return entity != null ? PostgreSqlMappers.Map(entity) : null;
    }

    public void UpdateBundleBacktestRequest(BundleBacktestRequest bundleRequest)
    {
        var entity = _context.BundleBacktestRequests
            .AsTracking()
            .FirstOrDefault(b => b.RequestId == bundleRequest.RequestId);
        
        if (entity != null)
        {
            // Update the entity properties
            entity.Status = bundleRequest.Status;
            entity.CompletedAt = bundleRequest.CompletedAt;
            entity.CompletedBacktests = bundleRequest.CompletedBacktests;
            entity.FailedBacktests = bundleRequest.FailedBacktests;
            entity.ErrorMessage = bundleRequest.ErrorMessage;
            entity.ProgressInfo = bundleRequest.ProgressInfo;
            entity.CurrentBacktest = bundleRequest.CurrentBacktest;
            entity.EstimatedTimeRemainingSeconds = bundleRequest.EstimatedTimeRemainingSeconds;
            entity.UpdatedAt = DateTime.UtcNow;
            
            // Serialize Results to JSON
            if (bundleRequest.Results != null && bundleRequest.Results.Any())
            {
                try
                {
                    entity.ResultsJson = JsonConvert.SerializeObject(bundleRequest.Results);
                }
                catch
                {
                    entity.ResultsJson = "[]";
                }
            }
            else
            {
                entity.ResultsJson = "[]";
            }

            _context.SaveChanges();
        }
    }

    public async Task UpdateBundleBacktestRequestAsync(BundleBacktestRequest bundleRequest)
    {
        var entity = await _context.BundleBacktestRequests
            .AsTracking()
            .FirstOrDefaultAsync(b => b.RequestId == bundleRequest.RequestId)
            .ConfigureAwait(false);
        
        if (entity != null)
        {
            // Update the entity properties
            entity.Status = bundleRequest.Status;
            entity.CompletedAt = bundleRequest.CompletedAt;
            entity.CompletedBacktests = bundleRequest.CompletedBacktests;
            entity.FailedBacktests = bundleRequest.FailedBacktests;
            entity.ErrorMessage = bundleRequest.ErrorMessage;
            entity.ProgressInfo = bundleRequest.ProgressInfo;
            entity.CurrentBacktest = bundleRequest.CurrentBacktest;
            entity.EstimatedTimeRemainingSeconds = bundleRequest.EstimatedTimeRemainingSeconds;
            entity.UpdatedAt = DateTime.UtcNow;
            
            // Serialize Results to JSON
            if (bundleRequest.Results != null && bundleRequest.Results.Any())
            {
                try
                {
                    entity.ResultsJson = JsonConvert.SerializeObject(bundleRequest.Results);
                }
                catch
                {
                    entity.ResultsJson = "[]";
                }
            }
            else
            {
                entity.ResultsJson = "[]";
            }

            await _context.SaveChangesAsync().ConfigureAwait(false);
        }
    }

    public void DeleteBundleBacktestRequestByIdForUser(User user, string id)
    {
        var entity = _context.BundleBacktestRequests
            .AsTracking()
            .FirstOrDefault(b => b.RequestId == id && b.UserId == user.Id);

        if (entity != null)
        {
            _context.BundleBacktestRequests.Remove(entity);
            _context.SaveChanges();
        }
    }

    public async Task DeleteBundleBacktestRequestByIdForUserAsync(User user, string id)
    {
        var entity = await _context.BundleBacktestRequests
            .AsTracking()
            .FirstOrDefaultAsync(b => b.RequestId == id && b.UserId == user.Id)
            .ConfigureAwait(false);

        if (entity != null)
        {
            _context.BundleBacktestRequests.Remove(entity);
            await _context.SaveChangesAsync().ConfigureAwait(false);
        }
    }

    public IEnumerable<BundleBacktestRequest> GetBundleBacktestRequestsByStatus(BundleBacktestRequestStatus status)
    {
        var entities = _context.BundleBacktestRequests
            .AsNoTracking()
            .Include(b => b.User)
            .Where(b => b.Status == status)
            .ToList();

        return entities.Select(PostgreSqlMappers.Map);
    }

    public async Task<IEnumerable<BundleBacktestRequest>> GetBundleBacktestRequestsByStatusAsync(BundleBacktestRequestStatus status)
    {
        var entities = await _context.BundleBacktestRequests
            .AsNoTracking()
            .Include(b => b.User)
            .Where(b => b.Status == status)
            .ToListAsync()
            .ConfigureAwait(false);

        return entities.Select(PostgreSqlMappers.Map);
    }
} 