using Infrastructure;
using Infrastructure.Model;
using Microsoft.AspNetCore.Mvc;
using MiniExcelLibs;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System.Web;
using FF = System.IO;

namespace ZR.Admin.WebApi.Controllers
{
    /// <summary>
    /// WebApi 基类
    /// </summary>
    public class BaseController : ControllerBase
    {
        /// <summary>
        /// Json字符串自定义的时间格式化 
        /// </summary>
        public const string TIME_FORMAT_FULL = "yyyy-MM-dd HH:mm:ss.fff";

        /// <summary>
        /// 封装 WebApi接口操作成功的返回结果
        /// </summary>
        /// <param name="data"></param>
        /// <param name="timeFormatStr"></param>
        /// <returns></returns>
        protected IActionResult SUCCESS(object data, string timeFormatStr = TIME_FORMAT_FULL)
        {
            string jsonStr = GetJsonStr(GetApiResult(data != null ? ResultCode.SUCCESS : ResultCode.FAIL, data), timeFormatStr);
            return Content(jsonStr, "application/json");
        }

        /// <summary>
        /// 封装 WebApi接口操作的返回结果
        /// json输出的字符串带有自定义的时间格式
        /// </summary>
        /// <param name="apiResult">返回结果对象</param>
        /// <param name="timeFormatStr">自定义的时间格式</param>
        /// <returns></returns>
        protected IActionResult ToResponse(ApiResult apiResult, string timeFormatStr = TIME_FORMAT_FULL)
        {
            string jsonStr = GetJsonStr(apiResult, timeFormatStr);

            return Content(jsonStr, "application/json");
        }
        /// <summary>
        /// 封装 WebApi接口操作的返回结果
        /// json输出的字符串带有自定义的时间格式
        /// </summary>
        /// <param name="rows">受影响行数</param>
        /// <param name="timeFormatStr">自定义的时间格式</param>
        /// <returns></returns>
        protected IActionResult ToResponse(long rows, string timeFormatStr = TIME_FORMAT_FULL)
        {
            string jsonStr = GetJsonStr(ToJson(rows), timeFormatStr);

            return Content(jsonStr, "application/json");
        }
        /// <summary>
        /// 封装 WebApi接口操作的返回结果
        /// json输出的字符串带有自定义的时间格式
        /// </summary>
        /// <param name="resultCode">返回的状态码</param>
        /// <param name="msg">返回信息</param>
        /// <returns></returns>
        protected IActionResult ToResponse(ResultCode resultCode, string msg = "")
        {
            return ToResponse(GetApiResult(resultCode, msg));
        }

        /// <summary>
        /// 导出Excel
        /// </summary>
        /// <param name="path">完整文件路径</param>
        /// <param name="fileName">带扩展文件名</param>
        /// <returns></returns>
        protected IActionResult ExportExcel(string path, string fileName)
        {
            //IWebHostEnvironment webHostEnvironment = (IWebHostEnvironment)App.ServiceProvider.GetService(typeof(IWebHostEnvironment));
            //string fileDir = Path.Combine(webHostEnvironment.WebRootPath, path, fileName);

            var stream = FF.File.OpenRead(path);  //创建文件流
            return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", HttpUtility.UrlEncode(fileName));
        }
        
        #region 方法

