using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using Domain;
using Service;
using WebSite.Models;
using System.Web.Caching;

namespace WebSite.Controllers
{
    [HandleError]
    public class HomeController : BaseController
    {
        private static log4net.ILog logger = log4net.LogManager.GetLogger(typeof(HomeController));

        private const int AuthorityID = 1001;

        public ISysUserManager SysUserManager { get; set; }
        public ISysAuthorityManager SysAuthorityManager { get; set; }
        public IHostManager HostManager { get; set; }
        public IGroupManager GroupManager { get; set; }
        public ISysActiveUserManager SysActiveUserManager { get; set; }
        public ISysSettingManager SysSettingManager { get; set; }
        public ISysRoleManager SysRoleManager { get; set; }
        public ISysHotelManager SysHotelManager { get; set; }
        public ISysHotelGroupManager SysHotelGroupManager { get; set; }

        #region Action

        [Authorize]
        public ActionResult Index()
        {
            //ViewData["Account"] = User.Identity.Name;
            return View("SimonIndex");
        }

        [Authorize]
        public ActionResult MenuIndex()
        {
            //ViewData["Account"] = User.Identity.Name;
            return View("SimonIndex");
        }

        private static IList<Menu> GetSubMenu(IList<SysAuthority> roleAuthority, int parentID)
        {
            IList<Menu> subMenu = new List<Menu>();
            IList<SysAuthority> Authories = roleAuthority.Where(r => r.ParentID == parentID).ToList();
            for (int i = 0; i < Authories.Count; i++)
            {
                subMenu.Add(new Menu
                {
                    Name = Authories[i].Name,
                    Url = HttpUtility.UrlEncode(Authories[i].Url),
                    Icon = Authories[i].Icon
                });
            }
            return subMenu;
        }

        private void ResultMenu()
        {
            IList<SysAuthority> roleAuthority = new List<SysAuthority>();
            SysUsers user = SysUserManager.LoadAll().FirstOrDefault(r => r.Account == this.User.Identity.Name);
            if (this.User.Identity.Name != "admin" && user.Role.Name != "超级管理员")
            {
                roleAuthority = SysRoleManager.GetAuthorities(user.Role);
            }
            else
            {
                roleAuthority = SysAuthorityManager.LoadAll().Where(r => r.ParentID != 0 && r.IsMenu && r.ActiveIndicator).OrderBy(o => o.Sort).ToList();
            }
            //客房管理
            ViewData["RoomManager"] = GetSubMenu(roleAuthority, 1);
            //参数设置
            ViewData["Setting"] = GetSubMenu(roleAuthority, 2);
            //设备管理
            ViewData["DeviceManager"] = GetSubMenu(roleAuthority, 3);
            //查询统计
            ViewData["QueryStatistics"] = GetSubMenu(roleAuthority, 4);
            //系统管理
            ViewData["SysMaintenance"] = GetSubMenu(roleAuthority, 5);
        }

        public ActionResult MenuMain()
        {
            ViewData["Account"] = this.User.Identity.Name;
            ResultMenu();
            return View("MenuMain");
        }
        /// <summary>
        ///选中语言触发事件引用方法
        /// </summary>
        /// <param name="language"></param>
        /// <returns></returns>
        public ActionResult ChangeLanguage(string language)
        {
            switch (language.ToLower())
            {
                case "en":
                    Session["isCN"] = 1;
                    break;
                case "zh-tw":
                    Session["isCN"] = 2;
                    break;
                default:
                    Session["isCN"] = 0;
                    break;
            }
            return Redirect("/");//Request.UrlReferrer.ToString());
        }

        public ActionResult LogOn()
        {
            string result = "";
            //这个是公网没有必要再验证证书了
            //if (!Common.MyDes.Validate(ref result))
            //{
            //    ViewData["Msg"] = result;
            //    return View("License");
            //}
            if (Request.Cookies["Account"] != null)
            {
                ViewData["Account"] = HttpUtility.UrlDecode(Request.Cookies["Account"].Value);
                ViewData["RememberMe"] = true;
            }
            else
            {
                ViewData["Account"] = "";
                ViewData["RememberMe"] = false;
            }
            ViewData["Language"] = Language;
            return View("SimonLogOn");
        }

