using e_suite.API.Common.repository;
using e_suite.Database.Audit;
using e_suite.Database.Core;
using e_suite.Database.Core.Extensions;
using e_suite.Database.Core.Tables.Activity;
using eSuite.Core.Miscellaneous;
using Microsoft.EntityFrameworkCore;

namespace e_suite.Modules.RunningActivityManager.repository;

public class ActivityRepository : RepositoryBase, IActivityRepository
{
    public ActivityRepository(IEsuiteDatabaseDbContext databaseDbContext) : base(databaseDbContext)
    {
    }

    public async Task CreateActivityInstanceAsync(
        AuditUserDetails auditUserDetails,
        Activity activity,
        CancellationToken cancellationToken
    )
    {
        DatabaseDbContext.Activities.Add(activity);
        await DatabaseDbContext.SaveChangesAsync(auditUserDetails, cancellationToken);
    }

    public async Task<Activity?> GetActivityInstanceAsync(GeneralIdRef activityId, CancellationToken cancellationToken)
    {
        return await DatabaseDbContext.Activities
            .Include( x=> x.WorkflowVersion)
            .Include( x => x.Tasks)
            .FindByGeneralIdRefAsync(activityId, cancellationToken);
    }

    public async Task UpdateActivityInstanceAsync(AuditUserDetails auditUserDetails, Activity activityInstance, CancellationToken cancellationToken)
    {
        await DatabaseDbContext.SaveChangesAsync(auditUserDetails, cancellationToken);
    }

    public async Task AddActivityTasksAsync(
        AuditUserDetails auditUserDetails,
        IEnumerable<ActivityTask> activityTasks,
        CancellationToken cancellationToken
    )
    {
        var enumerable = activityTasks as ActivityTask[] ?? activityTasks.ToArray();
        DatabaseDbContext.ActivityTasks.AddRange(enumerable);
        DatabaseDbContext.ActivityAssignments.AddRange(enumerable.SelectMany( x => x.Assignments));
        await DatabaseDbContext.SaveChangesAsync(auditUserDetails, cancellationToken);
    }

    public async Task UpdateActivityTasksAsync(
        AuditUserDetails auditUserDetails,
        ICollection<ActivityTask> tasks,
        CancellationToken cancellationToken
    )
    {
        await DatabaseDbContext.SaveChangesAsync(auditUserDetails, cancellationToken);
    }

    public IQueryable<ActivityAssignment> GetAssignments()
    {
        return DatabaseDbContext.ActivityAssignments
            .Include(x => x.User)
            .Include(x => x.Role)
                .ThenInclude(x => x.UserRoles.Where(ur => !ur.Deleted))
                .ThenInclude(x => x.User)
            .Include(x => x.Task)
            .ThenInclude( x => x.Activity);
    }
    
}