using AutoMapper;
using JobPortalAPI.DTOs;
using JobPortalAPI.Models;
using JobPortalAPI.Notifications;
using JobPortalAPI.UnitOfWork;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using System.Linq;

namespace JobPortalAPI.Controllers
{
    [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]

    [Route("api/[controller]")]
    [ApiController]
    public class InterviewsController : BaseController
    {
        private readonly IMapper _mapper;
        protected readonly JobPortalDBContext Context;
        private readonly UserManager<IdentityUser> _userManager;
        private readonly IHubContext<NotificationHub> _hubContext;

        private readonly IConfiguration _configuration;
        private DbSet<Interview> _dbSet;
        public InterviewsController(IUnitOfWork unitOfWork, IMapper mapper, JobPortalDBContext context, UserManager<IdentityUser> userManager, IConfiguration configuration, IHubContext<NotificationHub> hubContext)
        : base(unitOfWork)
        {
            _mapper = mapper;
            Context = context;
            _dbSet = Context.Set<Interview>();
            _userManager = userManager;
            _configuration = configuration;
            _hubContext = hubContext;

        }
        [HttpGet("getAllInterviewsByJobId/{id}")]
        public IActionResult getAllInterviewsByJobId(int id)
        {

            var interviews = _unitOfWork.InterviewRepo.GetAll().Where(n => n.JobId == id);
            if (interviews != null)
            {
                List<InterviewDto> x = new List<InterviewDto>();
                foreach (var interview in interviews)
                {
                    InterviewDto y = new InterviewDto();

                    y = _mapper.Map<InterviewDto>(interview);
                    var job = _unitOfWork.JobRepo.Get(interview.JobId);
                    y.JobName = job.Name;

                    var person = _unitOfWork.PersonRepo.Get(y.JobSeekerId);
                    y.Name = person.Name;

                    var filePath = Path.Combine("Images", person.Image);
                    y.Image = filePath;
                    x.Add(y);
                }
                List<InterviewDto> z = new List<InterviewDto>();
                for (int i = x.Count - 1; i >= 0; i--)
                {
                    z.Add(x[i]);
                }

                return Ok(z);
            }
            else
            {
                return NotFound("you don't have any interview for this job");
            }
        }
        [HttpGet("getNumberOfInterviewsByJobId/{id}")]
        public IActionResult getNumberOfInterviewsByJobId(int id)
        {

            var interviews = _unitOfWork.InterviewRepo.GetAll().Where(n => n.JobId == id);
            int x;

            if (interviews != null)
            {

                x = interviews.Count();
                return Ok(x);
            }
            else
            {
                return NotFound("you don't have any interview for this job");
            }
        }
        [HttpGet("getNumberOfInterviewsByJobseekerId/{id}")]
        public IActionResult getNumberOfInterviewsByJobseekerId(int id)
        {

            var interviews = _unitOfWork.InterviewRepo.GetAll().Where(n => n.JobSeekerId == id);
            int x;

            if (interviews != null)
            {

                x = interviews.Count();
                return Ok(x);
            }
            else
            {
                return NotFound("you don't have any interview for this job");
            }
        }
        [HttpGet("getAllInterviewsByJobseekerId/{id}")]
        public IActionResult getAllInterviewsByJobseekerId(int id)
        {

            var interviews = _unitOfWork.InterviewRepo.GetAll().Where(n => n.JobSeekerId == id);
            if (interviews != null)
            {


                List<InterviewDto> x = new List<InterviewDto>();
                foreach (var interview in interviews)
                {
                    InterviewDto y = new InterviewDto();
                    var job = _unitOfWork.JobRepo.Get(interview.JobId);
                    y = _mapper.Map<InterviewDto>(interview);

                    var person = _unitOfWork.PersonRepo.Get(y.CompanyId);
                    y.Name = person.Name;
                    y.JobName = job.Name;
                    var filePath = Path.Combine("Images", person.Image);
                    y.Image = filePath;
                    x.Add(y);
                }
                List<InterviewDto> z = new List<InterviewDto>();
                for (int i = x.Count - 1; i >= 0; i--)
                {
                    z.Add(x[i]);
                }

                return Ok(z);
            }
            else
            {
                return NotFound("you don't have any interview for this job");
            }
        }
        [HttpDelete("DeleteInterview")]
        public async Task<IActionResult> DeleteInterviewAsync([FromForm]InterviewDto dto)
        {
           if(ModelState.IsValid)
            {

                var inter = _unitOfWork.InterviewRepo.Get(dto.Id);
                _unitOfWork.InterviewRepo.Remove(inter);

                _unitOfWork.SaveChanges();
                var person = _unitOfWork.PersonRepo.Get(dto.CompanyId);
                var job = _unitOfWork.JobRepo.Get(dto.JobId);

                Notification notification = new Notification();
                notification.JobSeekerId = dto.JobSeekerId;
                notification.CompanyId = dto.CompanyId;
                notification.JobId = dto.JobId;
                notification.ToCompany = false;
                notification.IsRead = false;
                notification.Date = DateTime.Now;
                String details = $"Hello, {dto.Name},the {person.Name} company canceled your interview for {job.Name} work. ";
                notification.Details = details;
                _unitOfWork.NotificationRepo.Add(notification);
                _unitOfWork.SaveChanges();
                await _hubContext.Clients.Group($"jobseekerId_{dto.JobSeekerId}").SendAsync("ReceiveNotification", "new notification message");

                return Ok();
            }
            else
            {
                return BadRequest(new AuthResult() { Errors = new List<string>() { "Enter valid values" } });
            }
           
        }
        [HttpPut("UpdateInterview")]
        public async Task<IActionResult> UpdateInterviewAsync([FromForm] UpdateInterviewDto dto)
        {

          if(ModelState.IsValid)
            {
                var inter = _unitOfWork.InterviewRepo.Get(dto.Id);
                var companyperson = _unitOfWork.PersonRepo.Get(inter.CompanyId);
                var job = _unitOfWork.JobRepo.Get(inter.JobId);
                var jobseekerperson = _unitOfWork.PersonRepo.Get(inter.JobSeekerId);
                inter.Date = dto.Date;
                inter.Address = dto.Address;
                _unitOfWork.InterviewRepo.Update(inter);
                _unitOfWork.SaveChanges();

                Notification notification = new Notification();
                notification.JobSeekerId = inter.JobSeekerId;
                notification.CompanyId = inter.CompanyId;
                notification.JobId = inter.JobId;
                notification.ToCompany = false;
                notification.IsRead = false;
                notification.Date = DateTime.Now;
                String details = $"Hello, {jobseekerperson.Name},the {companyperson.Name} company updated your interview for {job.Name} work to : \n\nDate: {dto.Date} \nAddress: {dto.Address} ";
                notification.Details = details;
                _unitOfWork.NotificationRepo.Add(notification);
                _unitOfWork.SaveChanges();
                await _hubContext.Clients.Group($"jobseekerId_{jobseekerperson.Id}").SendAsync("ReceiveNotification", "new notification message");




                return Ok();
            }
          else
            {
                return BadRequest(new AuthResult() { Errors = new List<string>() { "Enter valid values" } });
            }

        }
        [HttpPost("BookInterview")]
        public async Task<IActionResult> BookInterviewAsync([FromForm]BookInterviewDto dto)
        {
          if(ModelState.IsValid)
            {
                var jobseeker = _unitOfWork.PersonRepo.Get(dto.JobSeekerId);
                var company = _unitOfWork.PersonRepo.Get(dto.CompanyId);
                var job = _unitOfWork.JobRepo.Get(dto.JobId);
                Interview interview = new Interview();
                interview = _mapper.Map<Interview>(dto);
                _unitOfWork.InterviewRepo.Add(interview);
                _unitOfWork.SaveChanges();
                Notification notification = new Notification();
                notification.JobId = dto.JobId;
                notification.JobSeekerId = dto.JobSeekerId;
                notification.CompanyId = dto.CompanyId;
                notification.IsRead = false;
                notification.ToCompany = false;
                notification.Date = DateTime.Now;
                String details = $"Hello {jobseeker.Name}, we are {company.Name} company, We have booked an appointment for you to conduct an interview for {job.Name} work at : \n\nDate: {dto.Date} \nAddress: {dto.Address}";
                notification.Details = details;
                _unitOfWork.NotificationRepo.Add(notification);
                _unitOfWork.SaveChanges();
                await _hubContext.Clients.Group($"jobseekerId_{dto.JobSeekerId}").SendAsync("ReceiveNotification", "new notification message");

                return Ok();
            }
            return BadRequest(new AuthResult() { Errors = new List<string>() { "Enter valid values" } });
        }

    }
}
