using Managing.Application.Abstractions.Repositories;
using Managing.Common;
using Managing.Domain.Workers;
using Managing.Infrastructure.Databases.PostgreSql.Entities;
using Microsoft.EntityFrameworkCore;

namespace Managing.Infrastructure.Databases.PostgreSql;

public class PostgreSqlWorkerRepository : IWorkerRepository
{
    private readonly ManagingDbContext _context;

    public PostgreSqlWorkerRepository(ManagingDbContext context)
    {
        _context = context;
    }

    public async Task DisableWorker(Enums.WorkerType workerType)
    {
        var entity = await GetWorkerEntity(workerType);
        if (entity == null) throw new InvalidOperationException($"Worker with type '{workerType}' not found");
        entity.IsActive = false;
        await _context.SaveChangesAsync().ConfigureAwait(false);
    }

    public async Task EnableWorker(Enums.WorkerType workerType)
    {
        var entity = await GetWorkerEntity(workerType);
        if (entity == null) throw new InvalidOperationException($"Worker with type '{workerType}' not found");
        entity.IsActive = true;
        await _context.SaveChangesAsync().ConfigureAwait(false);
    }

    public async Task<Worker> GetWorkerAsync(Enums.WorkerType workerType)
    {
        var entity = await GetWorkerEntity(workerType);
        return PostgreSqlMappers.Map(entity);
    }

    public async Task<IEnumerable<Worker>> GetWorkers()
    {
        var entities = await _context.Workers.AsNoTracking().ToListAsync().ConfigureAwait(false);
        return PostgreSqlMappers.Map(entities);
    }

    public async Task InsertWorker(Worker worker)
    {
        var entity = PostgreSqlMappers.Map(worker);
        await _context.Workers.AddAsync(entity).ConfigureAwait(false);
        await _context.SaveChangesAsync().ConfigureAwait(false);
    }

    public async Task UpdateWorker(Enums.WorkerType workerType, int executionCount)
    {
        var entity = await GetWorkerEntity(workerType);
        if (entity == null) throw new InvalidOperationException($"Worker with type '{workerType}' not found");
        entity.ExecutionCount = executionCount;
        entity.LastRunTime = DateTime.UtcNow;
        await _context.SaveChangesAsync().ConfigureAwait(false);
    }

    private async Task<WorkerEntity?> GetWorkerEntity(Enums.WorkerType workerType)
    {
        return await _context.Workers.FirstOrDefaultAsync(w => w.WorkerType == workerType).ConfigureAwait(false);
    }
} 