using Database.Models;
using Microsoft.EntityFrameworkCore;

namespace Database.Services
{
    public interface IFogBugzRepository
    {
        Task<FogBugzCase?> GetCaseByIdAsync(int caseId);
        Task<FogBugzCase?> GetCaseByDbIdAsync(int id);
        Task<List<FogBugzCase>> GetCasesByStatusAsync(string status);
        Task<List<FogBugzCase>> GetRecentCasesAsync(int count = 50);
        Task<FogBugzCase> CreateOrUpdateCaseAsync(FogBugzCase fogBugzCase);
        Task DeleteCaseAsync(int id, string deletedBy);
        Task<bool> CaseExistsAsync(int caseId);
        
        Task<List<FogBugzEvent>> GetEventsByCaseIdAsync(int caseId);
        Task<FogBugzEvent> CreateEventAsync(FogBugzEvent fogBugzEvent);
        Task<List<FogBugzEvent>> CreateEventsAsync(List<FogBugzEvent> events);
        Task<List<FogBugzEvent>> GetReleaseNoteEventsAsync(int caseId);
        Task<List<FogBugzEvent>> GetZendeskEventsAsync(int caseId);
    }
    
    public class FogBugzRepository : IFogBugzRepository
    {
        private readonly DatabaseContext _context;
        
        public FogBugzRepository(DatabaseContext context)
        {
            _context = context;
        }
        
        public async Task<FogBugzCase?> GetCaseByIdAsync(int caseId)
        {
            return await _context.FogBugzCases
                .Include(c => c.Events.OrderByDescending(e => e.EventDate))
                .FirstOrDefaultAsync(c => c.CaseId == caseId);
        }
        
        public async Task<FogBugzCase?> GetCaseByDbIdAsync(int id)
        {
            return await _context.FogBugzCases
                .Include(c => c.Events.OrderByDescending(e => e.EventDate))
                .FirstOrDefaultAsync(c => c.Id == id);
        }
        
        public async Task<List<FogBugzCase>> GetCasesByStatusAsync(string status)
        {
            return await _context.FogBugzCases
                .Where(c => c.Status == status)
                .OrderByDescending(c => c.LastUpdated)
                .ToListAsync();
        }
        
        public async Task<List<FogBugzCase>> GetRecentCasesAsync(int count = 50)
        {
            return await _context.FogBugzCases
                .OrderByDescending(c => c.LastUpdated)
                .Take(count)
                .ToListAsync();
        }
        
        public async Task<FogBugzCase> CreateOrUpdateCaseAsync(FogBugzCase fogBugzCase)
        {
            var existing = await GetCaseByIdAsync(fogBugzCase.CaseId);
            
            if (existing != null)
            {
                existing.Title = fogBugzCase.Title;
                existing.Project = fogBugzCase.Project;
                existing.Area = fogBugzCase.Area;
                existing.Status = fogBugzCase.Status;
                existing.LastUpdated = fogBugzCase.LastUpdated;
                existing.IsOpen = fogBugzCase.IsOpen;
                existing.UpdateTimestamp(fogBugzCase.UpdatedBy ?? "System");
                
                _context.FogBugzCases.Update(existing);
                await _context.SaveChangesAsync();
                return existing;
            }
            else
            {
                _context.FogBugzCases.Add(fogBugzCase);
                await _context.SaveChangesAsync();
                return fogBugzCase;
            }
        }
        
        public async Task DeleteCaseAsync(int id, string deletedBy)
        {
            var fogBugzCase = await GetCaseByDbIdAsync(id);
            if (fogBugzCase != null)
            {
                fogBugzCase.MarkAsDeleted(deletedBy);
                await _context.SaveChangesAsync();
            }
        }
        
        public async Task<bool> CaseExistsAsync(int caseId)
        {
            return await _context.FogBugzCases.AnyAsync(c => c.CaseId == caseId);
        }
        
        public async Task<List<FogBugzEvent>> GetEventsByCaseIdAsync(int caseId)
        {
            var fogBugzCase = await GetCaseByIdAsync(caseId);
            if (fogBugzCase == null)
                return new List<FogBugzEvent>();
                
            return await _context.FogBugzEvents
                .Where(e => e.CaseId == fogBugzCase.Id)
                .OrderByDescending(e => e.EventDate)
                .ToListAsync();
        }
        
        public async Task<FogBugzEvent> CreateEventAsync(FogBugzEvent fogBugzEvent)
        {
            _context.FogBugzEvents.Add(fogBugzEvent);
            await _context.SaveChangesAsync();
            return fogBugzEvent;
        }
        
        public async Task<List<FogBugzEvent>> CreateEventsAsync(List<FogBugzEvent> events)
        {
            _context.FogBugzEvents.AddRange(events);
            await _context.SaveChangesAsync();
            return events;
        }
        
        public async Task<List<FogBugzEvent>> GetReleaseNoteEventsAsync(int caseId)
        {
            var fogBugzCase = await GetCaseByIdAsync(caseId);
            if (fogBugzCase == null)
                return new List<FogBugzEvent>();
                
            return await _context.FogBugzEvents
                .Where(e => e.CaseId == fogBugzCase.Id && 
                           e.EventType == "ReleaseNoted" && 
                           !string.IsNullOrEmpty(e.ReleaseNote))
                .OrderByDescending(e => e.EventDate)
                .ToListAsync();
        }
        
        public async Task<List<FogBugzEvent>> GetZendeskEventsAsync(int caseId)
        {
            var fogBugzCase = await GetCaseByIdAsync(caseId);
            if (fogBugzCase == null)
                return new List<FogBugzEvent>();
                
            return await _context.FogBugzEvents
                .Where(e => e.CaseId == fogBugzCase.Id && 
                           e.EventType == "sZendesk" && 
                           e.ZendeskNumber.HasValue && 
                           e.ZendeskNumber > 0)
                .OrderByDescending(e => e.EventDate)
                .ToListAsync();
        }
    }
}