using DataSharing.FwDataExchange;
using DataSharing.RawData;
using DataSharing.Share.Dtos.HotlineSetting;
using DataSharing.Share.Dtos.YiBin.ConvergenceMedia;
using DataSharing.YiBin.ConvergenceMedia;
using Hotline.Share.Dtos.DataSharingSearch;
using Hotline.Share.Dtos.File;
using Hotline.Share.Dtos.Order;
using MapsterMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using XF.Domain.Filters;
using XF.Domain.Repository;
using DataSharing.Share.Dtos;
using System.Net;
using System.Text;
using DataSharing.Share.Dtos.LuZhou;

namespace DataSharing.Host.Controllers.LuZhou
{
    /// <summary>
    /// 泸州酒城一通
    /// </summary>
    public class WineCityController : BaseController
    {
        #region 注入
        private readonly IMapper _mapper;
        private readonly IChannelConfigurationManager _channelConfigurationManager;
        private readonly IRepository<DsReceiveMediaData> _dsReceiveMediaDataRepository;
        private readonly FwClient _fwClient;
        private readonly IDsUserTokenInfoService _dsUserTokenInfoService;
        private readonly ISharingConfigurationManager _sharingConfigurationManager;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="mapper"></param>
        /// <param name="channelConfigurationManager"></param>
        /// <param name="dsReceiveMediaDataRepository"></param>
        /// <param name="fwClient"></param>
        /// <param name="dsUserTokenInfoService"></param>
        /// <param name="sharingConfigurationManager"></param>
        public WineCityController(IMapper mapper,
            IChannelConfigurationManager channelConfigurationManager,
            IRepository<DsReceiveMediaData> dsReceiveMediaDataRepository,
            FwClient fwClient,
            IDsUserTokenInfoService dsUserTokenInfoService,
            ISharingConfigurationManager sharingConfigurationManager)
        {
            _mapper = mapper;
            _channelConfigurationManager = channelConfigurationManager;
            _dsReceiveMediaDataRepository = dsReceiveMediaDataRepository;
            _fwClient = fwClient;
            _dsUserTokenInfoService = dsUserTokenInfoService;
            _sharingConfigurationManager = sharingConfigurationManager;
        }
        #endregion

        #region 工单写信

