using Common;
using Common.system;

using Newtonsoft.Json.Linq;

using System;
using System.Collections.Specialized;
using System.Threading;

using XHWK.Model;

namespace XHWK.WKTool.DAL
{
    /// <summary>
    /// 上传相关方法 创建人：赵耀 创建时间：2020年9月4日
    /// </summary>
    public class DalUpload
    {
        private readonly string _fileRequestAddress = App.uploadUrl;

        //private string schoolfileRequestAddress = APP.showImageUrl;
        /// <summary>
        /// 文件是否允许上传
        /// </summary>
        /// <param name="md5">
        /// MD5
        /// </param>
        /// <param name="message">
        /// 错误消息
        /// </param>
        /// <returns>
        /// </returns>
        public bool IsAllowUploaded(string md5, out string message)
        {
            Exception ex = null;
            message = ""; //请求重试5次 共5秒
            for (int num = 0; num < 5; num++)
            {
                try
                {
                    JObject jo = HttpHelper.PostFunction(_fileRequestAddress + @"/chunkdb/isexist",
                        @"application/x-www-form-urlencoded", @"md5=" + md5, "");
                    if (jo == null)
                    {
                        message = "无法访问文件服务器，请检查网络或文件服务器地址。";
                        return false;
                    }

                    //修改为0为之前上传成功，1为之前未上传成功
                    if (jo["code"]?.ToString() == "0")
                    {
                        message = "";

                        Model.ResultVo<Model_ResourceAddTwo> resultObj =
                            JsonHelper.JsonToObj<Model.ResultVo<Model_ResourceAddTwo>>(jo.ToString());
                        App.ResourceAddTwo = resultObj.obj;
                        //已存在 不允许上传
                        return false;
                    }
                    else
                    {
                        message = "";
                        //不存在 允许上传
                        return true;
                    }
                }
                catch (Exception e)
                {
                    message = "上传失败，无法访问到服务器：" + e.Message;
                    ex = e;
                    Thread.Sleep(1000);
                }
            }

            string errMessage = "【文件是否存在】(IsUploaded):请求失败。" + message;
            LogHelper.WriteErrLog(errMessage, ex);
            return false;
        }

        /// <summary>
        /// 上报文件合并指令
        /// </summary>
        /// <param name="savefolder">
        /// 保存文件位置 学校id/resource
        /// </param>
        /// <param name="fileCode">
        /// 文件唯一编号 Guid
        /// </param>
        /// <param name="message">
        /// 错误信息
        /// </param>
        /// <returns>
        /// </returns>
        public bool ReportFileMerge(string savefolder, string fileCode, out string message)
        {
            Exception ex = null;
            message = ""; //请求重试5次 共5秒
            for (int num = 0; num < 5; num++)
            {
                try
                {
                    JObject jo = HttpHelper.PostFunction(_fileRequestAddress + @"/chunkdb/mergechunk",
                        @"application/x-www-form-urlencoded", @"savefolder=" + savefolder + "&identifier=" + fileCode,
                        "");
                    if (jo == null)
                    {
                        message = "无法访问文件服务器，请检查网络或文件服务器地址。";
                        return false;
                    }
                    Model.ResultVo<Model_ResourceAddTwo> resultObj = JsonHelper.JsonToObj<Model.ResultVo<Model_ResourceAddTwo>>(jo.ToString());
                    App.ResourceAddTwo = new Model_ResourceAddTwo();
                    //0成功，1失败
                    if (resultObj.code == 0 && resultObj.obj != null)
                    {
                        App.ResourceAddTwo = resultObj.obj;
                        return true;
                    }
                    else
                    {
                        //Message = "上传失败！";
                        message = jo["msg"]?.ToString();
                        return false;
                    }
                }
                catch (Exception e)
                {
                    message = e.Message;
                    ex = e;
                    Thread.Sleep(1000);
                }
            }

            string errMessage = "【上报合并文件】(ReportFileMerge):请求失败。" + message;
            LogHelper.WriteErrLog(errMessage, ex);
            return false;
        }

