using Database.Models;
using Microsoft.EntityFrameworkCore;

namespace Database.Services
{
    public interface IProjectRepository
    {
        Task<Project?> GetByIdAsync(int id);
        Task<Project?> GetByCCNetNameAsync(string ccNetProjectName);
        Task<List<Project>> GetAllAsync();
        Task<List<Project>> GetActiveProjectsAsync();
        Task<Project> CreateAsync(Project project);
        Task<Project> UpdateAsync(Project project);
        Task DeleteAsync(int id, string deletedBy);
        Task<bool> ExistsAsync(int id);
        Task<bool> CCNetNameExistsAsync(string ccNetProjectName);
    }
    
    public class ProjectRepository : IProjectRepository
    {
        private readonly DatabaseContext _context;
        
        public ProjectRepository(DatabaseContext context)
        {
            _context = context;
        }
        
        public async Task<Project?> GetByIdAsync(int id)
        {
            return await _context.Projects
                .Include(p => p.Builds)
                .Include(p => p.Packages)
                .FirstOrDefaultAsync(p => p.Id == id);
        }
        
        public async Task<Project?> GetByCCNetNameAsync(string ccNetProjectName)
        {
            return await _context.Projects
                .Include(p => p.Builds)
                .Include(p => p.Packages)
                .FirstOrDefaultAsync(p => p.CCNetProjectName == ccNetProjectName);
        }
        
        public async Task<List<Project>> GetAllAsync()
        {
            return await _context.Projects
                .Include(p => p.Builds.Take(5))
                .Include(p => p.Packages.Take(5))
                .OrderBy(p => p.Name)
                .ToListAsync();
        }
        
        public async Task<List<Project>> GetActiveProjectsAsync()
        {
            return await _context.Projects
                .Where(p => p.Status == "Active")
                .OrderBy(p => p.Name)
                .ToListAsync();
        }
        
        public async Task<Project> CreateAsync(Project project)
        {
            _context.Projects.Add(project);
            await _context.SaveChangesAsync();
            return project;
        }
        
        public async Task<Project> UpdateAsync(Project project)
        {
            project.UpdateTimestamp(project.UpdatedBy ?? "System");
            _context.Projects.Update(project);
            await _context.SaveChangesAsync();
            return project;
        }
        
        public async Task DeleteAsync(int id, string deletedBy)
        {
            var project = await GetByIdAsync(id);
            if (project != null)
            {
                project.MarkAsDeleted(deletedBy);
                await _context.SaveChangesAsync();
            }
        }
        
        public async Task<bool> ExistsAsync(int id)
        {
            return await _context.Projects.AnyAsync(p => p.Id == id);
        }
        
        public async Task<bool> CCNetNameExistsAsync(string ccNetProjectName)
        {
            return await _context.Projects.AnyAsync(p => p.CCNetProjectName == ccNetProjectName);
        }
    }
}