using Microsoft.EntityFrameworkCore;
using WhatsAppService.Domain.AggregatesModel.AutomationFlowAggregate;
using WhatsAppService.Domain.SeedWork;

namespace WhatsAppService.Infrastructure.Repositories;

/// <summary>
/// EN: Repository implementation for AutomationFlow aggregate.
/// VI: Triển khai repository cho AutomationFlow aggregate.
/// </summary>
public class AutomationFlowRepository : IAutomationFlowRepository
{
    private readonly WhatsAppServiceContext _context;

    public IUnitOfWork UnitOfWork => _context;

    public AutomationFlowRepository(WhatsAppServiceContext context)
    {
        _context = context ?? throw new ArgumentNullException(nameof(context));
    }

    public async Task<AutomationFlow> AddAsync(AutomationFlow flow, CancellationToken cancellationToken = default)
    {
        var entry = await _context.AutomationFlows.AddAsync(flow, cancellationToken);
        return entry.Entity;
    }

    public void Update(AutomationFlow flow)
    {
        _context.Entry(flow).State = EntityState.Modified;
    }

    public async Task<AutomationFlow?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default)
    {
        return await _context.AutomationFlows
            .Include(f => f.TriggerType)
            .Include(f => f.Steps.OrderBy(s => EF.Property<int>(s, "_order")))
            .FirstOrDefaultAsync(f => f.Id == id, cancellationToken);
    }

    public async Task<IReadOnlyList<AutomationFlow>> GetActiveByShopIdAsync(Guid shopId, CancellationToken cancellationToken = default)
    {
        return await _context.AutomationFlows
            .Include(f => f.TriggerType)
            .Include(f => f.Steps.OrderBy(s => EF.Property<int>(s, "_order")))
            .Where(f => 
                EF.Property<Guid>(f, "_shopId") == shopId &&
                EF.Property<bool>(f, "_isActive") == true)
            .OrderByDescending(f => EF.Property<int>(f, "_priority"))
            .ToListAsync(cancellationToken);
    }

    public async Task<IReadOnlyList<AutomationFlow>> GetByTriggerTypeAsync(Guid shopId, TriggerType triggerType, CancellationToken cancellationToken = default)
    {
        return await _context.AutomationFlows
            .Include(f => f.TriggerType)
            .Include(f => f.Steps.OrderBy(s => EF.Property<int>(s, "_order")))
            .Where(f => 
                EF.Property<Guid>(f, "_shopId") == shopId &&
                f.TriggerTypeId == triggerType.Id &&
                EF.Property<bool>(f, "_isActive") == true)
            .OrderByDescending(f => EF.Property<int>(f, "_priority"))
            .ToListAsync(cancellationToken);
    }
}