        /// <summary>
        /// 工单写信
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("OrderWrite")]
        [AllowAnonymous]
        public async Task<OpenResponse> OrderWrite([FromForm] WineCityDto dto)
        {
            #region 数据验证

            var accountDto = await _dsUserTokenInfoService.CheckAccountAsync(dto.AcceptSign, HttpContext.RequestAborted);
            if (accountDto is null || accountDto.IsCheckAccount == false)
            {
                return OpenResponse.Ok(WriteOrderResponseWineCityDto.Failed("-900", "密钥错误"));
            }

            //验证数据
            WineCity winCity = System.Text.Json.JsonSerializer.Deserialize<WineCity>(dto.AcceptContent);
            string strResult = winCity.Validate();
            if (!string.IsNullOrEmpty(strResult))
            {
                return OpenResponse.Ok(WriteOrderResponseWineCityDto.Failed("0", strResult));
            }

            //写入原始数据
            DsReceiveMediaData dsReceiveMediaData = new()
            {
                ServiceInterface = "WriteOrder",
                PlatformsName = accountDto.PlatformSourceName,
                ReceiveData = System.Text.Json.JsonSerializer.Serialize(winCity)
            };
            dsReceiveMediaData.Id = await _dsReceiveMediaDataRepository.AddAsync(dsReceiveMediaData, HttpContext.RequestAborted);

            #endregion

            #region 绑定数据

            var platformSource = accountDto.PlatformSource;
            if (platformSource == "JCeT")
                platformSource = "WineCity";

            AddOrderDto data = new()
            {
                Title = winCity.Title,
                FromName = winCity.LinkName,
                Contact = winCity.LinkTel,
                FullAddress = winCity.Address,
                Content = winCity.Content,
                IsSecret = winCity.SFlag == "0" ? false : true,
                Source = (Hotline.Share.Enums.Order.ESource)System.Enum.Parse(typeof(Hotline.Share.Enums.Order.ESource), platformSource),
                FromGender = winCity.LinkSex switch
                {
                    "1" => Hotline.Share.Enums.Order.EGender.Male,
                    "2" => Hotline.Share.Enums.Order.EGender.Female,
                    _ => Hotline.Share.Enums.Order.EGender.Unknown,
                },
                IdentityType = Hotline.Share.Enums.Order.EIdentityType.Citizen,
                Transpond = false,
                IsEnforcementOrder = false,
                ExternalId = Guid.NewGuid().ToString()
            };

            switch (accountDto.PlatformSource)
            {
                case "JCeT":
                    data.SourceChannel = "酒城e通";
                    data.SourceChannelCode = accountDto.PlatformSource;
                    break;
                case "LZCityPortalSite":
                    data.SourceChannel = "泸州市政府门户网站";
                    data.SourceChannelCode = accountDto.PlatformSource;
                    break;
                default:
                    break;
            }

            #endregion

            #region 受理类型

            switch (winCity.PurTypeID)
            {
                case "17":
                    data.AcceptType = "咨询";
                    data.AcceptTypeCode = "10";
                    break;
                case "19":
                    data.AcceptType = "投诉";
                    data.AcceptTypeCode = "35";
                    break;
                case "20":
                    data.AcceptType = "求助";
                    data.AcceptTypeCode = "20";
                    break;
                case "22":
                    data.AcceptType = "建议";
                    data.AcceptTypeCode = "15";
                    break;
                default:
                    data.AcceptType = "咨询";
                    data.AcceptTypeCode = "10";
                    break;
            }

            #endregion

            #region 区域类型

            string areaName = "";
            switch (winCity.AeraID)
            {
                case "55":
                    data.AreaCode = "510502"; areaName = "江阳区";
                    break;
                case "56":
                    data.AreaCode = "510503"; areaName = "纳溪区";
                    break;
                case "57":
                    data.AreaCode = "510504"; areaName = "龙马潭区";
                    break;
                case "58":
                    data.AreaCode = "510521"; areaName = "泸县";
                    break;
                case "59":
                    data.AreaCode = "510522"; areaName = "合江县";
                    break;
                case "60":
                    data.AreaCode = "510524"; areaName = "叙永县";
                    break;
                case "61":
                    data.AreaCode = "510525"; areaName = "古蔺县";
                    break;
                default:
                    data.AreaCode = "510500";
                    break;
            }
            data.Address = "四川省泸州市" + areaName;

            #endregion

            #region 写入工单

            //调用工单创建接口
            var result = await _fwClient.RequestNoTokenAsync<HotlineClientResponse>("api/v1/Order/add-anonymous", "Post", System.Text.Json.JsonSerializer.Serialize(data));
            if (result != null && result.code == 0)
            {
                dsReceiveMediaData.ExternalId = result.result.id;
                dsReceiveMediaData.OrderCode = result.result.no;
                await _dsReceiveMediaDataRepository.UpdateAsync(dsReceiveMediaData, HttpContext.RequestAborted);
                WineCityCodePwdDto wccp = new() { AcceptCode = result.result.no, AcceptPwd = result.result.password };
                return OpenResponse.Ok(WriteOrderResponseWineCityDto.Success("1", wccp));
            }
            else
            {
                return OpenResponse.Ok(WriteOrderResponseWineCityDto.Failed("0", "接口调用失败"));
            }

            #endregion
        }

        #endregion

        #region 工单明细

