using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Edu.Common.API;
using Edu.Common.Plugin;
using Edu.WebApi.Controllers.Course;
using Edu.WebApi.Filter;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;

namespace Edu.WebApi.Controllers.Upload
{
    [Route("api/[controller]/[action]")]
    [ApiExceptionFilter]
    [ApiController]
    [EnableCors("AllowCors")]
    public class UploadController : ControllerBase
    {

        /// <summary>
        /// 上传Excel文件
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [AllowAnonymous]
        public ApiResult UploadFile()
        {
            try
            {
                var files = Request.Form.Files;
                if (files.Count == 0)
                {
                    return new ApiResult { Code = (int)ResultCode.Fail, Message = "未选择文件", Data = "" };
                }
                var json = !string.IsNullOrEmpty(Request.Form["params"]) ? JObject.Parse(Request.Form["params"].ToString()) : null;

                Int32.TryParse((json["Analysis"]!=null? json["Analysis"].ToString():"0"), out int Analysis);
                Int32.TryParse((json["Excel"] != null ? json["Excel"].ToString() : "0"), out int Excel);
                Int32.TryParse((json["Word"] != null ? json["Word"].ToString() : "0"), out int Word);
                Int32.TryParse((json["CourseId"] != null ? json["CourseId"].ToString() : "0"), out int CourseId);
                Int32.TryParse((json["Uid"] != null ? json["Uid"].ToString() : "0"), out int Uid);

                string filename = files[0].FileName;
                string fileExtention = System.IO.Path.GetExtension(files[0].FileName);
                //验证文件格式
                List<string> ExtList = new List<string>() {
                    ".xls",
                    ".xlsx",
                    ".doc",
                    ".docx"
                };
                if (!ExtList.Contains(fileExtention))
                {
                    return new ApiResult { Code = (int)ResultCode.Fail, Message = "文件格式有误", Data = "" };
                }
                string path = Guid.NewGuid().ToString() + fileExtention;
                string basepath = AppContext.BaseDirectory;
                string tempPath = basepath + "\\upfile\\temporary\\" + DateTime.Now.ToString("yyyyMMdd")+"\\";
                string path_server = tempPath + path;
                if (!Directory.Exists(tempPath))
                {
                    Directory.CreateDirectory(tempPath);
                }
                using (FileStream fstream = new FileStream(path_server, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                {
                    files[0].CopyTo(fstream);
                }

                //导入Excel文件
                if (Analysis == 1 && Excel == 1)
                {
                    return new QuestionController().ImportExcelQuestion(path_server, CourseId, Uid);
                }
                //导入Word文件
                if (Analysis == 1 && Word == 1 )
                {
                    return new QuestionController().ImportWordQuestion(path_server, CourseId, Uid,isDelete:true);
                }
                return ApiResult.Success("", new { Name = filename, Path = path_server });
            }
            catch (Exception ex)
            {
                LogHelper.Write(ex, "UploadFile");
                return ApiResult.Failed();
            }
        }


        /// <summary>
        /// 文件流下载
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [AllowAnonymous]
        public FileContentResult DownloadFileForPdf(string fileName, string fPath)
        {
            try
            {
                string basepath = AppContext.BaseDirectory;
                string tempPath = basepath + fPath.Replace('/', '\\');
                for (var i = 0; i < 10; i++)
                {
                    if (FileIsUsed(tempPath))
                    {
                        //true  被占用
                        System.Threading.Thread.Sleep(1000); //停一秒
                    }
                    else
                    {
                        break;
                    }
                }
                //以字符流的形式下载文件
                FileStream fs = new FileStream(tempPath, FileMode.Open);
                byte[] bytes = new byte[(int)fs.Length];
                fs.Read(bytes, 0, bytes.Length);
                fs.Close();
                return File(bytes, "application/octet-stream", fileName);
            }
            catch (Exception ex)
            {
                LogHelper.Write(ex, "DownLoad");
            }
            return File(new byte[0], "application/octet-stream", fileName);
        }


        /// <summary>
        /// 返回指示文件是否已被其它程序使用的布尔值
        /// </summary>
        /// <param name="fileFullName">文件的完全限定名，例如：“C:\MyFile.txt”。</param>
        /// <returns>如果文件已被其它程序使用，则为 true；否则为 false。</returns>
        public static bool FileIsUsed(String fileFullName)
        {
            bool result = false;

            //判断文件是否存在，如果不存在，直接返回 false
            if (!System.IO.File.Exists(fileFullName))
            {
                result = false;

            }//end: 如果文件不存在的处理逻辑
            else
            {
                //如果文件存在，则继续判断文件是否已被其它程序使用
                //逻辑：尝试执行打开文件的操作，如果文件已经被其它程序使用，则打开失败，抛出异常，根据此类异常可以判断文件是否已被其它程序使用。
                System.IO.FileStream fileStream = null;
                try
                {
                    fileStream = System.IO.File.Open(fileFullName, System.IO.FileMode.Open, System.IO.FileAccess.ReadWrite, System.IO.FileShare.None);
                    result = false;
                }
                catch (System.IO.IOException)
                {
                    result = true;
                }
                catch (System.Exception)
                {
                    result = true;
                }
                finally
                {
                    if (fileStream != null)
                    {
                        fileStream.Close();
                    }
                }

            }//end: 如果文件存在的处理逻辑
            //返回指示文件是否已被其它程序使用的值
            return result;
        }

    }
}
