using AutoMapper;
using JobPortalAPI.DTOs;
using JobPortalAPI.Models;
using JobPortalAPI.UnitOfWork;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

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

    [Route("api/[controller]")]
    [ApiController]
    public class JobsController : BaseController
    {
        private readonly IMapper _mapper;
        public JobsController(IUnitOfWork unitOfWork, IMapper mapper)
            : base(unitOfWork)
        {
            _mapper = mapper;

        }
        [HttpGet("GetNumberOfJobSeekers/{id}")]
        public IActionResult GetNumberOfJobSeeker(int id )
        { 
            var entries = _unitOfWork.JobEntryRepo.GetAll().Where(e => e.JobId == id);
            int x = entries.Count();
            return Ok(x);
        }
            [HttpGet]
        public IActionResult GetAll()
        {
            var Jobs = _unitOfWork.JobRepo.GetAllJobsDetails().Where(j=> j.Status == "ON");
            List<JobDetailsDto> JobDetailsDtos = new List<JobDetailsDto>();
            foreach (Job v in Jobs)
            {
                JobDetailsDto JobDetailsDto = new JobDetailsDto();
                JobDetailsDto.Id = v.Id;
                JobDetailsDto.Name = v.Name;
                JobDetailsDto.Sallary = v.Sallary;
                JobDetailsDto.Status = v.Status;
                JobDetailsDto.Description = v.Description;
                JobDetailsDto.TimeType = v.TimeType;
                JobDetailsDto.CompanyId = v.CompanyId;

                var person = _unitOfWork.PersonRepo.Get(v.CompanyId);
                JobDetailsDto.CompanyName = person.Name;
                JobDetailsDto.Phone = person.Phone;
                JobDetailsDto.Email = person.Email;
                var specification = _unitOfWork.SpecificationRepo.Get(v.SpecificationId);
                JobDetailsDto.SpecificationName = specification.Name;
                //string currentDirectory = Directory.GetCurrentDirectory();
                var filePath = Path.Combine("Images", person.Image);
                //var fullPath = Path.Combine(currentDirectory, filePath);
                //byte[] myimage = System.IO.File.ReadAllBytes(fullPath);
                JobDetailsDto.Image = filePath;

                foreach (var item in v.JobSkills)
                {
                    SkillDto x = new SkillDto();
                    x.PracticePeriod = item.PracticePeriod;
                    var skill = _unitOfWork.SkillRepo.Get(item.SkillId);
                    x.SkillId = skill.Id;
                    x.Name = skill.Name;
                    if (x != null)
                    {
                        JobDetailsDto.skills.Add(x);

                    }
                    
                }
                JobDetailsDtos.Add(JobDetailsDto);
            }
            return Ok(JobDetailsDtos);
        }
       
        [HttpGet("GetAllJobsByCompanyId")]
        public IActionResult GetAllJobsByCompanyId(int id)
        {
            var Jobs = _unitOfWork.JobRepo.GetAllJobsDetailsByCompanyId(id);
            List<JobDetailsDto> JobDetailsDtos = new List<JobDetailsDto>();
            foreach (Job v in Jobs)
            {
                JobDetailsDto JobDetailsDto = new JobDetailsDto();
                JobDetailsDto.Id = v.Id;
                JobDetailsDto.Name = v.Name;
                JobDetailsDto.Sallary = v.Sallary;
                JobDetailsDto.Status = v.Status;
                JobDetailsDto.Description = v.Description;
                JobDetailsDto.TimeType = v.TimeType;
                JobDetailsDto.CompanyId = v.CompanyId;

                var person = _unitOfWork.PersonRepo.Get(v.CompanyId);
                JobDetailsDto.CompanyName = person.Name;
                JobDetailsDto.Phone = person.Phone;
                JobDetailsDto.Email = person.Email;
                var specification = _unitOfWork.SpecificationRepo.Get(v.SpecificationId);
                JobDetailsDto.SpecificationName = specification.Name;
                //string currentDirectory = Directory.GetCurrentDirectory();
                var filePath = Path.Combine("Images", person.Image);
                //var fullPath = Path.Combine(currentDirectory, filePath);
                //byte[] myimage = System.IO.File.ReadAllBytes(fullPath);
                JobDetailsDto.Image = filePath;

                foreach (var item in v.JobSkills)
                {
                    SkillDto x = new SkillDto();
                    x.PracticePeriod = item.PracticePeriod;
                    var skill = _unitOfWork.SkillRepo.Get(item.SkillId);
                    x.SkillId = skill.Id;
                    x.Name = skill.Name;
                    if (x != null)
                    {
                        JobDetailsDto.skills.Add(x);

                    }

                }
                JobDetailsDtos.Add(JobDetailsDto);
            }
            return Ok(JobDetailsDtos);
        }
        [HttpGet("GetAllJobsByJobseekerId")]
        public IActionResult GetAllJobsByJobseekerId(int id)
        {
            var entries = _unitOfWork.JobEntryRepo.GetAll().Where(e => e.JobSeekerId == id);
            //var Jobs = _unitOfWork.JobRepo.GetAllJobsDetailsByCompanyId(id);
            List<JobDetailsDto> JobDetailsDtos = new List<JobDetailsDto>();
            foreach (JobEntry entry in entries)
            {
                var v = _unitOfWork.JobRepo.GetAllJobDetails(entry.JobId);
                var person = _unitOfWork.PersonRepo.Get(v.CompanyId);

                JobDetailsDto JobDetailsDto = new JobDetailsDto();
                JobDetailsDto.Id = v.Id;
                JobDetailsDto.Name = v.Name;
                JobDetailsDto.Sallary = v.Sallary;
                JobDetailsDto.Status = v.Status;
                JobDetailsDto.Description = v.Description;
                JobDetailsDto.TimeType = v.TimeType;
                JobDetailsDto.CompanyId = v.CompanyId;
                JobDetailsDto.CompanyName = person.Name;
                JobDetailsDto.Phone = person.Phone;
                JobDetailsDto.Email = person.Email;
                var specification = _unitOfWork.SpecificationRepo.Get(v.SpecificationId);
                JobDetailsDto.SpecificationName = specification.Name;
                //string currentDirectory = Directory.GetCurrentDirectory();
                var filePath = Path.Combine("Images", person.Image);
                //var fullPath = Path.Combine(currentDirectory, filePath);
                //byte[] myimage = System.IO.File.ReadAllBytes(fullPath);
                JobDetailsDto.Image = filePath;

                foreach (var item in v.JobSkills)
                {
                    SkillDto x = new SkillDto();
                    x.PracticePeriod = item.PracticePeriod;
                    var skill = _unitOfWork.SkillRepo.Get(item.SkillId);
                    x.SkillId = skill.Id;
                    x.Name = skill.Name;
                    if (x != null)
                    {
                        JobDetailsDto.skills.Add(x);

                    }

                }
                JobDetailsDtos.Add(JobDetailsDto);
            }
            return Ok(JobDetailsDtos);
        }
        [HttpGet("id")]
        public IActionResult GetById(int id)
        {
            var Job = _unitOfWork.JobRepo.GetAllJobDetails(id);
            
            JobDetailsDto JobDetailsDto = new JobDetailsDto();
            JobDetailsDto.Id = Job.Id;
            JobDetailsDto.Name = Job.Name;
            JobDetailsDto.Sallary = Job.Sallary;
            JobDetailsDto.Status = Job.Status;
            JobDetailsDto.Description = Job.Description;
            JobDetailsDto.TimeType = Job.TimeType;
            JobDetailsDto.CompanyId = Job.CompanyId;

            var person = _unitOfWork.PersonRepo.Get(Job.CompanyId);
            JobDetailsDto.CompanyName = person.Name;
            JobDetailsDto.Phone = person.Phone;
            JobDetailsDto.Email = person.Email;
            var specification = _unitOfWork.SpecificationRepo.Get(Job.SpecificationId);
            JobDetailsDto.SpecificationName = specification.Name;
            //string currentDirectory = Directory.GetCurrentDirectory();
            var filePath = Path.Combine("Images", person.Image);
            //var fullPath = Path.Combine(currentDirectory, filePath);
            //byte[] myimage = System.IO.File.ReadAllBytes(fullPath);
            JobDetailsDto.Image = filePath;
            foreach (var item in Job.JobSkills)
            {
                SkillDto x = new SkillDto();
                x.PracticePeriod = item.PracticePeriod;
                var skill = _unitOfWork.SkillRepo.Get(item.SkillId);
                x.SkillId = skill.Id;
                x.Name = skill.Name;
                if (x != null)
                {
                    JobDetailsDto.skills.Add(x);
                }

            }
            
            return Ok(JobDetailsDto);
        }
        [HttpPost("CreateJob")]
        public IActionResult CreateJob([FromForm] JobDto dto)
        {
            if (ModelState.IsValid)
            {
                Job job = _mapper.Map<Job>(dto);
                var specification = _unitOfWork.SpecificationRepo.GetAll().FirstOrDefault(s => s.Name == dto.SpecificationName.ToUpper());
                if (specification == null)
                {
                    specification = new Specification
                    {
                        Name = dto.SpecificationName.ToUpper()
                    };
                    _unitOfWork.SpecificationRepo.Add(specification);
                    _unitOfWork.SaveChanges();
                    job.Specification = specification;
                    job.SpecificationId = specification.Id;
                }
                else
                {
                    job.Specification = specification;
                    job.SpecificationId = specification.Id;
                }
                _unitOfWork.JobRepo.Add(job);
                _unitOfWork.SaveChanges();
                return Ok();
            }
            else
            {
                return BadRequest();
            }

        }
        [HttpPut("UpdateJob/{id}")]
        public IActionResult UpdateJob(int id ,[FromForm] JobDto dto)
        {


            if (ModelState.IsValid)
            {
                var job = _unitOfWork.JobRepo.Get(id);
                 _mapper.Map(dto, job);
                var specification = _unitOfWork.SpecificationRepo.GetAll().FirstOrDefault(s => s.Name == dto.SpecificationName.ToUpper());
                if (specification == null)
                {
                    specification = new Specification
                    {
                        Name = dto.SpecificationName.ToUpper()
                    };
                    _unitOfWork.SpecificationRepo.Add(specification);
                    _unitOfWork.SaveChanges();
                    job.Specification = specification;
                    job.SpecificationId = specification.Id;
                }
                else
                {
                    job.Specification = specification;
                    job.SpecificationId = specification.Id;
                }
                _unitOfWork.JobRepo.Update(job);
                _unitOfWork.SaveChanges();
                return Ok();
            }
            else
            {
                return BadRequest();
            }

        }
        [HttpDelete("DeleteJob/{id}")]
        public IActionResult DeleteJob(int id)
        {
            var job = _unitOfWork.JobRepo.Get(id);


            if (job == null)
            {
                return NotFound();
            }
            var jobskills = _unitOfWork.JobSkillRepo.GetAll().Where(js => js.JobId == id);
            foreach(var js in jobskills)
            {
                _unitOfWork.JobSkillRepo.Remove(js);
                _unitOfWork.SaveChanges();
            }
            var interviews = _unitOfWork.InterviewRepo.GetAll().Where(i => i.JobId == id);
            foreach (var i in interviews)
            {
                _unitOfWork.InterviewRepo.Remove(i);
                _unitOfWork.SaveChanges();
            }
            var jobentries = _unitOfWork.JobEntryRepo.GetAll().Where(j => j.JobId == id);
            foreach (var e in jobentries)
            {
                _unitOfWork.JobEntryRepo.Remove(e);
                _unitOfWork.SaveChanges();
            }
            var notifications = _unitOfWork.NotificationRepo.GetAll().Where(n => n.JobId == id);
            foreach (var n in notifications)
            {
                _unitOfWork.NotificationRepo.Remove(n);
                _unitOfWork.SaveChanges();
            }

            _unitOfWork.JobRepo.Remove(job);
            _unitOfWork.SaveChanges();
            return Ok();
        }

        [HttpPost("AddSkills/{id}")]
        public IActionResult AddSkills(int id, JobSkillDto Myskill)
        {
           if(ModelState.IsValid)
            {
                Boolean y = false;
                var job = _unitOfWork.JobRepo.Get(id);

                JobSkill Jobskill = new JobSkill();
                Jobskill.JobId = job.Id;
                Jobskill.PracticePeriod = Myskill.PracticePeriod;

                var sk = _unitOfWork.SkillRepo.GetAll().FirstOrDefault(s => s.Name.ToUpper().Contains(Myskill.Name.ToUpper()));
                if (sk == null)
                {
                    Skill skill = new Skill()
                    {
                        Name = Myskill.Name.ToUpper(),
                    };
                    _unitOfWork.SkillRepo.Add(skill);
                    _unitOfWork.SaveChanges();
                    Jobskill.SkillId = skill.Id;
                    _unitOfWork.JobSkillRepo.Add(Jobskill);
                    _unitOfWork.SaveChanges();

                }
                else
                {

                    var x = _unitOfWork.JobSkillRepo.GetAll().FirstOrDefault(j => j.JobId == id && j.SkillId == sk.Id);
                    if (x == null)
                    {
                        Jobskill.SkillId = sk.Id;
                        _unitOfWork.JobSkillRepo.Add(Jobskill);
                        _unitOfWork.SaveChanges();

                    }
                    else
                    {
                        x.PracticePeriod = Myskill.PracticePeriod;
                        _unitOfWork.JobSkillRepo.Update(x);
                        _unitOfWork.SaveChanges();
                        y = true;
                    }
                }

                if (y == false)
                {
                    return Ok();
                }
                else
                {
                    return Ok("The skills are added, but there were skills  already exist so just updated the practice period !!!");
                }
            }
           else
            {
                return BadRequest(new AuthResult() { Errors = new List<string>() { "Enter valid values" } });
            }
        }

        [HttpPut("UpdateSkill/{id}")]
        public IActionResult UpdateSkill(int id, SkillDto skillDto)
        {
            if(ModelState.IsValid)
            {
                var jobskill = _unitOfWork.JobSkillRepo.GetAll().FirstOrDefault(js => js.JobId == id && js.SkillId == skillDto.SkillId);
                jobskill.PracticePeriod = skillDto.PracticePeriod;
                var skill = _unitOfWork.SkillRepo.GetAll().FirstOrDefault(s => s.Name.ToUpper().Contains(skillDto.Name.ToUpper()));
                if (skill == null)
                {
                    Skill sk = new Skill()
                    {
                        Name = skillDto.Name.ToUpper(),
                    };
                    _unitOfWork.SkillRepo.Add(sk);
                    _unitOfWork.SaveChanges();
                    jobskill.SkillId = sk.Id;
                    _unitOfWork.JobSkillRepo.Update(jobskill);
                    _unitOfWork.SaveChanges();
                    return Ok();
                }
                else
                {
                    jobskill.SkillId = skill.Id;
                    _unitOfWork.JobSkillRepo.Update(jobskill);
                    _unitOfWork.SaveChanges();
                    return Ok();
                }

            }
            else
            {
                return BadRequest(new AuthResult() { Errors = new List<string>() { "Enter valid values" } });
            }
        }
        [HttpDelete("DeleteSkill/{id}")]
        public IActionResult DeleteSkill(int id, int skillid)
        {
            var jobskill = _unitOfWork.JobSkillRepo.GetAll().FirstOrDefault(js => js.JobId == id && js.SkillId == skillid);
            _unitOfWork.JobSkillRepo.Remove(jobskill);
            _unitOfWork.SaveChanges();
            return Ok();
        }

        
    }
}
