using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Linq;
using System.Text;
using JLHHJSvr.BLL;
using JLHHJSvr.Com;
using JLHHJSvr.Com.Model;
using JLHHJSvr.DBA.DBModle;
using JLHHJSvr.LJException;
using LJLib.DAL.SQL;
using LJLib.Net.SPI.Server;
using LJLib.SQLEX;
using LJLib.Tools.DEncrypt;
using LJLib.Tools.Encry;

namespace JLHHJSvr.Excutor
{
    internal sealed class LoginExcutor : ExcutorBase<LoginRequest, LoginResponse>
    {
        protected override void ExcuteInternal(LoginRequest request, object state, LoginResponse rslt)
        {
            if (string.IsNullOrEmpty(request.usercode))
            {
                rslt.ErrMsg = "用户名不能为空";
                return;
            }

            var remoteIP = string.Empty;
            var remoteInfo = state as IRemoteInfoContainer;
            var remoteEndPoint = remoteInfo?.RemoteInfo;
            if (!string.IsNullOrEmpty(remoteEndPoint))
            {
                var pos = remoteEndPoint.LastIndexOf(":");
                remoteIP = pos > 0 ? remoteEndPoint.Substring(0, pos).Trim() : remoteEndPoint;
            }


            //if (string.IsNullOrEmpty(request.psw))
            //{
            //    rslt.ErrMsg = "密码不能为空";
            //}

            u_user_jlhprice stUser = new u_user_jlhprice();
            rslt.rsltFunids = new List<int>();
            using (var con = GlobalVar.ConnectionString.NewSqlConnection())
            using (var cmd = con.CreateCommand())
            {
                con.Open();
                
                try
                {
                    if (DbSqlHelper.SelectOne(cmd, "u_user_jlhprice", "userid = @usercode",
                    new Dictionary<string, object>() { { "@usercode", request.usercode } }, stUser,
                    "userid, empid, username, usermode, psw, access_failed_count, last_failed_attempt_time,whiteIPs") != 1)
                    {
                        rslt.ErrMsg = "用户名不存在或密码错误";
                        return;
                    }

                    // 判断是否lock
                    if (stUser.isLocked)
                    {
                        throw new LJCommonException("登录连续错误5次，账号已锁定，请联系管理员解锁!");
                    }

                    if (!string.IsNullOrEmpty(stUser.whiteIPs) && !string.IsNullOrEmpty(remoteIP))
                    {
                        var ipSet = new HashSet<string>(stUser.whiteIPs.Split(',', '，'), StringComparer.OrdinalIgnoreCase);
                        if (!ipSet.Contains(remoteIP))
                        {
                            Trace.Write($"{request.usercode}当前使用的IP[{remoteIP}]不在白名单里,不允许登录");
                            throw new LJCommonException($"{request.usercode}当前使用的IP不在白名单里,不允许登录");
                        }
                    }

                    psw_bczh3 pswhelper = new psw_bczh3();
                    if (pswhelper.GetEntrypt(request.psw, 0, "123457851239866") != stUser.psw)
                    {
                        using (cmd.Transaction = con.BeginTransaction())
                        {
                            try
                            {
                                cmd.CommandText = @"UPDATE u_user_jlhprice SET access_failed_count = CASE 
                                                    WHEN last_failed_attempt_time < @failedDate THEN 1 
                                                    ELSE access_failed_count + 1 
                                                 END,
                                                 last_failed_attempt_time = GETUTCDATE()
                                                WHERE u_user_jlhprice.empid = @empid";
                                cmd.Parameters.Clear();
                                cmd.Parameters.AddWithValue("@failedDate", DateTime.UtcNow.AddMonths(-1));
                                cmd.Parameters.AddWithValue("@empid", stUser.empid);
                                cmd.ExecuteNonQuery();

                                cmd.Transaction.Commit();
                            }
                            catch (Exception e)
                            {
                                cmd.Transaction.Rollback();
                            }
                        }
                        
                        throw new LJCommonException($"密码错误，剩余尝试次数：{5 - stUser.access_failed_count + 1} 次（共 5 次）");
                    }

                    string token = Guid.NewGuid().ToString();
                    rslt.token = token;
                    rslt.username = stUser.username;
                    rslt.usercode = stUser.userid;
                    rslt.empid = stUser.empid;
                    rslt.usermode = stUser.usermode;
                    rslt.rsltFunids = UserHelper.FilterMyFunids(cmd, stUser.empid);
                    var tokenData = new TokenData
                    {
                        empid = stUser.empid,
                        usercode = stUser.userid,
                        userid = stUser.empid,
                        username = stUser.username,
                        usermode = stUser.usermode
                    };
                    BllHelper.SetToken(token, tokenData);

                    // 登录成功，清除错误次数
                    using (cmd.Transaction = con.BeginTransaction())
                    {
                        try
                        {
                            UserHelper.UnLock(cmd, new List<int>() { stUser.empid });
                            cmd.Transaction.Commit();
                        }
                        catch (Exception e)
                        {
                            cmd.Transaction.Rollback();
                        }
                    }
                }
                catch(LJCommonException ex)
                {
                    rslt.ErrMsg = ex.Message;
                }
            }
        }
    }
}