        [HttpGet]
        public ActionResult ActiveUsersView()
        {
            return View();
        }
        /// <summary>
        /// 在线用户
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActionResult ActiveUsers()
        {
            var activeUsers = GetActiveUsers();
            var footer = new List<object>();
            footer.Add(new { Account = "在线人数", LoginIP = activeUsers.Count });
            footer.Add(new { Account = "用户总数", LoginIP = SysUserManager.GetCount() });
            return Json(new { total = activeUsers.Count, rows = activeUsers, footer = footer }, JsonRequestBehavior.AllowGet);
        }

        public ActionResult LogOut()
        {
            Session.Clear();
            //var activeUsers = GetActiveUsers();
            //var activeUser = activeUsers.FirstOrDefault(r => r.ID == Session.SessionID);
            //if (activeUser != null)
            //{
            //    activeUsers.Remove(activeUser);
            //}
            FormsAuthentication.SignOut();
            return Redirect("/LogOn/");
        }

        public ActionResult LogOnByAndPassword(string account, string password, string code, bool rememberMe)
        {
            if (this.Session["ValidateCode"] == null || code != this.Session["ValidateCode"].ToString())
            {
                return Json(new { IsSuccess = false, Message = HttpContext.InnerLanguage("VerificationCodeErrorPleaseReEenter") });
            }
            var entity = SysUserManager.Get(account, password);
            if (entity == null)
            {
                return Json(new { IsSuccess = false, Message = HttpContext.InnerLanguage("UsernameOrPasswordWrong") });
            }
            if (!entity.ActiveIndicator)
            {
                return Json(new { IsSuccess = false, Message = HttpContext.InnerLanguage("YourAccountHasBeenDisabledPleaseContactTheAdministrator") });
            }
            if (account.ToLower() != "admin")
            {
                if (entity.Hotels.Count == 0)
                {
                    return Json(new { IsSuccess = false, Message = HttpContext.InnerLanguage("UserNotSetHotel") });
                }
                if (DateTime.Now > entity.Hotels[0].ValidateDate)
                {
                    return Json(new { IsSuccess = false, Message = HttpContext.InnerLanguage("CurrentHotelExpire") });
                }
            }
            entity.LoginIP = GetClientIP();
            SysUserManager.Update(entity);

            if (rememberMe)
            {
                HttpCookie accountCookie = new HttpCookie("Account");
                accountCookie.Value = HttpUtility.UrlEncode(entity.Account);
                accountCookie.Expires = DateTime.Now.AddYears(1);
                Response.Cookies.Add(accountCookie);
            }
            else
            {
                Response.Cookies["Account"].Value = "";
            }
            Session["CurrentHotelID"] = 0;
            FormsAuthentication.SetAuthCookie(entity.Account, false);//保存当前用户

            Session["Account"] = entity.Account;
            //var activeUsers = GetActiveUsers();
            //if (activeUsers.FirstOrDefault(r => r.ID == Session.SessionID) == null)
            //{
            //    activeUsers.Add(new ActiveUserModel { ID = Session.SessionID, Account = entity.Account, LoginIP = entity.LoginIP });
            //}
            //SaveSystemLog(AuthorityID, HttpContext.InnerLanguage("Login"), account);

            return Json(new { IsSuccess = true, Message = HttpContext.InnerLanguage("LoginSuccessful") });
        }

