using System;
using System.Net.Http;
using EasyCaching.Core;
using gRPC.ZHiZHUN.AuthServer.protos;
using Grpc.Net.Client;
using Grpc.Net.Client.Configuration;
using IRaCIS.Application.Interfaces;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Auth;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using System.Collections.Generic;
using System.Text;
using Microsoft.AspNetCore.Http;
using IRaCIS.Core.Application.Interfaces;
using System.Threading.Tasks;
using IRaCIS.Application.Services;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Infrastructure;
using System.Linq;
using Microsoft.Extensions.Logging;
using IRaCIS.Core.Application.Contracts.Dicom.DTO;

namespace IRaCIS.Api.Controllers
{
    /// <summary>
    /// 医生基本信息 、工作信息  专业信息、审核状态
    /// </summary>
    [ApiController, ApiExplorerSettings(GroupName = "Reviewer")]
    public class ExtraController : ControllerBase
    {


        /// <summary>
        ///  获取医生详情 
        /// </summary>
        /// <param name="attachmentService"></param>
        /// <param name="_doctorService"></param>
        /// <param name="_educationService"></param>
        /// <param name="_trialExperienceService"></param>
        /// <param name="_researchPublicationService"></param>
        /// <param name="_vacationService"></param>
        /// <param name="doctorId"></param>
        /// <returns></returns>
        [HttpGet, Route("doctor/getDetail/{doctorId:guid}")]
       
        public  async Task<IResponseOutput<DoctorDetailDTO>> GetDoctorDetail([FromServices] IAttachmentService attachmentService, [FromServices] IDoctorService _doctorService,
            [FromServices] IEducationService _educationService, [FromServices] ITrialExperienceService _trialExperienceService,
            [FromServices] IResearchPublicationService _researchPublicationService, [FromServices] IVacationService _vacationService, Guid doctorId)
        {
            var education = await _educationService.GetEducation(doctorId);

            var sowList = _doctorService.GetDoctorSowList(doctorId);
            var ackSowList = _doctorService.GetDoctorAckSowList(doctorId);

            var doctorDetail = new DoctorDetailDTO
            {
                AuditView =await _doctorService.GetAuditState(doctorId),
                BasicInfoView = await _doctorService.GetBasicInfo(doctorId),
                EmploymentView = await _doctorService.GetEmploymentInfo(doctorId),
                AttachmentList = await attachmentService.GetAttachments(doctorId),

                EducationList = education.EducationList,
                PostgraduateList = education.PostgraduateList,

                TrialExperienceView = await _trialExperienceService.GetTrialExperience(doctorId),
                ResearchPublicationView = await _researchPublicationService.GetResearchPublication(doctorId),

                SpecialtyView =await _doctorService.GetSpecialtyInfo(doctorId),
                InHoliday = (await _vacationService.OnVacation(doctorId)).IsSuccess,
                IntoGroupInfo = _doctorService.GetDoctorIntoGroupInfo(doctorId),
                SowList = sowList,
                AckSowList = ackSowList
            };

            return ResponseOutput.Ok(doctorDetail);
        }



        //[HttpGet, Route("imageShare/VerifyShareImage/{resourceId:guid}/{password}")]
        //public async Task<IResponseOutput> VerifyShareImage(Guid resourceId, string password, [FromServices] IRepository<ImageShare> _imageShareRepository)
        //{
        //    var pWord = password.Trim();
        //    var imageShare = await _imageShareRepository.FirstOrDefaultAsync(t => t.Id == resourceId);

        //    if (imageShare == null)
        //    {
        //        return ResponseOutput.NotOk("资源不存在。");
        //    }

        //    if (pWord != imageShare.Password.Trim())
        //    {
        //        return ResponseOutput.NotOk("分享密码错误。");
        //    }

        //    if (DateTime.Now > imageShare.ExpireTime)
        //    {
        //        return ResponseOutput.NotOk("资源分享过期。");
        //    }

