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

namespace DTOToEntity
{
    public class GroupService : IGroupService
    {

        private readonly UnitOfWork context = new UnitOfWork();

        public GroupService()
        {

        }

        public GroupService(StubbedContext _context)
        {
            context = new UnitOfWork(_context);
        }
        public async Task<GroupDTO> Add(GroupDTO group)
        {
            if(group == null)
            {
                throw new ArgumentNullException();
            }
            GroupEntity groupEntity = group.ToEntity();
            context.GroupRepository.Insert(groupEntity);
             await context.SaveChangesAsync();

            return groupEntity.ToDTO(); ;
        }

        public async Task<UserDTO> AddUserToGroup(long idUser, long idGroup)
        {
            var group = context.GroupRepository.GetById(idGroup);
            if (group == null)
            {
                throw new Exception("Group not found");
            }
            var user = context.UserRepository.GetById(idUser);
            if (user == null)
            {
                throw new Exception("User not found");
            }
            group.Users.Add(user);
            await context.SaveChangesAsync();
            return user.ToDTO();

        }

        public async Task<VocabularyListDTO> AddVocabularyListToGroup(long vocabId, long groupId)
        {
            var group = context.GroupRepository.GetById(groupId);
            if (group == null)
            {
                throw new Exception("Group not found");
            }
            var vocab = context.VocabularyListRepository.GetById(vocabId);
            if (vocab == null)
            {
                throw new Exception("VocabularyList not found");
            }
            group.GroupVocabularyList.Add(vocab);

            await context.SaveChangesAsync();
            return vocab.ToDTO();

        }

        public async Task<GroupDTO> Delete(object id)
        {
            var group = context.GroupRepository.GetById((long)id);
            if (group != null)
            {
                context.GroupRepository.Delete(group);
                await context.SaveChangesAsync();
            }else
            {
                throw new Exception("Group not found");
            }
            return group.ToDTO();
        }

        public async Task<GroupDTO> GetById(object id)
        {
            var group = context.GroupRepository.GetById((long) id);
            if (group == null)
            {
                throw new Exception("Group not found");
            }
            return group.ToDTO();
        }

        public async Task<PageResponse<GroupDTO>> GetByNum(int index, int count, int num)
        {
            var  groups = context.GroupRepository.GetItems(filter: g => g.Num == num, index, count);
            return new PageResponse<GroupDTO>(groups.ToList().Select(g => g.ToDTO()), context.GroupRepository.GetItems(0, 1000000000).Count());
        }

        public async Task<PageResponse<GroupDTO>> GetBySector(int index, int count, string sector)
        {
            var groups = context.GroupRepository.GetItems(filter: g => g.sector == sector, index, count);
            return new PageResponse<GroupDTO>(groups.ToList().Select(g => g.ToDTO()), context.GroupRepository.GetItems(0, 100000000).Count());
        }

        public async Task<PageResponse<GroupDTO>> GetByYear(int index, int count, int year)
        {
            var groups = context.GroupRepository.GetItems(filter: g => g.year == year, index, count);
            return new PageResponse<GroupDTO>(groups.ToList().Select(g => g.ToDTO()), context.GroupRepository.GetItems(0,100000000).Count());
        }

        public async Task<PageResponse<GroupDTO>> Gets(int index, int count)
        {
            IEnumerable<GroupEntity> groups = context.GroupRepository.GetItems(index,count);
            return new PageResponse<GroupDTO>(groups.ToList().Select(g => g.ToDTO()), context.GroupRepository.GetItems(0, 1000000000).Count());
        }

        public async Task<GroupDTO> Update(GroupDTO group)
        {
            if(group == null)
            {
                throw new ArgumentNullException();
            }
            var existingGroup = context.GroupRepository.GetById(group.Id);
            if (existingGroup == null)
            {
                throw new Exception("Group not found");
            }
            existingGroup.year = group.Year;
            existingGroup.sector = group.sector;
            existingGroup.Num = group.Num;
            await context.SaveChangesAsync();
            return existingGroup.ToDTO();
        }
    }


}