        /// <summary>
        /// 工单明细
        /// </summary>
        /// <returns></returns>
        [HttpPost("OrderDetail")]
        [AllowAnonymous]
        public async Task<OpenResponse> OrderDetail([FromForm] WineCityDto dto)
        {
            #region 数据验证

            //验证密钥
            var accountDto = await _dsUserTokenInfoService.CheckAccountAsync(dto.AcceptSign, HttpContext.RequestAborted);
            if (accountDto is null || accountDto.IsCheckAccount == false)
            {
                return OpenResponse.Ok(WriteOrderResponseWineCityDto.Failed("-900", "密钥错误"));
            }

            WineCityCodePwd winCity = System.Text.Json.JsonSerializer.Deserialize<WineCityCodePwd>(dto.AcceptContent);
            //验证数据
            string strResult = winCity.Validate();
            if (!string.IsNullOrEmpty(strResult))
            {
                return OpenResponse.Ok(WriteOrderResponseWineCityDto.Failed("0", strResult));
            }

            #endregion

            #region 查询工单

            #region 查询老系统

            //Dictionary<string, object> dic = new Dictionary<string, object>
            //{
            //    { "AcceptSign", dto.AcceptSign },
            //    { "AcceptContent", dto.AcceptContent }
            //};
            //var strUrl = _sharingConfigurationManager.GetLuZhouConfig().LuZhouWineCity.SendDataAddress + "/lz12345/WineCity.asmx/OrderDetail";
            //var strResultData = e_SendHttpPostBySync(strUrl, dic);
            //if (!string.IsNullOrEmpty(strResultData))
            //{
            //    WinCityDetailCodeDto wdcd = System.Text.Json.JsonSerializer.Deserialize<WinCityDetailCodeDto>(strResultData);
            //    if (wdcd.code == "1")
            //    {
            //        WinCityDetailInfoDto wcdi = new()
            //        {
            //            Code = wdcd.msg.data[0].Code,
            //            AddDate = Convert.ToDateTime(wdcd.msg.data[0].AddDate).ToString("yyyy-MM-dd HH:mm:ss"),
            //            Content = wdcd.msg.data[0].Content,
            //            Result = wdcd.msg.data[0].Result
            //        };
            //        WinCityDetailDataDto wddd = new() { data = wcdi };
            //        return OpenResponse.Ok(WriteOrderResponseWineCityDto.Success("1", wddd));

            //    }
            //}
            //return OpenResponse.Ok(WriteOrderResponseWineCityDto.Failed("0", "查询失败"));

            #endregion

            #region 查询新系统

            GetOrderNoPwdDto getOrder = new()
            {
                No = winCity.AcceptCode,
                Password = winCity.AcceptPwd,
            };
            var result = await _fwClient.RequestNoTokenAsync<HotlineClientDataSharingResponse<Hotline.Share.Dtos.Order.OrderDto>>("api/v1/DataSharing/get_order_detail_by_no_pwd",
                "Post", System.Text.Json.JsonSerializer.Serialize(getOrder));
            List<MediaOrderDetailDataDto> items = new();
            if (result != null && result.code == 0)
            {
                if (result.result != null)
                {
                    var item = result.result;
                    WinCityDetailInfoDto wcdi = new()
                    {
                        Code = item.No,
                        AddDate = item.CreationTime.ToString("yyyy-MM-dd HH:mm:ss"),
                        Content = item.Content,
                        Result = item.ActualOpinion
                    };
                    WinCityDetailDataDto wddd = new() { data = wcdi };
                    return OpenResponse.Ok(WriteOrderResponseWineCityDto.Success("1", wddd));
                }
            }
            return OpenResponse.Ok(WriteOrderResponseWineCityDto.Failed("0", "查询失败"));

            #endregion

            #endregion
        }

        #endregion

        #region 上传附件

        /// <summary>
        /// 上传附件
        /// </summary>
        /// <param name="formData"></param>
        /// <returns></returns>
        [HttpPost("WriteFiles")]
        [AllowAnonymous]
        public async Task<OpenResponse> WriteFiles([FromForm] IFormCollection formData)
        {
            #region 数据验证

            string AcceptSign = formData["AcceptSign"];
            string AcceptCode = formData["AcceptCode"];
            string AcceptPwd = formData["AcceptPwd"];

            //验证密钥
            var accountDto = await _dsUserTokenInfoService.CheckAccountAsync(AcceptSign, HttpContext.RequestAborted);
            if (accountDto is null || accountDto.IsCheckAccount == false)
            {
                return OpenResponse.Ok(WriteOrderResponseWineCityDto.Failed("-900", "密钥错误"));
            }

            //验证数据
            if (string.IsNullOrEmpty(AcceptCode) || string.IsNullOrEmpty(AcceptPwd))
                return OpenResponse.Ok(WriteOrderResponseWineCityDto.Failed("0", "编号、密码不能为空！"));

            #endregion

            #region 上传附件

            var dataRaw = await _dsReceiveMediaDataRepository.GetAsync(p => p.OrderCode == AcceptCode, HttpContext.RequestAborted);
            if (dataRaw != null)
            {
                IFormFileCollection files = formData.Files;//等价于Request.Form.Files

                List<FileDto> fileDtos = new();

                foreach (var item in files)
                {
                    //这里需要上文件服务器上传
                    var businessFileDto = await SendFileData(item);

                    string strFileName = item.FileName;
                    string strSuffix = strFileName.LastIndexOf(".") > 0 ? strFileName.Substring(strFileName.LastIndexOf(".") + 1) : "";
                    string strSubFileName = strFileName.LastIndexOf(".") > 0 ? strFileName.Substring(0, strFileName.LastIndexOf(".")) : strFileName;
                    fileDtos.Add(new FileDto()
                    {
                        Name = strSubFileName,
                        Type = strSuffix,
                        Classify = "受理上传",
                        Additions = businessFileDto.id,
                        Path = businessFileDto.path,
                        AllPath = businessFileDto.path,
                        FileName = item.FileName,
                    });
                }

                UpdateOrderFilesDto updateOrderFiles = new()
                {
                    Files = fileDtos,
                    Id = dataRaw.ExternalId,
                    OrderNo = dataRaw.OrderCode
                };

                //推送数据
                var result = await _fwClient.RequestNoTokenAsync<HotlineClientResponse>("api/v1/Order/update-orderfiles", "Post", System.Text.Json.JsonSerializer.Serialize(updateOrderFiles));
                if (result != null)
                {
                    return OpenResponse.Ok(WriteOrderResponseWineCityDto.Failed("1", "上传成功"));
                }
            }
            return OpenResponse.Ok(WriteOrderResponseWineCityDto.Failed("0", "上传失败"));

            #endregion
        }