        //public ActionResult LoginInfo()
        //{
        //    SysUsers user = SysUserManager.Get(User.Identity.Name);
        //    if (null == user || user.Hotels.Count == 0)
        //    {
        //        return LogOut();
        //    }
        //    if (User.Identity.Name.ToLower() == "admin")
        //    {
        //        user.Hotels = SysHotelManager.LoadAll();
        //    }
        //    var curHotel = user.Hotels[0].Code + "-" + ReturnNameByLanguage(user.Hotels[0].Name, user.Hotels[0].EName, user.Hotels[0].TWName);//SysHotelGroupManager.BuildGroupName(user.Hotels[0].SysHotelGroup) + 
        //    foreach (SysHotel hotel in user.Hotels)
        //    {
        //        if (hotel.ID == CurrentHotelID)
        //        {
        //            curHotel = hotel.Code + "-" + ReturnNameByLanguage(hotel.Name, hotel.EName, hotel.TWName);//SysHotelGroupManager.BuildGroupName(hotel.SysHotelGroup) + 
        //            break;
        //        }
        //    }
        //    return Json(new { IsSuccess = true, User = new { Account = user.Account, Hotel = curHotel } }, JsonRequestBehavior.AllowGet);//Role = user.Role.Name, 
        //}
        /// <summary>
        /// 获取有权限菜单和酒店
        /// </summary>
        /// <returns></returns>
        [Authorize]
        public ActionResult LoadMenu()
        {
            try
            {
                IList<SysAuthority> authorities = new List<SysAuthority>();//用户所拥有权限
                SysHotel hotel = new SysHotel();
                switch (User.Identity.Name.ToLower())
                {
                    case "admin":
                    case "leo":
                    case "blw":
                        authorities = SysAuthorityManager.LoadAll().Where(r => r.IsMenu && r.ActiveIndicator).ToList();
                        hotel = SysHotelManager.LoadAll().OrderBy(o => o.Sort).FirstOrDefault();
                        break;
                    default:
                        SysUsers user = this.SysUserManager.Get(User.Identity.Name);
                        hotel = user.Hotels.OrderBy(o => o.Sort).FirstOrDefault();
                        IList<SysAuthority> firstMenus = SysAuthorityManager.LoadAll().Where(r => r.ParentID == 1000).ToList();//获取后台一级菜单
                        foreach (var authority in user.Role.Authorities)
                        {
                            if (!authorities.Contains(authority))
                            {
                                authorities.Add(authority);
                                var firstMenu = firstMenus.Where(r => r.ID == authority.ParentID).FirstOrDefault();//判断其上级菜单是否存在，如果不存在，则添加进来
                                if (firstMenu != null)// && !authorities.Contains(firstMenu) && !user.Role.Authorities.Contains(firstMenu))
                                {
                                    bool isExit = false;
                                    foreach (var exitAuthority in authorities)
                                    {
                                        if (exitAuthority.ID == firstMenu.ID)
                                        {
                                            isExit = true;
                                            break;
                                        }
                                    }
                                    if (!isExit)
                                    {
                                        authorities.Add(firstMenu);
                                    }
                                }
                            }
                        }
                        break;
                }
                IList<object> menuTree = BuildMenu(authorities, 1000);//获取后台菜单权限
                if (CurrentHotelID == 0)
                {
                    CurrentHotelID = hotel.ID;//缓存当前酒店ID
                    CurrentHotelCode = hotel.Code;
                    CurrentHotelName = hotel.Code + "-" + ReturnNameByLanguage(hotel.Name, hotel.EName, hotel.TWName);
                    CurrentLogoPath = hotel.LogoPath;
                    CurrentHotelIsExpire = DateTime.Now.AddMonths(1) > hotel.ValidateDate ? true : false;
                }
                return Json(new { MenuData = menuTree, HotelName = CurrentHotelName, LogoPath = CurrentLogoPath, IsExpire = CurrentHotelIsExpire });
            }
            catch (Exception ex)
            {
                logger.Error(ex.ToString());
                return Json(ex.Message);
            }
        }
        /// <summary>
        /// 缓存当前酒店ID
        /// </summary>
        /// <param name="hotelID"></param>
        /// <returns></returns>
        [Authorize]
        public ActionResult GetCurrentHotel(string query, int? groupId)
        {
            string key = "GetCurrentHotel_" + query + "_" + groupId.ToString();
            object data = HttpContext.Cache.Get(key);
            if (data != null)
            {
                return Json(new { total = 3000, rows = data }, JsonRequestBehavior.AllowGet);
            }
            else
            {
                IList<SysHotel> hotels = new List<SysHotel>();
                switch (User.Identity.Name.ToLower())
                {
                    case "admin":
                    case "leo":
                    case "blw":
                        hotels = SysHotelManager.LoadAll().Where(r => !r.IsDeleted).ToList();
                        break;
                    default:
                        hotels = SysHotelManager.LoadAll().Where(r => r.IsApprove && !r.IsDeleted).ToList();//装载已审核的酒店
                        break;
                }
                if (groupId.HasValue && groupId != 1)//过滤分组
                {
                    hotels = hotels.Where(r => r.SysHotelGroup.ID == groupId ||
                        (r.SysHotelGroup.Parent != null && r.SysHotelGroup.Parent.ID == groupId) ||
                        (r.SysHotelGroup.Parent != null && r.SysHotelGroup.Parent.Parent != null && r.SysHotelGroup.Parent.Parent.ID == groupId)).ToList();
                }
                if (!string.IsNullOrEmpty(query))
                {
                    hotels = hotels.Where(r => r.Code.Contains(query) || r.Name.Contains(query)).ToList();
                }
                hotels = hotels.OrderByDescending(o => o.ID).ThenBy(o => o.SysHotelGroup.Sort).ToList();
                var hotelData = hotels.Select(r => new
                {
                    r.ID,
                    r.Code,
                    GroupName = SysHotelGroupManager.BuildGroupName(r.SysHotelGroup),
                    Name = ReturnNameByLanguage(r.Name, r.EName, r.TWName)
                }).ToList();

                HttpContext.Cache.Add(key, hotelData, null, DateTime.Now.AddMinutes(10), Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
                return Json(new { total = hotels.Count, rows = hotelData }, JsonRequestBehavior.AllowGet);
            }

        }
        /// <summary>
        /// 缓存当前酒店ID
        /// </summary>
        /// <param name="hotelID"></param>
        /// <returns></returns>
        [Authorize]
        public ActionResult SetCurrentHotel(int hotelID)
        {
            CurrentHotelID = hotelID;//缓存当前酒店ID
            var curHotel = SysHotelManager.Get(hotelID);
            CurrentHotelName = curHotel.Code + "-" + ReturnNameByLanguage(curHotel.Name, curHotel.EName, curHotel.TWName);
            CurrentLogoPath = curHotel.LogoPath;
            CurrentHotelIsExpire = DateTime.Now.AddMonths(1) > curHotel.ValidateDate ? true : false;
            return Json(new { IsSuccess = true }, JsonRequestBehavior.AllowGet);
        }

        [Authorize]
        public ActionResult ChangedPassword(string password, string oldPassword)
        {
            SysUsers userEntity = this.SysUserManager.Get(this.User.Identity.Name, oldPassword);
            if (userEntity == null)
            {
                return Json(new { IsSuccess = false, Message = HttpContext.InnerLanguage("OldPasswordIsIncorrectPleaseReEnter") }, "text/x-json", JsonRequestBehavior.AllowGet);
            }
            this.SysUserManager.Update(userEntity, password);
            SaveSystemLog(AuthorityID, HttpContext.InnerLanguage("ChangePassword"), userEntity.Account);
            return Json(new { IsSuccess = true, Message = HttpContext.InnerLanguage("PasswordChangeSuccessful") }, "text/x-json", JsonRequestBehavior.AllowGet);
        }

        public ActionResult ValidateCode()
        {
            var code = Common.Tools.CreateValidateNumber(4);
            this.Session["ValidateCode"] = code;
            return File(Common.Tools.CreateValidateGraphic(code), "image/jpeg");
        }

        public ActionResult GetMachineCode()
        {
            var code = Common.Tools.GetMachineCode();
            return Json(new { IsSuccess = true, Message = code });
        }

        /// <summary>
        /// 导入授权文件
        /// </summary>
        /// <returns></returns>
        public ActionResult UploadLicense()
        {
            try
            {
                HttpFileCollection hfc = System.Web.HttpContext.Current.Request.Files;

                if (hfc.Count < 1 || hfc[0].ContentLength <= 0 || String.IsNullOrEmpty(hfc[0].FileName))
                {
                    return Json(new { IsSuccess = false, Message = HttpContext.InnerLanguage("PleaseSelectAuthorizationFile") });
                }

                string file = Common.MyDes.GetLicensePath();
                string path = Path.GetDirectoryName(file);
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }

                hfc[0].SaveAs(file);

                string result = "";
                if (!Common.MyDes.ImportValidate(hfc[0].InputStream, ref result))
                {
                    System.IO.File.Delete(file);
                    return Json(new { IsSuccess = false, Message = result });
                }

                return Json(new { IsSuccess = true });
            }
            catch (Exception ex)
            {
                if (logger.IsErrorEnabled)
                {
                    logger.Error(ex);
                }

                return Json(new { IsSuccess = false, Message = ex.Message });
            }
        }

