public async Task <IActionResult> CadastrarNovaVaga(CriarVagaInput input)
        {
            // Busca usuário por Id
            var usuarioDb = _usuarioRepository.GetById(input.UsuarioId);

            // Caso não existir
            if (usuarioDb == null)
            {
                return(StatusCode(404, $"Este Id de usuário [{input.UsuarioId}] não existe."));
            }

            // Busca o vinculo entre usuario X empresa
            var usuarioEmpresaDb = _usuarioEmpresaRepository.GetByUsuarioId(usuarioDb.Id);

            // Caso não achar, o usuário não é uma empresa
            if (usuarioEmpresaDb == null)
            {
                return(StatusCode(401, "Este usuário não tem permissão para criar uma vaga, pois não possuí um perfil de Empresa."));
            }

            if (!input.AreasRecomendadas.Any())
            {
                return(StatusCode(400, "A lista de áreas recomendadas da vaga não pode estar vazia."));
            }

            // Busca o municipio
            var municipioDb = _enderecoRepository.GetMunicipioById(input.Municipio.Id);

            // Caso não encontrar no BD
            if (municipioDb == null)
            {
                return(StatusCode(404, $"O município de [{input.Municipio.Descricao}] não existe no banco de dados."));
            }

            // Busca a faixa salarial
            var faixaSalarialDb = _faixaSalarialRepository.GetById(input.FaixaSalarial.Id);

            // Caso não encontrar no BD
            if (faixaSalarialDb == null)
            {
                return(StatusCode(404, $"A faixa salarial de [{input.FaixaSalarial.Descricao}] não existe no banco de dados."));
            }

            // Busca o tipo experiência
            var tipoExperienciaDb = _tipoExperienciaRepository.GetById(input.TipoExperiencia.Id);

            // Caso não encontrar no BD
            if (tipoExperienciaDb == null)
            {
                return(StatusCode(404, $"O tipo experiência de [{input.TipoExperiencia.Descricao}] não existe no banco de dados."));
            }

            List <Area> areasDb = new List <Area>();

            // ForEach para pesquisar se cada área recomendada da vaga selecionadas existem no BD
            foreach (var area in input.AreasRecomendadas)
            {
                // Busca a área
                var areaDb = _areaRepository.GetById(area.Id);

                // Caso não encontrar no BD
                if (areaDb == null)
                {
                    return(StatusCode(404, $"A área recomendada da vaga [{area.Descricao}] não existe no banco de dados."));
                }

                areasDb.Add(areaDb);
            }

            var statusVagaDb = _statusVagaRepository.GetByDescricao(StatusVagaDefaultValuesAcess.GetValue(StatusVagaDefaultValues.VagaAtiva));

            Vaga vaga = null;

            try
            {
                vaga = new Vaga(input.NomeVaga, input.Cargo, input.DescricaoVaga, input.DataEncerramento, statusVagaDb.Id, tipoExperienciaDb.Id, usuarioEmpresaDb.Id, municipioDb.Id, faixaSalarialDb.Id);
            }
            catch (Exception)
            {
                return(StatusCode(500, "Houve um erro interno ao criar a nova Vaga."));
            }

            var vagaDb = _vagaRepository.Create(vaga);

            List <AreaVagaRecomendada> recomendadas = new List <AreaVagaRecomendada>();

            AreaVagaRecomendada areaRecomendada = null;

            foreach (var area in areasDb)
            {
                try
                {
                    areaRecomendada = new AreaVagaRecomendada(area.Id, vagaDb.Id);

                    recomendadas.Add(areaRecomendada);
                }
                catch (Exception)
                {
                    return(StatusCode(500, "Houve um erro interno ao criar as áreas recomendadas para a Vaga."));
                }
            }

            _vagaRepository.CreateRangeAreasVagasRecomendadas(recomendadas);

            await _vagaRepository.UnitOfWork.SaveDbChanges();

            return(StatusCode(200, "A Vaga foi criada com sucesso!"));
        }
        public async Task <IActionResult> EmpresaEditarVaga(CriarVagaInput input, long vagaId)
        {
            // Busca usuário por Id
            var usuarioDb = _usuarioRepository.GetById(input.UsuarioId);

            // Caso não existir
            if (usuarioDb == null)
            {
                return(StatusCode(404, $"Este Id de usuário [{input.UsuarioId}] não existe."));
            }

            // Busca o vinculo entre usuario X empresa
            var usuarioEmpresaDb = _usuarioEmpresaRepository.GetByUsuarioId(usuarioDb.Id);

            // Caso não achar, o usuário não é uma empresa
            if (usuarioEmpresaDb == null)
            {
                return(StatusCode(401, "Este usuário não tem permissão para editar uma vaga, pois não possuí um perfil de Empresa."));
            }

            var vagaDb = _vagaRepository.GetById(vagaId);

            if (vagaDb == null)
            {
                return(StatusCode(404, $"Não foi encontrado uma vaga com id [{vagaId}] no banco de dados."));
            }

            // Verifica se a empresa é a criadora da vaga para assim ser liberado sua edição/encerramento
            if (vagaDb.UsuarioEmpresaId != usuarioEmpresaDb.Id)
            {
                return(StatusCode(403, $"Não é permitido empresas editarem vagas de outras empresas."));
            }

            if (!input.AreasRecomendadas.Any())
            {
                return(StatusCode(400, "A lista de áreas recomendadas da vaga não pode estar vazia."));
            }

            // Busca o municipio
            var municipioDb = _enderecoRepository.GetMunicipioById(input.Municipio.Id);

            // Caso não encontrar no BD
            if (municipioDb == null)
            {
                return(StatusCode(404, $"O município de [{input.Municipio.Descricao}] não existe no banco de dados."));
            }

            // Busca a faixa salarial
            var faixaSalarialDb = _faixaSalarialRepository.GetById(input.FaixaSalarial.Id);

            // Caso não encontrar no BD
            if (faixaSalarialDb == null)
            {
                return(StatusCode(404, $"A faixa salarial de [{input.FaixaSalarial.Descricao}] não existe no banco de dados."));
            }

            // Busca o tipo experiência
            var tipoExperienciaDb = _tipoExperienciaRepository.GetById(input.TipoExperiencia.Id);

            // Caso não encontrar no BD
            if (tipoExperienciaDb == null)
            {
                return(StatusCode(404, $"O tipo experiência de [{input.TipoExperiencia.Descricao}] não existe no banco de dados."));
            }

            // Altera as informações da Vaga
            try
            {
                vagaDb.AlterarInformacoesVaga(input.NomeVaga, input.Cargo, input.DescricaoVaga, input.DataEncerramento, tipoExperienciaDb.Id, municipioDb.Id, faixaSalarialDb.Id);

                // Altera a vaga na DB
                _vagaRepository.UpdateVaga(vagaDb);
            }
            catch (Exception)
            {
                return(StatusCode(500, "Houve um erro interno ao editar a vaga."));
            }

            // Pega todas as vagas recomendadas da vaga específica que esta sendo alterada
            var areasRecomendadasDb = _vagaRepository.GetAllAreaVagaRecomendadabyVagaId(vagaDb.Id);

            List <AreaVagaRecomendada> recomendadas = new List <AreaVagaRecomendada>();

            // Itera entre todas as novas vagas recomendadas
            AreaVagaRecomendada areaRecomendada = null;

            foreach (var area in input.AreasRecomendadas)
            {
                // Busca na DB se já existe a area recomendada selecionada para a vaga
                var areaRecomendadaDb = _vagaRepository.GetAreaVagaRecomendadabyVagaIdAndAreaId(vagaDb.Id, area.Id);

                // Caso não existir, cria uma nova area recomendada para a vaga
                if (areaRecomendadaDb == null)
                {
                    try
                    {
                        areaRecomendada = new AreaVagaRecomendada(area.Id, vagaDb.Id);

                        recomendadas.Add(areaRecomendada);
                    }
                    catch (Exception)
                    {
                        return(StatusCode(500, "Houve um erro interno ao criar as áreas recomendadas para a Vaga."));
                    }
                }
                else
                {
                    // Caso existir, quer dizer que o usuário quer altera-lo para ativo novamente, ou apenas, não alterou esta area específica

                    // Verifica se a area recomendada existente esta como "inativa"
                    if (areaRecomendadaDb.Ativo == false)
                    {
                        areaRecomendadaDb.AlterarParaAtivo();
                    }

                    // Altera a areaVagarecomendada específica no BD
                    _vagaRepository.UpdateAreaVagaRecomendada(areaRecomendadaDb);
                }
            }

            // Itera entre todas as vagas recomendadas da vaga do BD para verificar se usuário removeu alguma área recomendada selecionada no input
            foreach (var areaRec in areasRecomendadasDb)
            {
                // Verifica se alguma area recomendada do BD não existe no input de novas áreas enviado pelo usuário
                if (!input.AreasRecomendadas.Any(x => x.Id == areaRec.AreaId))
                {
                    // Caso area do BD NÃO existir no input, significa que o usuário removeu aquela area específica

                    // Altera a area do BD para "inativo"
                    areaRec.AlterarParaAntigo();

                    // Altera no BD
                    _vagaRepository.UpdateAreaVagaRecomendada(areaRec);
                }
            }

            // Caso existir novas areas recomendadas para a vaga, adiciona-as no BD
            if (recomendadas.Any())
            {
                _vagaRepository.CreateRangeAreasVagasRecomendadas(recomendadas);
            }

            // Salva todas as alterações no DB
            await _vagaRepository.UnitOfWork.SaveDbChanges();

            return(StatusCode(200, "Vaga editada com sucesso."));
        }