        //    var resource = new ResourceInfo()
        //    {
        //        VisitTaskId = imageShare.VisitTaskId,
        //        RouteUrl = imageShare.RouteUrl,
        //        Token = _tokenService.GetToken(IRaCISClaims.Create(new UserBasicInfo()
        //        {
        //            Id = Guid.Empty,
        //            IsReviewer = false,
        //            IsAdmin = false,
        //            RealName = "Share001",
        //            UserName = "Share001",
        //            Sex = 0,
        //            //UserType = "ShareType",
        //            UserTypeEnum = UserTypeEnum.ShareImage,
        //            Code = "ShareCode001",
        //        }))
        //    };


        //    return ResponseOutput.Ok(resource);

        //}



        /// <summary>  系统用户登录接口[New] </summary>
        [HttpPost, Route("user/login")]
        [AllowAnonymous]
        public  async Task<IResponseOutput<LoginReturnDTO>>  Login(UserLoginDTO loginUser, [FromServices] IEasyCachingProvider provider, [FromServices] IUserService _userService,
            [FromServices] ITokenService _tokenService, [FromServices] IConfiguration configuration)
        {

            var returnModel = await _userService.Login(loginUser.UserName, loginUser.Password);

            if (returnModel.IsSuccess)
            {
                #region GRPC 调用鉴权中心，因为服务器IIS问题 http/2   故而没法使用

                ////重试策略
                //var defaultMethodConfig = new MethodConfig
                //{
                //    Names = { MethodName.Default },
                //    RetryPolicy = new RetryPolicy
                //    {
                //        MaxAttempts = 3,
                //        InitialBackoff = TimeSpan.FromSeconds(1),
                //        MaxBackoff = TimeSpan.FromSeconds(5),
                //        BackoffMultiplier = 1.5,
                //        RetryableStatusCodes = { Grpc.Core.StatusCode.Unavailable }
                //    }
                //};

                //#region  unable to trust the certificate then the gRPC client can be configured to ignore the invalid certificate

                //var httpHandler = new HttpClientHandler();
                //// Return `true` to allow certificates that are untrusted/invalid
                //httpHandler.ServerCertificateCustomValidationCallback =
                //    HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;


                //////这一句是让grpc支持本地 http  如果本地访问部署在服务器上，那么是访问不成功的 
                //AppContext.SetSwitch(
                //    "System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);

                //#endregion



                //var grpcAdress = configuration.GetValue<string>("GrpcAddress");
                ////var grpcAdress = "http://localhost:7200";

                //var channel = GrpcChannel.ForAddress(grpcAdress, new GrpcChannelOptions
                //{
                //    HttpHandler = httpHandler,
                //    ServiceConfig = new ServiceConfig { MethodConfigs = { defaultMethodConfig } }

                //});
                ////var channel = GrpcChannel.ForAddress(grpcAdress);
                //var grpcClient = new TokenGrpcService.TokenGrpcServiceClient(channel);

                //var userInfo = returnModel.Data.BasicInfo;

                //var tokenResponse = grpcClient.GetUserToken(new GetTokenReuqest()
                //{
                //    Id = userInfo.Id.ToString(),
                //    ReviewerCode = userInfo.ReviewerCode,
                //    IsAdmin = userInfo.IsAdmin,
                //    RealName = userInfo.RealName,
                //    UserTypeEnumInt = (int)userInfo.UserTypeEnum,
                //    UserTypeShortName = userInfo.UserTypeShortName,
                //    UserName = userInfo.UserName
                //});

                //returnModel.Data.JWTStr = tokenResponse.Token;

                #endregion

                returnModel.Data.JWTStr = _tokenService.GetToken(IRaCISClaims.Create(returnModel.Data.BasicInfo));

                // 创建一个 CookieOptions 对象，用于设置 Cookie 的属性
                var option = new CookieOptions
                {
                    Expires = DateTime.Now.AddMonths(1), // 设置过期时间为 30 分钟之后
                    HttpOnly = true, // 确保 cookie 只能通过 HTTP 访问
                    SameSite = Microsoft.AspNetCore.Http.SameSiteMode.Unspecified, // 设置 SameSite 属性
                    Secure = false // 确保 cookie 只能通过 HTTPS 访问
                };

                HttpContext.Response.Cookies.Append("access_token", returnModel.Data.JWTStr, option);

            }

            var userId = returnModel.Data.BasicInfo.Id.ToString();
            //provider.Set(userId, userId, TimeSpan.FromMinutes(AppSettings.LoginExpiredTimeSpan));

            await provider.SetAsync(userId.ToString(), returnModel.Data.JWTStr, TimeSpan.FromDays(7));
            return returnModel;
        }



