using Microsoft.EntityFrameworkCore;
using MktXService.Domain.AggregatesModel.TemplateAggregate;
using MktXService.Domain.SeedWork;

namespace MktXService.Infrastructure.Repositories;

/// <summary>
/// EN: Repository implementation for Template aggregate.
/// VI: Triển khai repository cho Template aggregate.
/// </summary>
public class TemplateRepository : ITemplateRepository
{
    private readonly MktXServiceContext _context;

    public IUnitOfWork UnitOfWork => _context;

    public TemplateRepository(MktXServiceContext context)
    {
        _context = context ?? throw new ArgumentNullException(nameof(context));
    }

    public Template Add(Template template)
    {
        return _context.Templates.Add(template).Entity;
    }

    public void Update(Template template)
    {
        _context.Entry(template).State = EntityState.Modified;
    }

    public void Delete(Template template)
    {
        _context.Templates.Remove(template);
    }

    public async Task<Template?> GetByIdAsync(Guid id)
    {
        return await _context.Templates.FirstOrDefaultAsync(t => t.Id == id);
    }

    public async Task<IEnumerable<Template>> GetByMerchantIdAsync(Guid merchantId)
    {
        return await _context.Templates
            .Where(t => EF.Property<Guid>(t, "_merchantId") == merchantId)
            .OrderByDescending(t => EF.Property<DateTime>(t, "_createdAt"))
            .ToListAsync();
    }

    public async Task<IEnumerable<Template>> GetByTypeAsync(Guid merchantId, string type)
    {
        return await _context.Templates
            .Where(t => EF.Property<Guid>(t, "_merchantId") == merchantId && 
                        EF.Property<string>(t, "_type") == type)
            .OrderByDescending(t => EF.Property<DateTime>(t, "_createdAt"))
            .ToListAsync();
    }

    public async Task<IEnumerable<Template>> SearchByNameAsync(Guid merchantId, string searchTerm)
    {
        var term = searchTerm.ToLowerInvariant();
        return await _context.Templates
            .Where(t => EF.Property<Guid>(t, "_merchantId") == merchantId &&
                        EF.Property<string>(t, "_name").ToLower().Contains(term))
            .OrderByDescending(t => EF.Property<DateTime>(t, "_createdAt"))
            .ToListAsync();
    }
}
