using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Serilog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using WorkFlowCheck.DL;

namespace WorkFlowCheck.BL.Services
{
    public class BaseService

    {
        public readonly AppDbContext _dbContext;
        public readonly IMapper _mapper;

        public BaseService(AppDbContext db_dbContext, IMapper mapper)
        {
            _dbContext = db_dbContext;
            _mapper = mapper;
        }

        public async Task<bool> DeleteEntityByIdAsync<T>(int id) where T : class
        {
            try
            {
                var entity = await _dbContext.Set<T>().FindAsync(id);

                if (entity == null)
                    return false;
                _dbContext.Set<T>().Remove(entity);
                await _dbContext.SaveChangesAsync();

                return true;
            }
            catch (Exception ex)
            {
                Log.Error($"Hiba történt a törlés során: {ex.Message}");
                return false;
            }
        }
        public async Task<T?> GetEntityByIdAsync<T>(int id) where T : class
        {
            try
            {
                var entity = await _dbContext.Set<T>().FindAsync(id);
                return entity;
            }
            catch (Exception ex)
            {
                Log.Error($"Hiba történt a lekérdezés során: {ex.Message}");
                return null;
            }
        }
        public async Task<List<TEntity>> GetEntityByFilterAsync<TEntity, TFilter>(TFilter filter) where TEntity : class where TFilter : class
        {
            try
            {
                IQueryable<TEntity> query = _dbContext.Set<TEntity>();


                foreach (var property in typeof(TFilter).GetProperties())
                {
                    var value = property.GetValue(filter);
                    if (value != null)
                    {
                        var parameter = Expression.Parameter(typeof(TEntity), "x");
                        var member = Expression.Property(parameter, property.Name);
                        var constant = Expression.Constant(value);
                        var equal = Expression.Equal(member, constant);
                        var lambda = Expression.Lambda<Func<TEntity, bool>>(equal, parameter);

                        query = query.Where(lambda);
                    }
                }

                // Adatok lekérdezése
                return await query.ToListAsync();
            }
            catch (Exception ex)
            {
                Log.Error($"Hiba történt a lekérdezés során: {ex.Message}");
                return new List<TEntity>();
            }
        }
        public async Task<PagedResult<TEntity>> GetPagedEntityByFilterAsync<TEntity, TFilter>(TFilter filter, int pageNumber, int pageSize) where TEntity : class where TFilter : class
        {
            try
            {
                

                // Az IQueryable típusú lista létrehozása
                IQueryable<TEntity> query = _dbContext.Set<TEntity>();

                // Dinamikus szűrés a filter tulajdonságai alapján
                foreach (var property in typeof(TFilter).GetProperties())
                {
                    var value = property.GetValue(filter);
                    if (value != null)
                    {
                        var parameter = Expression.Parameter(typeof(TEntity), "x");
                        var member = Expression.Property(parameter, property.Name);
                        var constant = Expression.Constant(value);
                        var equal = Expression.Equal(member, constant);
                        var lambda = Expression.Lambda<Func<TEntity, bool>>(equal, parameter);
                        query = query.Where(lambda);
                    }
                }

                // Teljes rekordok száma a szűrő után
                int totalCount = await query.CountAsync();

                // Lapozás alkalmazása
                var items = await query
                    .Skip((pageNumber - 1) * pageSize)
                    .Take(pageSize)
                    .ToListAsync();

                // Lapozási eredmény összerakása
                return new PagedResult<TEntity>
                {
                    Items = items,
                    TotalCount = totalCount,
                    PageNumber = pageNumber,
                    PageSize = pageSize
                };
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Hiba történt a lekérdezés során: {ex.Message}");
                return new PagedResult<TEntity>();
            }
        }

    }
    public class PagedResult<TEntity>
    {
        public List<TEntity> Items { get; set; } = new List<TEntity>();
        public int TotalCount { get; set; }
        public int PageNumber { get; set; }
        public int PageSize { get; set; }
    }

}