        [HttpGet, Route("imageShare/ShareImage")]
        [AllowAnonymous]
        public IResponseOutput ShareImage([FromServices] ITokenService _tokenService)
        {
            var token = _tokenService.GetToken(IRaCISClaims.Create(new UserBasicInfo()
            {
                Id = Guid.Empty,
                IsReviewer = false,
                IsAdmin = false,
                RealName = "Share001",
                UserName = "Share001",
                Sex = 0,
                //UserType = "ShareType",
                UserTypeEnum = UserTypeEnum.ShareImage,
                Code = "ShareCode001",
            }));
            return ResponseOutput.Ok("/showdicom?studyId=f7b67793-8155-0223-2f15-118f2642efb8&type=Share&token=" + token);
        }





        [HttpGet("User/UserRedirect")]
        [AllowAnonymous]
        public async Task<IActionResult> UserRedirect([FromServices] IRepository<User> _userRepository,  string url ,[FromServices]ILogger<ExtraController> _logger)
        {

            var decodeUrl = System.Web.HttpUtility.UrlDecode(url);

            var userId = decodeUrl.Substring(decodeUrl.IndexOf("UserId=") + "UserId=".Length , 36) ;

            var token = decodeUrl.Substring(decodeUrl.IndexOf("access_token=") + "access_token=".Length);

            var domainStrList = decodeUrl.Split("/").ToList().Take(3).ToList();

            var errorUrl = domainStrList[0]+"//"+ domainStrList[2]+ "/error";


            if (!await _userRepository.AnyAsync(t => t.Id == Guid.Parse(userId)  && t.EmailToken == token && t.IsFirstAdd))
            {
                decodeUrl = errorUrl+ $"?ErrorMessage={System.Web.HttpUtility.UrlEncode("您的初始化链接已过期")} ";
            }

            return Redirect(decodeUrl);
        }





        [HttpGet, Route("ip")]
        [AllowAnonymous]
        public IResponseOutput Get([FromServices] IHttpContextAccessor _context/*, [FromServices] IUserService _userService*/)
        {

            StringBuilder sb = new StringBuilder();
            sb.AppendLine($"RemoteIpAddress：{_context.HttpContext.Connection.RemoteIpAddress}");

            if (Request.Headers.ContainsKey("X-Real-IP"))
            {
                sb.AppendLine($"X-Real-IP：{Request.Headers["X-Real-IP"].ToString()}");
            }

            if (Request.Headers.ContainsKey("X-Forwarded-For"))
            {
                sb.AppendLine($"X-Forwarded-For：{Request.Headers["X-Forwarded-For"].ToString()}");
            }
            return ResponseOutput.Ok(sb.ToString());
        }


        [HttpGet, Route("ip2")]
        [AllowAnonymous]
        public IResponseOutput Get2([FromServices] IHttpContextAccessor _context, [FromServices] IRepository _userService)
        {

            StringBuilder sb = new StringBuilder();
            sb.AppendLine($"RemoteIpAddress：{_context.HttpContext.Connection.RemoteIpAddress}");

            if (Request.Headers.ContainsKey("X-Real-IP"))
            {
                sb.AppendLine($"X-Real-IP：{Request.Headers["X-Real-IP"].ToString()}");
            }

            if (Request.Headers.ContainsKey("X-Forwarded-For"))
            {
                sb.AppendLine($"X-Forwarded-For：{Request.Headers["X-Forwarded-For"].ToString()}");
            }
            return ResponseOutput.Ok(sb.ToString());
        }

    }
}
