using System;
using System.Data;
using System.Web;
using System.Web.Security;

namespace ynhtm.BLL
{
    using DBUtility;

    /// <summary>
    /// 用户操作。
    /// </summary>
    public class User
    {
        public const string SQL_ORDER = "ORDER BY " + DAL.User.USERID + " DESC";

        /// <summary>
        /// 插入用户实例到数据库。
        /// </summary>
        /// <param name="item">用户实例。</param>
        public void Insert(Model.User item)
        {
            DAL.User.Insert(item);
            using (var db = DbBase.GetDb())
                db.ExecuteNonQuery("UPDATE " + DAL.Setting.SQL_TABLE + " SET " + DAL.Setting.USERCOUNT + " = " + DAL.Setting.USERCOUNT + " + 1");
        }

        #region UserID

        /// <summary>
        /// 根据用户编号取得用户实例。
        /// </summary>
        /// <param name="userID">用户编号。</param>
        /// <returns>返回用户实例，没有将返回 null 。</returns>
        public Model.User GetByUserID(int userID)
        {
            return DAL.User.GetByUserID(userID);
        }

        /// <summary>
        /// 更新用户。
        /// </summary>
        /// <param name="item">用户实例。</param>
        /// <returns>返回受到影响的行数。</returns>
        public int Update(Model.User item)
        {
            return DAL.User.Update(item);
        }

        /// <summary>
        /// 删除用户。
        /// </summary>
        /// <param name="userID">用户编号。</param>
        /// <returns>返回受到影响的行数。</returns>
        public int Delete(int userID)
        {
            using (var db = DbBase.GetDb())
                db.ExecuteNonQuery("UPDATE " + DAL.Setting.SQL_TABLE + " SET " + DAL.Setting.USERCOUNT + " = " + DAL.Setting.USERCOUNT + " - 1");
            return DAL.User.Delete(userID);
        }

        #endregion

        #region UserName

        /// <summary>
        /// 根据用户名取得用户实例。
        /// </summary>
        /// <param name="userName">用户名。</param>
        /// <returns>返回用户实例，没有将返回 null 。</returns>
        public Model.User GetByUserName(string userName)
        {
            return DAL.User.GetByUserName(userName);
        }

        #endregion

        #region OAuthQzoneID

        /// <summary>
        /// 根据 OAuthQzoneID 取得用户实例。
        /// </summary>
        /// <param name="qzoneID">qzoneID 值。</param>
        /// <returns>返回用户实例，没有将返回 null 。</returns>
        public Model.User GetByOAuthQzoneID(string qzoneID)
        {
            using (var db = DbBase.GetDb())
            {
                using (var reader = db.ExecuteReader(DAL.User.SQL_SELECT + " WHERE " + DAL.User.OAUTHQZONEID + " = @" + DAL.User.OAUTHQZONEID, db.CreateParameter(DAL.User.OAUTHQZONEID, qzoneID)))
                {
                    if (!reader.Read()) return null;
                    var result = new Model.User();
                    DAL.User.FillItem(reader, result);
                    return result;
                }
            }
        }

        #endregion

        /// <summary>
        /// 取得用户分页集合。
        /// </summary>
        /// <param name="recordCount">记录总数。</param>
        /// <param name="pageSize">分页大小。</param>
        /// <param name="pageIndex">要返回的页数。</param>
        /// <param name="query">查询条件。</param>
        /// <param name="order">排序方式。</param>
        /// <returns>返回分页数据。</returns>
        public DataTable GetList(ref int recordCount, int pageSize, int pageIndex, IQuery query = null, string order = SQL_ORDER)
        {
            using (var db = DbBase.GetDb())
                return db.GetPage(ref recordCount, DAL.User.SQL_TABLE, order, pageSize, pageIndex, query, DAL.User.SQL_FIELD);
        }

        /// <summary>
        /// 检测用户名是否存在。
        /// </summary>
        /// <param name="userName">要检测的用户名。</param>
        /// <returns>返回 System.Boolean，如果用户存在则返回 true。</returns>
        public bool IsExistUserName(string userName)
        {
            using (var db = DbBase.GetDb())
                return Convert.ToInt32(db.ExecuteScalar("SELECT COUNT(0) FROM " + DAL.User.SQL_TABLE + " WHERE " + DAL.User.USERNAME + " = @" + DAL.User.USERNAME, db.CreateParameter(DAL.User.USERNAME, userName.Trim()))) > 0;
        }