        #endregion

        #region 私有方法-将文件转化为文件流

        /// <summary>
        /// 组装附件参数
        /// </summary>
        /// <param name="fileJson"></param>
        /// <returns></returns>
        private List<GetFiles> GetOrderFiles(List<FileJson> fileJson)
        {
            var businessFile = _channelConfigurationManager.GetConfigurationBusinessFile();
            var baseUrl = businessFile.BaseUrl.Remove(businessFile.BaseUrl.Length - 1);
            List<GetFiles> getFiles = [];
            if (fileJson != null && fileJson.Count > 0)
            {
                foreach (var item in fileJson)
                {
                    GetFiles files = new()
                    {
                        FileID = item.FileId,
                        FileName = item.FileName + "." + item.FileType,
                        FileContent = baseUrl + item.Path
                    };
                    getFiles.Add(files);
                }
            }
            return getFiles;
        }

        private string GetChannelCode(string platformSource)
        {
            var sourceChannelCode = "";
            switch (platformSource)
            {
                case "ZGTFTB":
                    sourceChannelCode = "TFTB001";
                    break;
                case "ZGGC":
                    sourceChannelCode = "observe";
                    break;
                default:
                    break;
            }
            return sourceChannelCode;
        }

        /// <summary>
        /// 将文件流上传到附件服务器    
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        private async Task<BusinessFileDto> SendFileData(IFormFile file)
        {
            var businessFile = _channelConfigurationManager.GetConfigurationBusinessFile();
            // 文件名称
            string fileName = file.FileName;

            // 文件内容字节数据
            using var memoryStream = new MemoryStream();
            await file.CopyToAsync(memoryStream);
            memoryStream.Seek(0, SeekOrigin.Begin);
            byte[] fileContentBytes = memoryStream.ToArray();

            // 构造字典文件数据
            // 接口参数名称为files
            CFormUpload.FileParameter fileParameter = new CFormUpload.FileParameter("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, "");
            if (!string.IsNullOrEmpty(result))
            {
                var resultData = Newtonsoft.Json.JsonConvert.DeserializeObject<BusinessFileResponse>(result);
                if (resultData != null && resultData.code == 0)
                {
                    return resultData.result;
                }
            }
            return new BusinessFileDto();
        }

        /// <summary>
        /// POST 提交数据
        /// </summary>
        /// <param name="strUrl"> 地址</param>
        /// <param name="headers">参数</param>
        /// <param name="strEncoding"></param>
        /// <param name="strContentType"></param>
        /// <returns></returns>
        private string e_SendHttpPostBySync(string strUrl, Dictionary<string, object> headers = null, string strEncoding = "UTF-8",
            string strContentType = "application/x-www-form-urlencoded")
        {
            // 返回数据
            string strResult = "";

            try
            {
                ServicePointManager.Expect100Continue = false;
                string postDataStr = SerializeDictionaryToParam2(headers);
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(strUrl);
                request.Method = "POST";
                request.ContentType = strContentType;
                request.ContentLength = postDataStr.Length;

                StreamWriter write = new StreamWriter(request.GetRequestStream(), Encoding.ASCII);
                write.Write(postDataStr);
                write.Flush();
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                string encoding = "UTF-8";
                StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encoding));
                strResult = reader.ReadToEnd();
            }
            catch (Exception ex)
            {
                strResult = "";
            }
            finally
            {
            }
            return strResult;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dict"></param>
        /// <returns></returns>
        private string SerializeDictionaryToParam2<TKey, TValue>(Dictionary<TKey, TValue> dict)
        {
            string strParam = "";
            int nIndex = 0;
            foreach (var item in dict)
            {
                if (0 == nIndex)
                    strParam += item.Key + "=" + item.Value;
                else
                    strParam += "&" + item.Key + "=" + item.Value;
                nIndex++;
            }
            return strParam;
        }
        #endregion


    }
}