        public ActionResult ProductInfo()
        {
            string version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
            version = version.Substring(0, version.LastIndexOf("."));
            Common.License license = Common.MyDes.GetLicense();
            SysHotel hotel = SysHotelManager.Get(CurrentHotelID);

            string expires = hotel.ValidateDate.ToString("yyyy.MM.dd"); //license.EndDate.ToString("yyyy.MM.dd");
            if (hotel.ValidateDate >= new DateTime(2037, 12, 31))//license.EndDate
            {
                expires = HttpContext.InnerLanguage("UnlimitedDuration");
            }
            else if (DateTime.Now.AddMonths(1) > hotel.ValidateDate)
            {
                expires = string.Format("<font style='color:red'>{0}</font>", expires);
            }
            var result = new
            {
                Version = version,
                SerialNumber = license.SN,
                Limit = license.Limit,
                Expires = expires,
                CurrentHotel = ReturnNameByLanguage(hotel.Name, hotel.EName, hotel.TWName)
            };
            return Json(new { IsSuccess = true, Data = result });
        }

        public ActionResult SaveSystemConfig(string jsonData)
        {
            try
            {
                var sysConfig = Newtonsoft.Json.JsonConvert.DeserializeObject<SystemConfigModel>(jsonData);

                var sysSetting = SysSettingManager.Get("MessageIP");
                if (sysSetting != null)
                {
                    sysSetting.Value = sysConfig.MessageIP;
                    SysSettingManager.Update(sysSetting);
                }

                sysSetting = SysSettingManager.Get("MessagePort");
                if (sysSetting != null)
                {
                    sysSetting.Value = sysConfig.MessagePort.ToString();
                    SysSettingManager.Update(sysSetting);
                }


                return Json(new { IsSuccess = true, Message = "保存成功。" });
            }
            catch (Exception ex)
            {
                return Json(new { IsSuccess = false, Message = ex.Message });
            }
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// 构造菜单用于easyui-tree
        /// </summary>
        /// <param name="role"></param>
        /// <param name="parentId"></param>
        /// <returns></returns>
        private IList<object> BuildMenuForEasyUITree(IList<SysAuthority> authorities, int parentId)
        {
            IList<object> menuTree = new List<object>();
            IList<SysAuthority> subAuthorities = authorities.Where(r => r.ParentID == parentId).OrderBy(o => o.Sort).ToList();
            foreach (SysAuthority authority in subAuthorities)
            {
                IList<object> children = BuildMenuForEasyUITree(authorities, authority.ID);
                if (authority.ActiveIndicator && authority.IsMenu)
                {
                    if (children.Count != 0)
                    {
                        menuTree.Add(new { text = authority.Name, iconCls = authority.Icon, url = authority.Url, children = children });
                    }
                    else
                    {
                        menuTree.Add(new { text = authority.Name, iconCls = authority.Icon, url = authority.Url });
                    }
                }
            }
            return menuTree;
        }

        /// <summary>
        /// 构造菜单
        /// </summary>
        /// <param name="role"></param>
        /// <param name="parentId"></param>
        /// <returns></returns>
        private IList<object> BuildMenu(IList<SysAuthority> authorities, int parentId)
        {
            IList<object> menuTree = new List<object>();
            IList<SysAuthority> subAuthorities = authorities.Where(r => r.ParentID == parentId).OrderBy(o => o.Sort).ToList();
            foreach (SysAuthority authority in subAuthorities)
            {
                IList<object> children = BuildMenu(authorities, authority.ID);
                if (authority.ActiveIndicator && authority.IsMenu)
                {
                    if (children.Count != 0)
                    {
                        menuTree.Add(new { Name = ReturnNameByLanguage(authority.Name, authority.EName, authority.TWName), Icon = authority.Icon, Url = authority.Url, Items = children });
                    }
                    else
                    {
                        menuTree.Add(new { Name = ReturnNameByLanguage(authority.Name, authority.EName, authority.TWName), Icon = authority.Icon, Url = authority.Url });
                    }
                }
            }
            return menuTree;
        }

        private IList<ActiveUserModel> GetActiveUsers()
        {
            var activeUsers = HttpContext.Application["ActiveUsers"] as List<ActiveUserModel>;
            if (activeUsers == null)
            {
                activeUsers = new List<ActiveUserModel>();
                HttpContext.Application.Lock();
                HttpContext.Application["ActiveUsers"] = activeUsers;
                HttpContext.Application.UnLock();
            }
            return activeUsers;
        }
        #endregion
    }
    /// <summary>
    /// 菜单类
    /// </summary>
    public class Menu
    {
        public string Url { get; set; }
        public string Name { get; set; }
        public string Icon { get; set; }
    }
}
