using IWS5.DatabaseAccess.Interfaces.IAdmin;
using IWS5.DatabaseAccess.IwsDataContext;
using IWS5.DatabaseAccess.IwsDataModels;
using Microsoft.EntityFrameworkCore;
using System.Globalization;
using System.Text.RegularExpressions;

namespace IWS5.DatabaseAccess.Repositories.IAdmin;

public class ScheduleRepository(GreenfieldPd2015Context context)
    : IWSRepository<AtscheduledItem>(context), IScheduleRepository
{
    public async Task<List<AtscheduledItem>> ListAsync()
    {
        return await context.AtscheduledItems
            .Include(s => s.Status)
            .Include(s => s.LastRunStatus)
            .Include(s => s.ScheduleType)
            .Include(s => s.Server)
            .OrderBy(s => s.Name)
            .ToListAsync();
    }

    public async Task<AtscheduledItem?> GetByIdAsync(int scheduleId)
    {
        return await context.AtscheduledItems
            .Include(s => s.Status)
            .Include(s => s.LastRunStatus)
            .Include(s => s.ScheduleType)
            .Include(s => s.Server)
            .Include(s => s.AtscheduledTasks)
                .ThenInclude(t => t.TaskType)
            .FirstOrDefaultAsync(s => s.ScheduleId == scheduleId);
    }

    public async Task AddAsync(AtscheduledItem entity)
    {
        context.AtscheduledItems.Add(entity);
        await context.SaveChangesAsync();
    }

    public async Task UpdateAsync(AtscheduledItem entity)
    {
        entity.UpdatedAt = DateTime.UtcNow;
        context.AtscheduledItems.Update(entity);
        await context.SaveChangesAsync();
    }

    public async Task DeleteAsync(AtscheduledItem entity)
    {
        context.AtscheduledItems.Remove(entity);
        await context.SaveChangesAsync();
    }

    public async Task<bool> UpdateStatusAsync(int scheduleId, bool enabled, int statusId)
    {
        var schedule = await context.AtscheduledItems.FindAsync(scheduleId);
        if (schedule == null) return false;

        schedule.Enabled = enabled;
        schedule.StatusId = statusId;
        schedule.UpdatedAt = DateTime.UtcNow;
        await context.SaveChangesAsync();

        return true;
    }

    public async Task<bool> RunScheduleAsync(int scheduleId)
    {
        var schedule = await context.AtscheduledItems
            .Include(s => s.AtscheduledTasks)
            .FirstOrDefaultAsync(s => s.ScheduleId == scheduleId);

        if (schedule == null) return false;

        schedule.StatusId = 2; // Running
        schedule.LastRun = DateTime.UtcNow;

        // TODO: Execute tasks sequentially

        schedule.StatusId = 3; // Completed
        schedule.UpdatedAt = DateTime.UtcNow;

        await context.SaveChangesAsync();
        return true;
    }

    public async Task<List<AtscheduleType>> ListScheduleTypesAsync()
        => await context.AtscheduleTypes.OrderBy(t => t.ScheduleTypeId).ToListAsync();

    public async Task<AtscheduleType?> GetScheduleTypeByIdAsync(int scheduleTypeId)
        => await context.AtscheduleTypes.FirstOrDefaultAsync(t => t.ScheduleTypeId == scheduleTypeId);

    public async Task<bool> ExistsByNameAsync(string name)
    {
        return await context.AtscheduledItems
            .AnyAsync(s => s.Name == name);
    }
}
