namespace DocuMed.Repository.Repositories.Entities;

public class MedicalHistoryRepository(ApplicationContext dbContext, ICurrentUserService currentUserService)
    : BaseRepository<MedicalHistory>(dbContext, currentUserService), IMedicalHistoryRepository
{
    public async Task<List<MedicalHistorySDto>> GetMedicalHistoriesAsync(int page = 0, CancellationToken cancellationToken = default)
    {
        if (!Guid.TryParse(CurrentUserService.UserId, out Guid userId))
            throw new AppException("توکن غیرمجاز", ApiResultStatusCode.UnAuthorized);
        var list = await TableNoTracking
            .Where(t => t.ApplicationUserId == userId)
            .OrderByDescending(t => t.CreatedAt)
            .Skip(page * 15)
            .Take(15)
            .Select(MedicalHistoryMapper.ProjectToSDto)
            .ToListAsync(cancellationToken);
        return list;
    }

    public async Task<List<MedicalHistorySDto>> GetMedicalHistoriesByFilterAsync(DayQueryFilter dayQuery, int page = 0, CancellationToken cancellationToken = default)
    {
        if (!Guid.TryParse(CurrentUserService.UserId, out Guid userId))
            throw new AppException("توکن غیرمجاز", ApiResultStatusCode.UnAuthorized);
        var list = new List<MedicalHistorySDto>();
        switch (dayQuery)
        {
            case DayQueryFilter.Today:
                list = await TableNoTracking
                    .Where(t => t.ApplicationUserId == userId && t.CreatedAt.Date == DateTime.Today)
                    .OrderByDescending(t => t.CreatedAt)
                    .Skip(page * 15)
                    .Take(15)
                    .Select(MedicalHistoryMapper.ProjectToSDto)
                    .ToListAsync(cancellationToken);
                break;
            case DayQueryFilter.Yesterday:
                list = await TableNoTracking
                    .Where(t => t.ApplicationUserId == userId && t.CreatedAt.Date == DateTime.Today.AddDays(-1))
                    .OrderByDescending(t => t.CreatedAt)
                    .Skip(page * 15)
                    .Take(15)
                    .Select(MedicalHistoryMapper.ProjectToSDto)
                    .ToListAsync(cancellationToken);
                break;
            case DayQueryFilter.Week:
                list = await TableNoTracking
                    .Where(t => t.ApplicationUserId == userId && t.CreatedAt.Date >= DateTime.Today.AddDays(-7) )
                    .OrderByDescending(t => t.CreatedAt)
                    .Skip(page * 15)
                    .Take(15)
                    .Select(MedicalHistoryMapper.ProjectToSDto)
                    .ToListAsync(cancellationToken);
                break;
            default:
                throw new ArgumentOutOfRangeException(nameof(dayQuery), dayQuery, null);
        }
        return list;
    }

    public async Task<MedicalHistoryLDto> GetMedicalHistoryAsync(Guid id, CancellationToken cancellationToken = default)
    {
        var dto = await TableNoTracking.Where(t => t.Id == id)
            .Select(MedicalHistoryMapper.ProjectToLDto)
            .FirstOrDefaultAsync(cancellationToken);
        if (dto == null)
            throw new AppException("شرح حال پیدا نشد", ApiResultStatusCode.NotFound);
        return dto;
    }
}