using DbContextLib;
using DTO;
using Entities;
using Microsoft.EntityFrameworkCore;
using StubbedContextLib;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DTOToEntity
{
    public class UserService : IUserService
    {
        private UnitOfWork _context = new UnitOfWork();

        public UserService() { }
        public UserService(StubbedContext context)
        {
            _context = new UnitOfWork(context);
        }
        public async Task<UserDTO> Add(UserDTO user)
        {
            UserEntity userEntity = user.ToEntity();
            if(userEntity == null)
            {
                throw new Exception("User Entity is null");
            }
            _context.UserRepository.Insert(userEntity);
            await _context.SaveChangesAsync();
            return user;
        }

        public async Task<UserDTO> Delete(object id)
        {
            UserEntity? user = _context.UserRepository.GetById((long)id);
            if(user == null)
            {
                throw new Exception("User not found");
            }
            _context.UserRepository.Delete((long)id);
            await _context.SaveChangesAsync();
            return user.ToDTO();
        }

        public async Task<PageResponse<UserDTO>> GetByGroup(int index, int count, long group)
        {
            var users = _context.UserRepository.GetItems(index,count).Where(u => u.GroupId == group);
            return new PageResponse<UserDTO>(users.Select(u => u.ToDTO()), _context.UserRepository.GetItems(0,1000000000).Count());
        }

        public async Task<UserDTO> GetById(object id)
        {
            var user = _context.UserRepository.GetById((long)id);
            if(user == null)
            {
                throw new Exception("User not found");
            }
            return user.ToDTO();
        }

        public async Task<PageResponse<UserDTO>> GetByRole(int index, int count, string role)
        {

            var users = _context.UserRepository.GetItems(filter: u => u.Role != null && u.Role.Name == role,
                                             index: index,
                                             count: count);
            return new PageResponse<UserDTO>(users.Select(u => u.ToDTO()), _context.UserRepository.GetItems(0, 1000000000).Count());
        }

        public async Task<PageResponse<UserDTO>> Gets(int index, int count)
        {
            IEnumerable<UserEntity> users = _context.UserRepository.GetItems(index, count) ;
            return new PageResponse<UserDTO>( users.Select(u => u.ToDTO()),_context.UserRepository.GetItems(0, 1000000000).Count());
        }

        public async Task<UserDTO> Update(UserDTO user)
        {
            if(user == null)
            {
                throw new Exception("User is null");
            }
            var existingUser = _context.UserRepository.GetById(user.Id);
            if(existingUser == null)
            {
                throw new Exception("User not found");
            }
            existingUser.image = user.image;
            existingUser.Name = user.Name;
            existingUser.Password = user.Password;
            existingUser.NickName = user.NickName;
            existingUser.Email = user.Email;
            existingUser.RoleId = user.RoleId;
            existingUser.GroupId = user.GroupId;
            existingUser.UserName = user.UserName;
            existingUser.ExtraTime = user.ExtraTime;

            await _context.SaveChangesAsync();
            return existingUser.ToDTO();
        }
    }
}
