using DataSharing.Application.Identity;
using DataSharing.RawData;
using DataSharing.Share.Dtos;
using DataSharing.Share.Dtos.YiBin.Enterprise;
using DataSharing.YiBin.Enterprise;
using DotNetCore.CAP;
using Hotline.Share.Dtos.DataSharing.PusherHotlineDto;
using Hotline.Share.Dtos.File;
using Hotline.Share.Dtos.FlowEngine.Workflow;
using MapsterMapper;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using XF.Domain.Filters;
using XF.Domain.Options;
using XF.Domain.Repository;

namespace DataSharing.Host.Controllers.YiBin
{
    /// <summary>
    /// 企业专班
    /// </summary>
    public class EnterpriseController : BaseController
    {
        private readonly IMapper _mapper;
        private readonly IRepository<DsReceiveEnterpriseData> _dsReceiveEnterpriseDataRepository;
        private readonly EnterpriseClient _enterpriseClient;
        private readonly IMediator _mediator;
        private readonly ICapPublisher _capPublisher;
        private readonly IRepository<DsOrder> _dataOrderRepository;
        private readonly IChannelConfigurationManager _channelConfigurationManager;
        private readonly IIdentityAppService _identityAppService;
        private readonly IOptionsSnapshot<IdentityConfiguration> _identityOptionsAccessor;
        private readonly ISharingConfigurationManager _sharingConfigurationManager;
        private readonly IRepository<DsReceiveHandleData> _dsReceiveHandleDataRepository;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="mapper"></param>
        /// <param name="dsReceiveEnterpriseDataRepository"></param>
        /// <param name="enterpriseClient"></param>
        /// <param name="mediator"></param>
        /// <param name="capPublisher"></param>
        /// <param name="dataOrderRepository"></param>
        /// <param name="channelConfigurationManager"></param>
        /// <param name="identityAppService"></param>
        /// <param name="identityOptionsAccessor"></param>
        /// <param name="sharingConfigurationManager"></param>
        /// <param name="dsReceiveHandleDataRepository"></param>
        public EnterpriseController(IMapper mapper, IRepository<DsReceiveEnterpriseData> dsReceiveEnterpriseDataRepository,
            EnterpriseClient enterpriseClient,
         IMediator mediator,
         ICapPublisher capPublisher,
         IRepository<DsOrder> dataOrderRepository,
         IChannelConfigurationManager channelConfigurationManager,
         IIdentityAppService identityAppService,
         IOptionsSnapshot<IdentityConfiguration> identityOptionsAccessor,
         ISharingConfigurationManager sharingConfigurationManager,
         IRepository<DsReceiveHandleData> dsReceiveHandleDataRepository)
        {
            _mapper = mapper;
            _dsReceiveEnterpriseDataRepository = dsReceiveEnterpriseDataRepository;
            _enterpriseClient = enterpriseClient;
            _mediator = mediator;
            _capPublisher = capPublisher;
            _dataOrderRepository = dataOrderRepository;
            _channelConfigurationManager = channelConfigurationManager;
            _identityAppService = identityAppService;
            _identityOptionsAccessor = identityOptionsAccessor;
            _sharingConfigurationManager = sharingConfigurationManager;
            _dsReceiveHandleDataRepository = dsReceiveHandleDataRepository;
        }

        /// <summary>
        /// 根据账号、秘钥获取token授权
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("api/token")]
        [AllowAnonymous]
        public async Task<OpenResponse> GetToken([FromBody] TokenAccount dto)
        {
            var token = await _identityAppService.LoginTokenAsync(new LoginDto() { Username = dto.clientid, Password = dto.clientsecret }, HttpContext.RequestAborted);

            if (token == null || !token.IsSuccess)
                return OpenResponse.Ok(GetDataBaseReponse<string>.Failed(token?.Message));

            var jwtOptions = _identityOptionsAccessor.Value.Jwt;
            TokenModel tokenInfo = new()
            {
                expires_in = jwtOptions.Expired,
                access_token = token.Token
            };

            return OpenResponse.Ok(GetDataBaseReponse<TokenModel>.Success(tokenInfo, "授权成功"));
        }

