using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Data;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Dynamic;
using Common;
using Service;

namespace WebSite.Controllers
{
    public class Oauth2Controller : BaseController
    {
        private static log4net.ILog logger = log4net.LogManager.GetLogger(typeof(Oauth2Controller));
        private static string _clientID = System.Configuration.ConfigurationManager.AppSettings["rokid_client_id"];
        private static string _clientSecret = System.Configuration.ConfigurationManager.AppSettings["rokid_client_secret"];
        private static int _expiresIn = 180000;//50个小时

        public ISysUserManager SysUserManager { get; set; }
        public ISysOauth2Manager SysOauth2Manager { get; set; }

        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Authorize()
        {
            logger.Error("收到调用Authorize方法Url：" + Request.Url);
            try
            {
                if (Request.QueryString["response_type"] != "code")//固定code
                {
                    return returnResult("response_type验证失败");
                }
                string client_id = Request.QueryString["client_id"];//若琪所使用的标识
                string redirect_uri = Request.QueryString["redirect_uri"];//回调地址
                string state = Request.QueryString["state"];//用来保持授权请求和授权回调状态的值，当授权完成后需要将这个参数附加在回调里。
                //string scope = Request.QueryString["scope"];//授权的范围
                if (client_id != _clientID)
                {
                    logger.Error("client_id验证失败:" + client_id);
                    return returnResult("client_id验证失败");
                }
                if (string.IsNullOrEmpty(redirect_uri))
                {
                    logger.Error("redirect_uri无效:" + redirect_uri);
                    return returnResult("redirect_uri无效");
                }
                if (redirect_uri.IndexOf("lzos.lunzn.com") > -1)//岚正播放盒免登录授权
                {
                    string code = "1001BLW" + redirect_uri.Substring(redirect_uri.LastIndexOf("/") + 1);
                    var sysOahth2 = SysOauth2Manager.Get(code);
                    if (null == sysOahth2)
                    {
                        SysOauth2Manager.Save(new Domain.SysOauth2() { Code = code, RedirectUri = redirect_uri, ExpiresIn = _expiresIn, CreatedDate = DateTime.Now, Account = "system" });
                    }
                    return Redirect(redirect_uri + "?code=" + code + "&state=" + state);
                }
                else
                {
                    ViewData["client_id"] = client_id;
                    ViewData["redirect_uri"] = redirect_uri;
                    ViewData["state"] = state;
                    return View();
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
                return returnResult("授权失败：" + ex.Message);
            }
        }

        public ActionResult LoginOn(string jsonData)
        {
            try
            {
                JObject jData = (JObject)JsonConvert.DeserializeObject(jsonData);
                string account = jData["account"].ToString();
                string password = jData["password"].ToString();
                string redirect_uri = jData["redirect_uri"].ToString();
                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") });
                }
                string code = entity.Hotels[0].Code + "BLW" + redirect_uri.Substring(redirect_uri.LastIndexOf("/") + 1);
                var sysOauth2 = SysOauth2Manager.Get(code);
                if (null == sysOauth2)
                {
                    SysOauth2Manager.Save(new Domain.SysOauth2() { Code = code, RedirectUri = redirect_uri, ExpiresIn = _expiresIn, CreatedDate = DateTime.Now, Account = account });
                }
                redirect_uri = System.Web.HttpUtility.UrlDecode(redirect_uri, System.Text.Encoding.UTF8) + "?code=" + code + "&state=" + jData["state"].ToString();
                return Json(new { IsSuccess = true, Message = redirect_uri });
            }
            catch (Exception ex)
            {
                logger.Error(ex);
                return returnResult("授权失败：" + ex.Message);
            }
        }

