/// <summary>
        /// get user id, make sure he's real, return his user id and his video id
        /// </summary>
        /// <param name="id">user id</param>
        /// <returns>user id and video id if rented, else 0</returns>
        public StatusModel<RentVideoModel> GetRentUser(int id)
        {
            var result = new StatusModel<RentVideoModel>();
            result.Data = new RentVideoModel();
            result.Data.UserID = id;
            try
            {
                using (Repository repository = new Repository())
                {
                    var userEntity = repository.UserRepository.GetByKey(id);
                    if (userEntity == null)
                    {
                        result.Success = false; result.Message = "user not founded"; result.Data = new RentVideoModel();
                        return result;
                    }
                    result.Data.UserName = userEntity.Name;
                    var video = repository.VideoRepository.GetUserMovie(id);
                    if (video != null)
                    {
                        result.Data.VideoID = video.ID;
                    }

                }
            }
            catch (Exception)
            {
                result.Success = false;
                result.Message = "unexpected ERROR";
            }
            return result;
        }
        public ActionResult RentVideo(RentVideoModel model)
        {
            var result = new StatusModel();

            var rentBL = new RentBL();
            result = rentBL.RentVideo(model);

            return Json(result);
        }
        public ActionResult ReturnVideo(RentVideoModel model)
        {
            var result = new StatusModel();

            var rentBL = new RentBL();
            result = rentBL.ReturnVideo(model);

            return Json(result, JsonRequestBehavior.AllowGet);
        }
        public ActionResult ReturnUserVideo(int userId)
        {
            var result = new StatusModel();

            var rentBL = new RentBL();
            result = rentBL.ReturnUserVideo(userId);

            return Json(result,JsonRequestBehavior.AllowGet);
        }
        /// <summary>
        /// login action logic
        /// </summary>
        /// <param name="model">model contains credentials</param>
        /// <returns>true or false if authenticated and attached the relevant controller.</returns>
        public StatusModel<string> Login(UserLoginModel model)
        {
            var result = new StatusModel<string>();
            try
            {
                using (var repository = new Repository())
                {

                    var user = repository.UserRepository.GetByKey(model.ID);
                    if (user == null)
                    {
                        result.Success = false;
                        result.Message = "User not found";
                        return result;
                    }
                    //user founded - compare passwords
                    if (user.Password == model.Password)
                    {
                        result.Success = true;
                        result.Message = "Log In Success";
                        //access granted
                        switch (user.Name)
                        {
                            case "Admin":
                                result.Data = "Admin";
                                break;
                            default:
                                result.Data = "User/Index?id=" + model.ID;
                                break;
                        }
                    }
                    else
                    {
                        //access denied
                        result.Success = false;
                        result.Message = "Bad Credentials";
                        return result;
                    }
                }
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Message = "Unexpected Error";
            }

            return result;
        }
        public JsonResult GetVideos(VideoSearchModel searchModel)
        {
            var result = new StatusModel<List<VideoDataTableModel>>();
            var videoBL = new VideoBL();
            result = videoBL.GetVideos(searchModel);

            if (result.Success)
            {
                //return Json(result.Data);
                return Json(new { data = result.Data }, JsonRequestBehavior.AllowGet);
            }
            else
            {
                return Json(new List<VideoModel>());
            }
        }
        //public ActionResult AddVideo(VideoModel model)
        //{
        //    var result = new StatusModel(true);
        //    //validation
        //    if (string.IsNullOrWhiteSpace(model.Name) || string.IsNullOrWhiteSpace(model.Director) || model.Year == 0 || string.IsNullOrWhiteSpace(model.Genre))
        //    {
        //        result.Success = false; result.Message = "Bad Parameters";
        //        return Json(result);
        //    }
        //    var videoBL = new VideoBL();
        //    result = videoBL.Add(model);
        //    return Json(result);
        //}
        public ActionResult EditVideo(VideoModel model)
        {
            var result = new StatusModel(true);

            //validation
            if (string.IsNullOrWhiteSpace(model.Name) || string.IsNullOrWhiteSpace(model.Director) || model.Year == 0 || string.IsNullOrWhiteSpace(model.Genre))
            {
                result.Success = false; result.Message = "Bad Parameters";
                return Json(result);
            }

            var videoBL = new VideoBL();
            result = videoBL.Edit(model);

            return Json(result);
        }
        public ActionResult GetVideo(VideoModel model)
        {
            var result = new StatusModel<VideoModel>(true);

            if (model.ID != 0)
            {

                var videoBL = new VideoBL();
                result = videoBL.Get(model);
            }
            else
            {
                result.Data = new VideoModel();
            }

            return View("_Get", result.Data);
        }
        /// <summary>
        /// method that gets only user id and return his book
        /// </summary>
        /// <param name="model">contains user id</param>
        /// <returns>success/nor</returns>
        public StatusModel ReturnUserVideo(int userid)
        {
            var result = new StatusModel(); result.Success = true;
            try
            {
                using (var repository = new Repository())
                {
                    //check if user is renting currently video and if video's renter id is that user
                    var user = repository.UserRepository.GetByKey(userid);
                    if (user == null || !user.IsRenting)
                    {
                         result.Success = false;
                        result.Message = "user doesnt renting any movie ";
                        return result;
                    }
                    var video = repository.VideoRepository.GetUserMovie(userid);

                    if ( video == null)
                    {
                        result.Success = false;
                        result.Message = "user movie not founded";
                        return result;
                    }

                    if (!user.IsRenting || video.RenterID != user.ID)
                    {
                        result.Success = false;
                        result.Message = "return video proccess cannot be exceuted";
                        return result;
                    }

                    //commit returning video
                    user.IsRenting = false;
                    video.RenterID = null;
                    repository.UserRepository.Commit();
                }
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Message = "unexpected ERROR";
            }
            return result;
        }
 /// <summary>
 /// add specifiec video to DB
 /// </summary>
 /// <param name="model">model contains video properties</param>
 /// <returns>success/nor</returns>
 public StatusModel Add(VideoModel model)
 {
     var result = new StatusModel(true);
     try
     {
         using (Repository repository = new Repository())
         {
             var video = model.GetEntity();
             repository.VideoRepository.Insert(video);
             repository.VideoRepository.Commit();
         }
     }
     catch (Exception)
     {
         result.Success = false;
         result.Message = "unexpected ERROR";
     }
     return result;
 }
        /// <summary>
        /// edit specifiec video from DB or add new one
        /// </summary>
        /// <param name="model">model contains video properties</param>
        /// <returns>success/nor</returns>
        public StatusModel Edit(VideoModel model)
        {
            var result = new StatusModel(true, "Save Completed Successfully");
            try
            {
                using (Repository repository = new Repository())
                {
                    if (model.ID == 0)
                    {
                        //add
                        var video = new Video();
                        video.Brief = model.Brief;
                        video.Director = model.Director;
                        video.Genre = model.Genre;
                        video.Name = model.Name;
                        video.Year = model.Year;

                        repository.VideoRepository.Insert(video);
                    }
                    else
                    {

                        //edit
                        var video = repository.VideoRepository.GetByKey(model.ID);
                        video.Brief = model.Brief;
                        video.Director = model.Director;
                        video.Genre = model.Genre;
                        video.Name = model.Name;
                        video.Year = model.Year;
                    }

                    repository.VideoRepository.Commit();
                }
            }
            catch (Exception)
            {
                result.Success = false;
                result.Message = "unexpected ERROR";
            }
            return result;
        }
        /// <summary>
        /// method that executing the renting action
        /// </summary>
        /// <param name="model">model containrs user id and video id</param>
        /// <returns>success/nor</returns>
        public StatusModel RentVideo(RentVideoModel model)
        {
            var result = new StatusModel(); result.Success = true;
            try
            {

                using (var repository = new Repository())
                {
                    //check if user already renting video and if video is 'free'
                    var user = repository.UserRepository.GetByKey(model.UserID);
                    var video = repository.VideoRepository.GetByKey(model.VideoID);

                    if (user == null || video == null)
                    {
                        result.Success = false;
                        result.Message = "Bad parameters";
                        return result;
                    }

                    if (user.IsRenting || video.RenterID != null)
                    {
                        result.Success = false;
                        result.Message = "rent proccess cannot be exceuted";
                        return result;
                    }

                    //commit renting
                    user.IsRenting = true;
                    video.RenterID = user.ID;
                    repository.UserRepository.Commit();
                }
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Message = "unexpected ERROR";
            }

            return result;
        }
 public StatusModel<UserModel> Get(int id)
 {
     var result = new StatusModel<UserModel>(true);
     try
     {
         using (Repository repository = new Repository())
         {
             var userEntity = repository.UserRepository.GetByKey(id);
             if (userEntity == null)
             {
                 result.Success = false; result.Message = "user not founded"; result.Data = new UserModel();
                 return result;
             }
             result.Data = new UserModel(userEntity);
         }
     }
     catch (Exception)
     {
         result.Success = false;
         result.Message = "unexpected ERROR";
     }
     return result;
 }
        public ActionResult UploadThumb(int videoId)
        {
            var result = new StatusModel(true,"Upload Success");
                string fName = "";
            try
            {
                //saving file section
                HttpPostedFileBase file = Request.Files[0];
                //Save file content goes here
                fName = file.FileName;
                if (file != null && file.ContentLength > 0 && videoId > 0)
                {

                    var originalDirectory = new DirectoryInfo(string.Format("{0}Images\\Thumbs", Server.MapPath(@"\")));

                    string pathString = System.IO.Path.Combine(originalDirectory.ToString(), videoId.ToString());

                    //var fileName1 = Path.GetFileName(file.FileName);

                    bool isExists = System.IO.Directory.Exists(pathString);

                    if (!isExists)
                        System.IO.Directory.CreateDirectory(pathString);

                    var path = string.Format("{0}\\{1}", pathString, file.FileName);
                    file.SaveAs(path);

                }
            }
            catch (Exception ex)
            {
                result.Success = false; result.Message = "Error Occured " + ex.Message;
            }
            if (result.Success )//image upload success - continue to save image name in DB
            {
                var videoBL = new VideoBL();
                result = videoBL.SaveThumbName(videoId,fName);
            }
            return Json(result, JsonRequestBehavior.AllowGet);
        }
        /// <summary>
        /// remove specifiec video from DB
        /// </summary>
        /// <param name="model">model contains video id</param>
        /// <returns>success/nor</returns>
        public StatusModel Remove(VideoModel model)
        {
            var result = new StatusModel(true);
            try
            {
                using (Repository repository = new Repository())
                {
                    var video = repository.VideoRepository.GetByKey(model.ID);
                    if (video == null)
                    {
                        result.Success = false; result.Message = "Video not found";
                        return result;
                    }
                    if (video.RenterID != null)
                    {
                        result.Success = false; result.Message = "Video is rented";
                        return result;
                    }

                    repository.VideoRepository.Delete(video);
                    repository.VideoRepository.Commit();
                }
            }
            catch (Exception)
            {
                result.Success = false;
                result.Message = "unexpected ERROR";
            }
            return result;
        }
 /// <summary>
 /// save the thumb name for specific video
 /// </summary>
 /// <param name="videoId"></param>
 /// <param name="fName"></param>
 /// <returns>success/nor</returns>
 public StatusModel SaveThumbName(int videoId, string fName)
 {
     var result = new StatusModel(true,"sacve thumb in DB success");
     try
     {
         using (Repository repository = new Repository())
         {
             var video = repository.VideoRepository.GetByKey(videoId);
             if (video == null)
             {
                 result.Success = false;
                 result.Message = "video not exist";
                 return result;
             }
             video.Thumb = fName;
             repository.VideoRepository.Commit();
         }
     }
     catch (Exception ex)
     {
         result.Success = false; result.Message = "error: " + ex.Message;
     }
     return result;
 }
 /// <summary>
 /// get specifiec video from DB
 /// </summary>
 /// <param name="model">model contains video id</param>
 /// <returns>success/nor and entity model</returns>
 public StatusModel<VideoModel> Get(VideoModel model)
 {
     var result = new StatusModel<VideoModel>(true);
     try
     {
         using (Repository repository = new Repository())
         {
             var videoEntity = repository.VideoRepository.GetByKey(model.ID);
             if (videoEntity == null)
             {
                 result.Success = false; result.Message = "Video not founded";
                 return result;
             }
             result.Data = new VideoModel(videoEntity);
         }
     }
     catch (Exception)
     {
         result.Success = false;
         result.Message = "unexpected ERROR";
     }
     return result;
 }
        public ActionResult RemoveVideo(VideoModel model)
        {
            var result = new StatusModel(true);

            var videoBL = new VideoBL();
            result = videoBL.Remove(model);

            return Redirect("/admin");
        }
        /// <summary>
        /// method that return all relevant videos
        /// </summary>
        /// <param name="searchModel">model contains all the search parameters</param>
        /// <returns>succes/nor and relevant videos</returns>
        public StatusModel<List<VideoDataTableModel>> GetVideos(VideoSearchModel searchModel)
        {
            var result = new StatusModel<List<VideoDataTableModel>>(true);
            try
            {

                using (var repository = new Repository())
                {
                    result.Data = repository.VideoRepository.SearchVideos(searchModel.Name, searchModel.Director, searchModel.Genre, searchModel.Year).Select(v => new VideoDataTableModel(v)).OrderBy(v=>v.IsRented).ThenByDescending(v=>v.Year).ToList();
                }

            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Message = "unexepcted Error";
            }

            return result;
        }