        /// <summary>
        /// 上传视频
        /// </summary>
        /// <returns>
        /// </returns>
        public bool UploadVideo(string videoGuid, out string errMessage)
        {
            errMessage = "";
            try
            {
                Model_Video videoInfo = null;
                foreach (Model_WKData vdata in App.WKDataList)
                {
                    if (vdata.VideoList == null)
                    {
                        continue;
                    }
                    foreach (Model_Video videoinfo in vdata.VideoList)
                    {
                        if (videoinfo.FileGuid == videoGuid)
                        {
                            videoInfo = videoinfo;
                            break;
                        }
                    }
                    if (videoInfo != null)
                    {
                        break;
                    }
                }

                if (videoInfo == null)
                {
                    errMessage = "未找到课程！";
                    return false;
                }

                if (videoInfo.IsUpload)
                {
                    errMessage = "视频已上传";
                    return false;
                }
                else
                {
                    return true;
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrLog("【视频上传】（UploadVideo）视频上传失败：" + ex.Message, ex);
            }
            return false;
        }

        /// <summary>
        /// 上传视频
        /// </summary>
        /// <returns>
        /// </returns>
        public bool UploadVideoTwo(string videoGuid, out string errMessage)
        {
            errMessage = "";
            try
            {
                Model_Video videoInfo = null;
                foreach (Model_WKData vdata in App.WKDataList)
                {
                    if (vdata.VideoList == null)
                    {
                        continue;
                    }
                    foreach (Model_Video videoinfo in vdata.VideoList)
                    {
                        if (videoinfo.FileGuid == videoGuid)
                        {
                            videoInfo = videoinfo;
                            break;
                        }
                    }
                    if (videoInfo != null)
                    {
                        break;
                    }
                }

                if (videoInfo == null)
                {
                    errMessage = "未找到课程！";
                    return false;
                }

                string uploadUrl = _fileRequestAddress + "/chunkdb/upchunk"; //zxyceshi
                if (videoInfo.IsUpload)
                {
                    errMessage = "视频已上传";
                    return false;
                }
                else
                {
                    if (string.IsNullOrWhiteSpace(videoInfo.FileMD5))
                    {
                        videoInfo.FileMD5 =
                            AESHelper.AESEncrypt(FileToolsCommon.ReadBigFileStr(videoInfo.VideoPath, 1024));
                    }

                    //视频长度
                    long filelen = FileToolsCommon.GetFileSize(videoInfo.VideoPath);
                    //每片的长度
                    double uploadSliceLenMb = double.Parse(FileToolsCommon.GetConfigValue("UploadSliceLen"));
                    string fileName = FileToolsCommon.GetFileName(videoInfo.VideoPath);
                    //是否续传
                    //分块数为0时 从未上传过
                    if (videoInfo.Block > 0)
                    {
                        //是否已上传所有分块
                        if (videoInfo.Block > videoInfo.Uploaded)
                        {
                            //已上传，未上传完
                        }
                        else
                        {
                            //上传完,未合并

                            #region 合并文件

                            //合并文件
                            bool isres = ReportFileMerge
                            (
                                App.UserInfo.cloudcode + "/" + App.UserInfo.Schoolid.ToString() + "/resource",
                                videoInfo.FileGuid,
                                out errMessage
                            );
                            if (isres)
                            {
                                videoInfo.IsUpload = true;
                                return true;
                            }
                            else
                            {
                                return false;
                            }

                            #endregion 合并文件
                        }
                    }
                    else
                    {
                        //是否允许上传
                        if (IsAllowUploaded(videoInfo.FileMD5, out errMessage))
                        {
                            if (videoInfo.SliceLen == 0)
                            {
                                videoInfo.SliceLen = (long)(uploadSliceLenMb * 1024 * 1024);
                                videoInfo.Block = (int)(filelen / videoInfo.SliceLen +
                                                        (filelen % videoInfo.SliceLen > 0 ? 1 : 0));
                            }
                        }
                        else
                        {
                            //文件在服务器上已存在  空间是否存在未知 若增加空间是否存在判断在此处添加
                            videoInfo.Block = 1;
                            videoInfo.Uploaded = 1;

                            videoInfo.IsUpload = true;
                            return true;
                        }
                    }

                    ////临时修改 没有断点续传，每次上传都重新上传。
                    //VideoInfo.Uploaded = 0;
                    {
                        //已上传长度
                        long len;

                        //分块
                        do
                        {
                            len = videoInfo.Uploaded * videoInfo.SliceLen;
                            //取指定长度的流
                            byte[] byteArray = FileToolsCommon.ReadBigFileSpecifyLength(videoInfo.VideoPath, len,
                                (int)videoInfo.SliceLen);
                            //参数
                            NameValueCollection formFields = new NameValueCollection
                            {
                                { "identifier", videoInfo.FileGuid },
                                { "chunkNumber", (videoInfo.Uploaded + 1).ToString() },
                                { "filename", fileName },
                                { "totalchunk", videoInfo.Block.ToString() },
                                { "md5", videoInfo.FileMD5 }
                            };
                            //formFields.Add();///教材
                            //if()//章节若没选不传
                            //{
                            //    formFields.Add();
                            //}

                            JObject jo = HttpHelper.UploadRequestflow(uploadUrl, byteArray, fileName, formFields);
                            //0成功，1失败
                            if (jo["code"]?.ToString() != "0")
                            {
                                errMessage = jo["msg"]?.ToString();
                                return false;
                            }
                            else
                            {
                                videoInfo.Uploaded++;
                            }
                        } while (len + videoInfo.SliceLen < filelen);

                        #region 合并文件

                        //合并文件
                        bool isres = ReportFileMerge
                        (
                            App.UserInfo.cloudcode + "/" + App.UserInfo.Schoolid.ToString() + "/resource",
                            videoInfo.FileGuid,
                            out errMessage
                        );
                        if (isres)
                        {
                            //VideoInfo.IsUpload = true;
                            return true;
                        }
                        else
                        {
                            return false;
                        }

                        #endregion 合并文件
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrLog("【视频上传】（UploadVideo）视频上传失败：" + ex.Message, ex);
            }
            return false;
        }
    }
}