        public ActionResult Token()
        {
            Request.InputStream.Position = 0;
            byte[] reqBody = new byte[Request.InputStream.Length];
            Request.InputStream.Read(reqBody, 0, reqBody.Length);
            string reqData = System.Text.Encoding.UTF8.GetString(reqBody);
            //logger.Error("收到调用Token方法参数值：" + reqData);
            try
            {
                string grant_type = "";//Request.QueryString["grant_type"];//必须，值为 authorization_code，如果是刷新 Token 则为 refresh_token
                string code = "";//Request.QueryString["code"];//如果是通过 authorization_code 获取 access token 则为必须，授权过程中颁发的授权代码
                string client_id = "";//Request.QueryString["client_id"];//必须，若琪所使用的标识
                string client_secret = "";//Request.QueryString["client_secret"];//可选，如果使用 HTTP Basic Auth 则该参数会包含在 HTTP Authorization Header 中
                string refresh_token = "";
                string[] queryStrings = reqData.Split('&');
                foreach (string queryString in queryStrings)
                {
                    string[] querys = queryString.Split('=');
                    switch (querys[0])
                    {
                        case "client_id":
                            client_id = querys[1];
                            break;
                        case "client_secret":
                            client_secret = querys[1];
                            break;
                        case "grant_type":
                            grant_type = querys[1];
                            break;
                        case "code":
                            code = querys[1];
                            break;
                        case "refresh_token":
                            refresh_token = querys[1];
                            break;
                    }
                }
                if (string.IsNullOrEmpty(client_id))//获取岚正播放盒调用参数
                {
                    JObject jData = (JObject)JsonConvert.DeserializeObject(reqData);
                    client_id = jData["client_id"].ToString();
                    client_secret = jData["client_secret"].ToString();
                    grant_type = jData["grant_type"].ToString();
                    code = jData["code"].ToString();
                    refresh_token = jData["refresh_token"] == null ? "" : jData["refresh_token"].ToString();
                }
                if (client_id != _clientID)
                {
                    logger.Error("client_id验证失败:" + client_id);
                    return returnResult("client_id验证失败");
                }
                if (client_secret != _clientSecret)
                {
                    logger.Error("client_secret验证失败:" + client_secret);
                    return returnResult("client_secret验证失败");
                }
                Domain.SysOauth2 sysOauth2 = null;
                switch (grant_type)
                {
                    case "client_credentials"://客户端凭证授权模式
                        code = "1001BLWXiaoDu";//1001BLWXiaoMi
                        sysOauth2 = SysOauth2Manager.Get(code);
                        if (null == sysOauth2)
                        {
                            sysOauth2 = new Domain.SysOauth2()
                            {
                                Code = code,
                                RedirectUri = "",
                                ExpiresIn = _expiresIn,
                                CreatedDate = DateTime.Now,
                                Account = "system",
                                AccessToken = code.Substring(0, code.IndexOf("BLW") + 3) + Guid.NewGuid(),
                                RefreshToken = code.Substring(0, code.IndexOf("BLW") + 3) + Guid.NewGuid()
                            };
                            SysOauth2Manager.Save(sysOauth2);
                        }
                        else
                        {
                            sysOauth2.ExpiresIn = _expiresIn;
                            sysOauth2.CreatedDate = DateTime.Now;
                            SysOauth2Manager.Update(sysOauth2);//更新保存token
                        }
                        return Json(sysOauth2.AccessToken, JsonRequestBehavior.AllowGet);
                    case "refresh_token":
                        sysOauth2 = SysOauth2Manager.GetByRefreshToken(refresh_token);
                        break;
                    default:
                        sysOauth2 = SysOauth2Manager.Get(code);
                        sysOauth2.AccessToken = sysOauth2.Code.Substring(0, sysOauth2.Code.IndexOf("BLW") + 3) + Guid.NewGuid();//获取新的token
                        sysOauth2.RefreshToken = sysOauth2.Code.Substring(0, sysOauth2.Code.IndexOf("BLW") + 3) + Guid.NewGuid();//获取新的token
                        break;
                }
                if (null == sysOauth2)
                {
                    logger.Error(string.Format("code或refresh_token验证失败,code:{0},refresh_token:{1}, 收到调用参数:{2}, 来自:{3}", code, refresh_token, reqData, Tools.GetClientIP()));
                    return returnResult("code或refresh_token验证失败");
                }
                sysOauth2.ExpiresIn = _expiresIn;
                sysOauth2.CreatedDate = DateTime.Now;
                SysOauth2Manager.Update(sysOauth2);//更新保存token
                AuthorizeResult result = new AuthorizeResult
                {
                    access_token = sysOauth2.AccessToken,
                    expires_in = sysOauth2.ExpiresIn,
                    refresh_token = sysOauth2.RefreshToken,
                    example_parameter = "example_value"
                };
                return Json(result, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                logger.Error(ex);
                return returnResult("授权失败：" + ex.Message);
            }
        }

        private ActionResult returnResult(string message)
        {
            return Json(new { IsSuccess = false, Message = message }, JsonRequestBehavior.AllowGet);
        }
    }

    public class AuthorizeResult
    {
        /// <summary>
        /// 必须，由授权服务颁发的 access token
        /// </summary>
        public string access_token { get; set; }
        /// <summary>
        /// 可选，AccessToken 的寿命，以秒为单位，如果 access_token 会过期则应该必须提供
        /// </summary>
        public int expires_in { get; set; }
        /// <summary>
        /// 可选，用来通过以 refresh_token 的 grant_type 请求 AccessToken 接口获取新的 AccessToken 的 token
        /// </summary>
        public string refresh_token { get; set; }
        /// <summary>
        /// example_value
        /// </summary>
        public string example_parameter { get; set; }
    }
}