        /// <summary>
        /// 切换用户锁定状态。
        /// </summary>
        /// <param name="userID">用户编号。</param>
        /// <returns>返回受到影响的行数。</returns>
        public int LockToggle(int userID)
        {
            using (var db = DbBase.GetDb())
                return db.ExecuteNonQuery("UPDATE " + DAL.User.SQL_TABLE + " SET " + DAL.User.ISLOCK + " = ABS(" + DAL.User.ISLOCK + " - 1) WHERE " + DAL.User.USERID + " = @" + DAL.User.USERID, db.CreateParameter(DAL.User.USERID, userID));
        }

        /// <summary>
        /// 根据用户名和密码取得用户实例。
        /// </summary>
        /// <param name="userName">用户名。</param>
        /// <param name="passWord">密码。</param>
        /// <returns>返回用户实例，没有将返回 null 。</returns>
        public Model.User GetByUserNameAndPassWord(string userName, string passWord)
        {
            using (var db = DbBase.GetDb())
            {
                using (var reader = db.ExecuteReader(DAL.User.SQL_SELECT + " WHERE " + DAL.User.USERNAME + " = @" + DAL.User.USERNAME + " AND " + DAL.User.PASSWORD + " = @" + DAL.User.PASSWORD, db.CreateParameter(DAL.User.USERNAME, userName), db.CreateParameter(DAL.User.PASSWORD, passWord)))
                {
                    if (!reader.Read()) return null;
                    var result = new Model.User();
                    DAL.User.FillItem(reader, result);
                    return result;
                }
            }
        }

        /// <summary>
        /// 登录用户并将用户信息存储到身份验证中。
        /// </summary>
        /// <param name="item">用户实例。</param>
        /// <param name="request">客户端 Web 请求。</param>
        /// <param name="response">客户端 HTTP 响应的信息。</param>
        /// <returns>返回受到影响的行数。</returns>
        public int Login(Model.User item, HttpRequest request, HttpResponse response)
        {
            var roles = "";
            if (item.IsAdmin) roles += ",Admin";
            var cookie = FormsAuthentication.GetAuthCookie(item.UserName, false);
            cookie.Value = FormsAuthentication.Encrypt(new FormsAuthenticationTicket(1, item.UserName, DateTime.Now, DateTime.Now.AddHours(24), false, roles.Trim(',')));
            response.AppendCookie(cookie);
            using (var db = DbBase.GetDb())
                return db.ExecuteNonQuery("UPDATE " + DAL.User.SQL_TABLE + " SET " + DAL.User.LOGINCOUNT + " = " + DAL.User.LOGINCOUNT + " + 1, " + DAL.User.LASTIP + " = @" + DAL.User.LASTIP + ", " + DAL.User.LASTDATE + " = " + db.Now + " WHERE " + DAL.User.USERID + " = @" + DAL.User.USERID, db.CreateParameter(DAL.User.USERID, item.UserID), db.CreateParameter(DAL.User.LASTIP, request.UserHostAddress));
        }

        /// <summary>
        /// 统计用户数据。
        /// </summary>
        /// <returns>返回受到影响的行数。</returns>
        public int Sumup()
        {
            using (var db = DbBase.GetDb())
                return db.ExecuteNonQuery("UPDATE " + DAL.User.SQL_TABLE + " SET " + DAL.User.POSTCOUNT + " = (SELECT COUNT(0) FROM " + DAL.Post.SQL_TABLE + " WHERE " + DAL.Post.USERID + " = " + DAL.User.SQL_TABLE + "." + DAL.User.USERID + "), " + DAL.User.COMMENTCOUNT + " = (SELECT COUNT(0) FROM " + DAL.Comment.SQL_TABLE + " WHERE " + DAL.Comment.USERID + " = " + DAL.User.SQL_TABLE + "." + DAL.User.USERID + ")");
        }
    }
}