using AutoMapper;
using Common.Dtos.Exper;
using Common.Dtos.Group;
using Hushian.Application.Contracts.Persistence;
using Hushian.Application.Models;
using Common.Validation;
using Hushian.Domain.Entites;
using Microsoft.EntityFrameworkCore;

namespace Hushian.Application.Services
{
    public class GroupService
    {
        private readonly IGenericRepository<Group> _GroupRepository;
        private readonly IGenericRepository<ExperGroup> _EGRepository;
        private readonly IMapper _mapper;
        private readonly ExperService _experService;

        public GroupService(IGenericRepository<Group> groupRepository
            , IGenericRepository<ExperGroup> eGRepository
            , IMapper mapper, ExperService experService)
        {
            _GroupRepository = groupRepository;
            _EGRepository = eGRepository;
            _mapper = mapper;
            _experService = experService;
        }

        public async Task<ResponseBase<bool>> NewGroup(ADD_GroupDto model, int CompanyID)
        {
            ResponseBase<bool> Response = new();
            if (!model.Name.IsOnlyPersianLetters())
                Response.Errors.Add("نام باید کاملا به صورت فارسی باشد");
            else if (!string.IsNullOrEmpty(model.Info) && !model.Info.IsOnlyPersianLetters())
                Response.Errors.Add("توضیحات باید کاملا به صورت فارسی باشد");
            else if (model.img != null && !model.img.IsValidImage())
                Response.Errors.Add("تصویر نمی تواند از 5 مگ بیشتر باشد");
            else
            {
                var nGroup = _mapper.Map<Group>(model);
                nGroup.CompanyID = CompanyID;
                Response.Value = await _GroupRepository.ADDBool(nGroup);
                if (Response.Value) Response.Success = true;

                else
                {
                    Response.Errors.Add("خطا در ذخیره سازی");
                }

            }
            return Response;
        }
        public async Task<List<Read_GroupDto>> GetGroupsCompany(int CompanyID)
        {
            var entity = await _GroupRepository.Get().Where(f => f.CompanyID == CompanyID).ToListAsync();
            return _mapper.Map<List<Read_GroupDto>>(entity);
        }
        public async Task<List<Read_GroupDto>> GetGroupsExper(int ExperID)
        {
            var entity = await _GroupRepository.Get().Where(f => f.EG.Any(a=>a.ExperID==ExperID)).ToListAsync();
            return _mapper.Map<List<Read_GroupDto>>(entity);
        }
        public async Task<ResponseBase<bool>> UpdateGroup(Update_GroupDto model, int CompanyID)
        {
            ResponseBase<bool> Response = new();
            if (!model.Name.IsOnlyPersianLetters())
                Response.Errors.Add("نام باید کاملا به صورت فارسی باشد");
            else if (!string.IsNullOrEmpty(model.Info) && !model.Info.IsOnlyPersianLetters())
                Response.Errors.Add("توضیحات باید کاملا به صورت فارسی باشد");
            else if (model.img != null && !model.img.IsValidImage())
                Response.Errors.Add("تصویر نمی تواند از 5 مگ بیشتر باشد");
            else
            {
                try
                {
                    var entity = await _GroupRepository.Get().FirstOrDefaultAsync(f => f.ID == model.ID && f.CompanyID == CompanyID);
                    entity.Name = model.Name;
                    entity.Info = model.Info;
                    entity.img = model.img;

                    Response.Value = await _GroupRepository.UPDATEBool(entity);
                    if (Response.Value)
                        Response.Success = true;
                    else
                    {
                        Response.Errors.Add("خطا در ذخیره سازی");
                    }
                }
                catch (Exception ex)
                {
                    Response.Errors.Add("خطای سیستمی");
                }
            }

            return Response;
        }
        public async Task<bool> ChangeAvailableGroup(ChangeAvailable_GroupDto model, int CompanyID)
        {
            try
            {
                var entity = await _GroupRepository.Get().FirstOrDefaultAsync(f => f.ID == model.ID && f.CompanyID == CompanyID);
                entity.Available = model.Available;
                return await _GroupRepository.UPDATEBool(entity);

            }
            catch (Exception ex)
            {
                return false;
            }
        }
        public async Task<ResponseBase<bool>> DeleteGroup(int GroupID,int CompanyID)
        {
            ResponseBase<bool> Response = new();

            var Group =  await _GroupRepository.Get().FirstOrDefaultAsync(a => a.CompanyID == CompanyID && a.ID == GroupID);
            if (Group!=null) Response.Value=Response.Success=  await _GroupRepository.DELETE(Group);
            else Response.Errors.Add("یافت نشد");
            
            return Response;
        }
        public async Task<ResponseBase<bool>> JoinExperInGroup(int GroupID, int ExperID, int CompanyID)
        {
            ResponseBase<bool> Response = new();

            if (await CHeckGroupMemberCompany(GroupID,CompanyID))
            {
                if (await _experService.CheckExperInCompany(CompanyID,ExperID))
                {
                    Response.Value=Response.Success= await _EGRepository.ADDBool(new ExperGroup()
                    {
                        ExperID = ExperID,
                        GroupID = GroupID
                    });
                }
                else Response.Errors.Add("کارشناس یافت نشد");

            }
            else Response.Errors.Add("گروه یافت نشد");
            
                return Response;
        }
        public async Task<ResponseBase<bool>> UnJoinExperInGroup(int GroupID, int ExperID, int CompanyID)
        {
            ResponseBase<bool> Response = new();

            if (await CHeckGroupMemberCompany(GroupID, CompanyID))
            {
                if (await _experService.CheckExperInCompany(CompanyID, ExperID))
                {
                    try
                    {
                        var eg =await _EGRepository.Get().FirstOrDefaultAsync(w=>w.GroupID==GroupID && w.ExperID==ExperID);
                        Response.Value = Response.Success = eg==null ? true : await _EGRepository.DELETE(eg);
                    }
                    catch (Exception)
                    {

                        throw;
                    }
                 
                }
                else Response.Errors.Add("کارشناس یافت نشد");

            }
            else Response.Errors.Add("گروه یافت نشد");

            return Response;
        }
        public async Task<bool> AnyGroup(int GroupID) =>
           await _GroupRepository.Get().AnyAsync(a=>a.ID==GroupID);
        public async Task<bool> CHeckGroupMemberCompany(int GroupID, int CompanyID)=>
            await _GroupRepository.Get().AnyAsync(a => a.CompanyID == CompanyID && a.ID == GroupID);
        public async Task<List<Read_ExperDto>> GetExpersFromGroupID(int GroupID)
            => _mapper.Map<List<Read_ExperDto>>( await _EGRepository.Get().Where(w => w.GroupID == GroupID).Select(s=>s.Exper).ToListAsync());

    }
}
