using Microsoft.EntityFrameworkCore;
using ColaFlow.Modules.IssueManagement.Domain.Entities;
using ColaFlow.Modules.IssueManagement.Domain.Enums;
using ColaFlow.Modules.IssueManagement.Domain.Repositories;
using ColaFlow.Modules.IssueManagement.Infrastructure.Services;

namespace ColaFlow.Modules.IssueManagement.Infrastructure.Persistence.Repositories;

/// <summary>
/// Repository implementation for Issue aggregate with multi-tenant isolation
/// </summary>
public sealed class IssueRepository : IIssueRepository
{
    private readonly IssueManagementDbContext _context;
    private readonly ITenantContext _tenantContext;

    public IssueRepository(IssueManagementDbContext context, ITenantContext tenantContext)
    {
        _context = context;
        _tenantContext = tenantContext;
    }

    private Guid CurrentTenantId => _tenantContext.GetCurrentTenantId();

    public async Task<Issue?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default)
    {
        return await _context.Issues
            .AsNoTracking()
            .FirstOrDefaultAsync(i => i.Id == id && i.TenantId == CurrentTenantId, cancellationToken);
    }

    public async Task<List<Issue>> GetByProjectIdAsync(Guid projectId, CancellationToken cancellationToken = default)
    {
        return await _context.Issues
            .AsNoTracking()
            .Where(i => i.ProjectId == projectId && i.TenantId == CurrentTenantId)
            .OrderBy(i => i.CreatedAt)
            .ToListAsync(cancellationToken);
    }

    public async Task<List<Issue>> GetByProjectIdAndStatusAsync(
        Guid projectId,
        IssueStatus status,
        CancellationToken cancellationToken = default)
    {
        return await _context.Issues
            .AsNoTracking()
            .Where(i => i.ProjectId == projectId && i.Status == status && i.TenantId == CurrentTenantId)
            .OrderBy(i => i.CreatedAt)
            .ToListAsync(cancellationToken);
    }

    public async Task<List<Issue>> GetByAssigneeIdAsync(Guid assigneeId, CancellationToken cancellationToken = default)
    {
        return await _context.Issues
            .AsNoTracking()
            .Where(i => i.AssigneeId == assigneeId && i.TenantId == CurrentTenantId)
            .OrderBy(i => i.CreatedAt)
            .ToListAsync(cancellationToken);
    }

    public async Task AddAsync(Issue issue, CancellationToken cancellationToken = default)
    {
        await _context.Issues.AddAsync(issue, cancellationToken);
    }

    public Task UpdateAsync(Issue issue, CancellationToken cancellationToken = default)
    {
        _context.Issues.Update(issue);
        return Task.CompletedTask;
    }

    public Task DeleteAsync(Issue issue, CancellationToken cancellationToken = default)
    {
        _context.Issues.Remove(issue);
        return Task.CompletedTask;
    }

    public async Task<bool> ExistsAsync(Guid id, CancellationToken cancellationToken = default)
    {
        return await _context.Issues.AnyAsync(i => i.Id == id && i.TenantId == CurrentTenantId, cancellationToken);
    }
}
