using System;
using System.Net;
using System.Security.Claims;
using System.Security.Policy;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Performance.DtoModels;
using Performance.DtoModels.AppSettings;
using Performance.DtoModels.OAuth;
using Performance.Services;

namespace Performance.Api.Controllers
{
    public class OAuthController : Controller
    {
        private readonly ILogger<OAuthController> _logger;
        private readonly IOptions<Application> _options;
        private readonly OAuthService _service;

        public OAuthController(ILogger<OAuthController> logger, IOptions<Application> options, OAuthService service)
        {
            _logger = logger;
            _options = options;
            _service = service;
        }
        /// <summary>
        /// 授权起始地址
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous, HttpGet, Route("api/oauth2/authorize")]
        public async Task<ActionResult> Authorize()
        {
            _logger.LogInformation("OAuth授权启动");
            try
            {
                var url = await _service.Authorize();
                return Ok(new ApiResponse(ResponseType.OK, "", url));
            }
            catch (Exception ex)
            {
                _logger.LogError($"OAuth授权启动：请求异常={ex}");
            }
            return Ok(new ApiResponse(ResponseType.Fail, ""));
        }

        /// <summary>
        /// 获取授权码，初始化登录信息
        /// </summary>
        /// <param name="code"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        [AllowAnonymous, HttpPost, Route("api/oauth2/token")]
        public async Task<ApiResponse<JwtToken>> Token([FromQuery] string code, [FromQuery] string state)
        {
            _logger.LogInformation($"OAuth授权接受回调请求：code={code}&state={state}");
            try
            {
                var tokenResponse = await _service.Token(code, state);
                if (tokenResponse.StatusCode != (int)HttpStatusCode.OK)
                    return new ApiResponse<JwtToken>(ResponseType.Fail, "授权中心Token获取错误");

                if (tokenResponse.Data is not TokenResponse)
                    return new ApiResponse<JwtToken>(ResponseType.Fail, "授权中心Token数据无法解析");

                var tokenData = tokenResponse.Data as TokenResponse;
                var userResponse = await _service.GetUserInfo(tokenData.access_token);
                if (userResponse.StatusCode != (int)HttpStatusCode.OK)
                    return new ApiResponse<JwtToken>(ResponseType.Fail, "授权中心AccessToken获取错误");

                if (userResponse.Data is not OAuthUserInfoResponse)
                    return new ApiResponse<JwtToken>(ResponseType.Fail, "授权中心AccessToken数据无法解析");

                var userData = userResponse.Data as OAuthUserInfoResponse;
                var user = _service.GetOrInitUserInfo(userData);

                var claims = new Claim[]
                {
                    new Claim(JwtClaimTypes.Id, user.UserID.ToString()),
                    new Claim(JwtClaimTypes.Login, user.Login),
                    new Claim(JwtClaimTypes.RealName,  user.RealName),
                    new Claim(JwtClaimTypes.Mail, user.Mail??""),
                    new Claim(JwtClaimTypes.AppName, ""),
                    new Claim(JwtClaimTypes.Device, ""),
                    new Claim(JwtClaimTypes.Department, user.Department ?? ""),
                    new Claim(JwtClaimTypes.QuickLogin, EQuickLogin.SSO.ToString()),
                };

                var jwtToken = JwtTokenHelper.GenerateToken(claims, _options.Value.ExpirationMinutes);
                return new ApiResponse<JwtToken>(ResponseType.OK, jwtToken);
            }
            catch (Exception ex)
            {
                _logger.LogError($"OAuth授权接受回调请求：请求异常：{ex}");
            }
            return new ApiResponse<JwtToken>(ResponseType.Fail, "授权失败");
        }
    }
}