        /// <summary>
        /// 查询企业专班
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("platform/12345/selectEnterpriseList")]
        public async Task<OpenResponse> GetEnterpriseList([FromBody] SelectEnterpriseListDto dto)
        {
            var enterpriseList = _mapper.Map<SelectEnterpriseList>(dto);

            var configEnterprise = _sharingConfigurationManager.GetYiBinConfig().Enterprise;
            string baseAddress = configEnterprise.AddressUrl;
            if (!baseAddress.EndsWith('/'))
                baseAddress += "/";
            var response = await _enterpriseClient.RequestAsync<EnterpriseResponse>(baseAddress + YbEnterpriseDefaults.PathEnterprisesList, "Post", System.Text.Json.JsonSerializer.Serialize(enterpriseList), HttpContext.RequestAborted);

            if (response != null)
            {
                if (response.success == true && response.data != null)
                {
                    return OpenResponse.Ok(System.Text.Json.JsonSerializer.Deserialize<EnRecordsDto>(response.data.ToString()));
                }
            }
            return OpenResponse.Ok("");
        }

        /// <summary>
        /// 企业服务提交办理结果
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("api/yb12345/enterprise/writeResult")]
        public async Task<OpenResponse> WriteResult([FromBody] WriteResultDto dto)
        {
            var data = new DsReceiveEnterpriseData()
            {
                ExternalId = dto.ReplyCode,
                ServiceInterface = "api/yb12345/enterprise/writeResult",
                ReceiveData = System.Text.Json.JsonSerializer.Serialize(dto)
            };

            //验证数据
            string strResult = dto.Validate();
            if (!string.IsNullOrEmpty(strResult))
                return OpenResponse.Ok(EnterpriseDeResponse.Failed(description: strResult));

            var id = await _dsReceiveEnterpriseDataRepository.AddAsync(data, HttpContext.RequestAborted);
            var order = await _dataOrderRepository.GetAsync(p => p.OrderNo == dto.ReplyCode, HttpContext.RequestAborted);
            if (order == null)
            {
                //写入对外展示表数据
                DsReceiveHandleData dsReceive = new()
                {
                    OrderNo = dto.ReplyCode,
                    Source = "企业专班",
                    PlatformsName = "企业专班",
                    ReceiveData = System.Text.Json.JsonSerializer.Serialize(dto),
                    OperationType = dto.ReplyResultType == 2 ? "工单退回" : dto.ReplyResultType == 1 ? "办理完成" : "办理中",
                    Opinion = dto.ReplyContent
                };
                await _dsReceiveHandleDataRepository.AddAsync(dsReceive, HttpContext.RequestAborted);
                //这里往业务系统推送数据
                return OpenResponse.Ok(EnterpriseDeResponse.Success("回复提交成功"));
            }

            List<FileDto> Files = new();
            if (dto.ReplyFiles != null && dto.ReplyFiles.Count > 0)
            {
                foreach (var item in dto.ReplyFiles)
                {
                    byte[] fileContentBytes = Convert.FromBase64String(item.FileText);
                    var fileData = SendFileData(fileContentBytes, item.Filename, item.Fileformat, dto.ReplyResultType == 2 ? "退回附件" : "办理上传");
                    if (fileData != null)
                    {
                        Files.Add(fileData);
                    }
                }
            }

            if (!string.IsNullOrEmpty(id))
            {
                //如果是办理中调用
                if (dto.ReplyResultType != 0)
                {
                    string FinishType = "";
                    if (dto.ReplyResultType == 2)
                        FinishType = "0";
                    else if (dto.ReplyResultType == 1)
                        FinishType = "1";

                    if (order != null)
                    {
                        OrderResultDto orderResultDto = new()
                        {
                            OrderId = order.OrderId,
                            FinishType = FinishType,
                            Opinion = dto.ReplyContent,
                            Files = Files,
                            Source = "yb-enterprise"
                        };
                        await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.SharingOrderReultSend, orderResultDto, cancellationToken: HttpContext.RequestAborted);
                    }
                }
                else
                {
                    //这里调用业务接口，推送办理数据
                    List<WorkflowTraceDto> Traces = new()
                    {
                        new()
                        {
                            HandlerName = dto.ReplyUserName,
                            HandlerOrgName = dto.ReplyBMName,
                            HandleTime =Convert.ToDateTime( dto.ReplyDate),
                            Opinion = dto.ReplyContent,
                            Files=Files
                        }
                    };
                    AddOrderTracesDto addOrderTracesDto = new()
                    {
                        OrderId = order.OrderId,
                        Traces = Traces
                    };

                    if (order != null)
                        await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.SharingOrderAddTraces, addOrderTracesDto, cancellationToken: HttpContext.RequestAborted);
                }

                //这里往业务系统推送数据
                return OpenResponse.Ok(EnterpriseDeResponse.Success("回复提交成功"));
            }
            return OpenResponse.Ok(EnterpriseDeResponse.Failed("接口调用失败！"));
        }

        /// <summary>
        /// 将文件流上传到附件服务器
        /// </summary>
        /// <param name="fileContentBytes">文件流</param>
        /// <param name="fileName">文件名称</param>
        /// <param name="type">文件类型</param>
        /// <param name="classify">文件分类</param>
        /// <returns></returns>
        private FileDto SendFileData(byte[] fileContentBytes, string fileName, string type, string classify)
        {
            var businessFile = _channelConfigurationManager.GetConfigurationBusinessFile();
            fileName = fileName + "." + type;
            // 构造字典文件数据
            // 接口参数名称为files
            CFormUpload.FileParameter fileParameter = new("fileData", fileContentBytes, fileName, "multipart/form-data");

            Dictionary<string, object> dicParam = new()
            {
                { fileName, fileParameter }
            };
            string url = string.Format("{0}{1}?source={2}", businessFile.BaseUrl, businessFile.UploadUrlAddress, businessFile.Source);
            var result = CFormUpload.MultipartFormDataPost(url, null, dicParam, "");
            FileDto fileDto = null;
            if (!string.IsNullOrEmpty(result))
            {
                var resultData = Newtonsoft.Json.JsonConvert.DeserializeObject<BusinessFileResponse>(result);
                if (resultData != null && resultData.code == 0)
                {
                    string strSuffix = fileName.LastIndexOf(".") > 0 ? fileName.Substring(fileName.LastIndexOf(".") + 1) : "";
                    string strSubFileName = fileName.LastIndexOf(".") > 0 ? fileName.Substring(0, fileName.LastIndexOf(".")) : fileName;
                    fileDto = new()
                    {
                        Name = strSubFileName,
                        Type = strSuffix,
                        Classify = classify,
                        Additions = resultData.result.id,
                        Path = resultData.result.path
                    };
                }
            }
            return fileDto;
        }
    }
}