        /// <summary>
        /// 响应返回结果
        /// </summary>
        /// <param name="rows">受影响行数</param>
        /// <returns></returns>
        protected ApiResult ToJson(long rows)
        {
            return rows > 0 ? GetApiResult(ResultCode.SUCCESS) : GetApiResult(ResultCode.FAIL);
        }
        /// <summary>
        /// 响应返回结果
        /// </summary>
        /// <param name="rows">受影响行数</param>
        /// <param name="data"></param>
        /// <returns></returns>
        protected ApiResult ToJson(long rows, object data)
        {
            return rows > 0 ? GetApiResult(ResultCode.SUCCESS, data) : GetApiResult(ResultCode.FAIL);
        }
        /// <summary>
        /// 全局Code使用
        /// </summary>
        /// <param name="resultCode"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        protected ApiResult GetApiResult(ResultCode resultCode, object? data = null)
        {
            ApiResult apiResult = new((int)resultCode, resultCode.ToString())
            {
                Data = data
            };

            return apiResult;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="resultCode"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        protected ApiResult GetApiResult(ResultCode resultCode, string msg)
        {
            return new ApiResult((int)resultCode, msg);
        }
        private static string GetJsonStr(ApiResult apiResult, string timeFormatStr)
        {
            if (string.IsNullOrEmpty(timeFormatStr))
            {
                timeFormatStr = TIME_FORMAT_FULL;
            }
            var serializerSettings = new JsonSerializerSettings
            {
                // 设置为驼峰命名
                ContractResolver = new CamelCasePropertyNamesContractResolver(),
                DateFormatString = timeFormatStr
            };

            return JsonConvert.SerializeObject(apiResult, Formatting.Indented, serializerSettings);
        }
        #endregion

        /// <summary>
        /// 导出Excel
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="sheetName"></param>
        /// <param name="fileName"></param>
        protected string ExportExcel<T>(List<T> list, string sheetName, string fileName)
        {
            return ExportExcelMini(list, sheetName, fileName).Item1;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="sheetName"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        protected (string, string) ExportExcelMini<T>(List<T> list, string sheetName, string fileName)
        {
            IWebHostEnvironment webHostEnvironment = (IWebHostEnvironment)App.ServiceProvider.GetService(typeof(IWebHostEnvironment));
            string sFileName = $"{fileName}{DateTime.Now:MM-dd-HHmmss}.xlsx";
            string fullPath = Path.Combine(webHostEnvironment.WebRootPath, "export", sFileName);
            
            Directory.CreateDirectory(Path.GetDirectoryName(fullPath));

            MiniExcel.SaveAs(fullPath, list, sheetName: sheetName);
            return (sFileName, fullPath);
        }

        /// <summary>
        /// 导出多个工作表(Sheet)
        /// </summary>
        /// <param name="sheets"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        protected (string, string) ExportExcelMini(Dictionary<string, object> sheets, string fileName)
        {
            IWebHostEnvironment webHostEnvironment = (IWebHostEnvironment)App.ServiceProvider.GetService(typeof(IWebHostEnvironment));
            string sFileName = $"{fileName}{DateTime.Now:MM-dd-HHmmss}.xlsx";
            string fullPath = Path.Combine(webHostEnvironment.WebRootPath, "export", sFileName);

            Directory.CreateDirectory(Path.GetDirectoryName(fullPath));

            MiniExcel.SaveAs(fullPath, sheets);
            return (sFileName, fullPath);
        }

        /// <summary>
        /// 下载导入模板
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="stream"></param>
        /// <param name="fileName">下载文件名</param>
        /// <returns></returns>
        protected (string,string) DownloadImportTemplate<T>(List<T> list,Stream stream, string fileName)
        {
            IWebHostEnvironment webHostEnvironment = (IWebHostEnvironment)App.ServiceProvider.GetService(typeof(IWebHostEnvironment));
            string sFileName = $"{fileName}模板.xlsx";
            string sFilePath = Path.Combine(webHostEnvironment.WebRootPath, "importTemplate");
            string fullPath = Path.Combine(sFilePath, sFileName);
            //判断模板路径是否存在 2023年4月24日 赵
            if (!Directory.Exists(sFilePath))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(sFilePath));
            }
            //判断模板文件是否存在 2023年4月24日 赵
            if (!FF.File.Exists(fullPath))
            {
                //在服务器生成模板文件，用来提供下载 2023年4月24日 赵
                MiniExcel.SaveAs(fullPath, list);
            }
            return (fullPath,sFileName);
        }
    }
}
