using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.DependencyInjection;
using Performance.DtoModels;
using Performance.EntityModels;
using Performance.Infrastructure;
using Performance.Services;
using Performance.Services.ExtractExcelService;
using Performance.Services.Queues;
using System.Collections.Generic;
using System.IO;

namespace Performance.Api.Controllers
{
    [Route("api/extract")]
    public class ModExtractController : Controller
    {
        private readonly ClaimService _claim;
        private readonly AllotService _allotService;
        private readonly TaskService _taskService;
        private readonly CustomExtractService _extractService;
        private readonly IServiceScopeFactory _serviceScopeFactory;
        //private readonly IBackgroundTaskQueue _backgroundTaskQueue;
        private readonly IHubNotificationQueue _notificationQueue;
        private readonly ExtractPreConfigService _preConfigService;

        public ModExtractController(
            ClaimService claim,
            AllotService allotService,
            TaskService taskService,
            CustomExtractService extractService,
            IServiceScopeFactory serviceScopeFactory,
            //IBackgroundTaskQueue backgroundTaskQueue,
            IHubNotificationQueue notificationQueue,
            ExtractPreConfigService preConfigService
            )
        {
            _claim = claim;
            _allotService = allotService;
            _taskService = taskService;
            _extractService = extractService;
            _serviceScopeFactory = serviceScopeFactory;
            //_backgroundTaskQueue = backgroundTaskQueue;
            _notificationQueue = notificationQueue;
            _preConfigService = preConfigService;
        }

        [HttpPost("custom/{allotId}")]
        public ApiResponse CustomExtract(int allotId)
        {
            var userId = _claim.GetUserId();
            if (!_extractService.CheckConfigScript(userId, allotId))
                return new ApiResponse(ResponseType.Fail, "未配置自定义抽取，请联系绩效管理人员。");

            //_backgroundTaskQueue.QueueBackgroundWorkItem(async token =>
            //{
            //    using (var scope = _serviceScopeFactory.CreateScope())
            //    {
            //        var scopedServices = scope.ServiceProvider.GetRequiredService<CustomExtractService>();
            //        var scopedAllotService = scope.ServiceProvider.GetRequiredService<AllotService>();
            //        var scopedQueue = scope.ServiceProvider.GetRequiredService<IHubNotificationQueue>();

            //        if (scopedServices.ExtractData(userId, allotId, out string resultFilePath))
            //        {
            //            scopedAllotService.UpdateAllotCustomExtractPath(allotId, resultFilePath);
            //            scopedQueue.Send(new Notification(allotId, "CustomDowoload", new CustomDownloadContent("自定义数据提取数据成功，是否立即下载", allotId)));
            //        }
            //        else
            //        {
            //            scopedQueue.Send(new Notification(allotId, "ReceiveMessage", new TextContent("自定义数据提取数据失败", NotificationLevel.ERR)));
            //        }

            //        await Task.Delay(TimeSpan.FromSeconds(5), token);
            //    }
            //});

            _taskService.Add(Background.JobType.自定义抽取, JsonHelper.Serialize(new { UserId = userId, AllotId = allotId }));

            _notificationQueue.Send(new Notification(allotId, "ReceiveMessage", new TextContent("自定义数据提取任务开始执行")));


            return new ApiResponse(ResponseType.OK);
        }

        /// <summary>
        /// 从WebAPI下载文件
        /// </summary>
        /// <returns></returns>
        [Route("down/{allotId}")]
        [HttpGet]
        [AllowAnonymous]
        public IActionResult DownFile(int allotId)
        {
            var allot = _allotService.GetAllot(allotId);
            if (allot == null || string.IsNullOrWhiteSpace(allot.CustomExtractPath) || !FileHelper.IsExistFile(allot.CustomExtractPath))
            {
                return new ObjectResult(new ApiResponse(ResponseType.Fail, "文件不存在"));
            }

            var memoryStream = new MemoryStream();
            using (var stream = new FileStream(allot.CustomExtractPath, FileMode.Open))
            {
                stream.CopyToAsync(memoryStream).Wait();
            }
            memoryStream.Seek(0, SeekOrigin.Begin);
            string fileExt = Path.GetExtension(allot.CustomExtractPath);
            var provider = new FileExtensionContentTypeProvider();
            var memi = provider.Mappings[fileExt];
            return File(memoryStream, memi, Path.GetFileName(allot.CustomExtractPath));
        }

        #region 医院数据库配置

        /// <summary>
        /// 医院数据库配置列表
        /// </summary>
        /// <param name="hospitalId"></param>
        /// <returns></returns>
        [HttpGet("hospital/config/{hospitalId}")]
        public ApiResponse<List<sys_hospitalconfig>> GetHospitalConfig([FromRoute] int hospitalId)
        {
            if (hospitalId == 0) return new ApiResponse<List<sys_hospitalconfig>>(ResponseType.ParameterError, "参数错误");
            var list = _preConfigService.GetHospitalConfig(hospitalId);
            return new ApiResponse<List<sys_hospitalconfig>>(ResponseType.OK, list);
        }

        /// <summary>
        /// 创建医院数据库配置
        /// </summary>
        /// <param name="hospitalconfig"></param>
        /// <returns></returns>
        [HttpPost("hospital/config/create")]
        public ApiResponse CreateHospitalConfig([FromBody] sys_hospitalconfig hospitalconfig)
        {
            if (hospitalconfig == null) return new ApiResponse(ResponseType.ParameterError, "参数错误");
            var flag = _preConfigService.CreateHospitalConfig(hospitalconfig);
            return flag
                ? new ApiResponse(ResponseType.OK, "添加成功")
                : new ApiResponse(ResponseType.Fail, "添加失败");
        }

        /// <summary>
        /// 修改医院数据库配置
        /// </summary>
        /// <param name="hospitalconfig"></param>
        /// <returns></returns>
        [HttpPost("hospital/config/update")]
        public ApiResponse UpdateHospitalConfig([FromBody] sys_hospitalconfig hospitalconfig)
        {
            if (hospitalconfig == null) return new ApiResponse(ResponseType.ParameterError, "参数错误");
            var flag = _preConfigService.UpdateHospitalConfig(hospitalconfig);
            return flag
                ? new ApiResponse(ResponseType.OK, "添加成功")
                : new ApiResponse(ResponseType.Fail, "添加失败");
        }

        /// <summary>
        /// 删除医院数据库配置
        /// </summary>
        /// <param name="hospitalconfigId"></param>
        /// <returns></returns>
        [HttpPost("hospital/config/{hospitalconfigId}")]
        public ApiResponse DeleteHospitalConfig([FromRoute] int hospitalconfigId)
        {
            if (hospitalconfigId == 0) return new ApiResponse(ResponseType.ParameterError, "参数错误");
            var flag = _preConfigService.DeleteHospitalConfig(hospitalconfigId);
            return flag
                ? new ApiResponse(ResponseType.OK, "添加成功")
                : new ApiResponse(ResponseType.Fail, "添加失败");
        }

        /// <summary>
        /// 测试连接
        /// </summary>
        /// <param name="hospitalconfigId"></param>
        /// <returns></returns>
        [HttpPost("hospital/connection/{hospitalconfigId}")]
        public ApiResponse TestConnectionCleared([FromRoute] int hospitalconfigId)
        {
            if (hospitalconfigId == 0) return new ApiResponse(ResponseType.ParameterError, "参数错误");
            var flag = _preConfigService.TestConnectionCleared(hospitalconfigId);
            return flag
                ? new ApiResponse(ResponseType.OK, "连接成功")
                : new ApiResponse(ResponseType.Fail, "连接失败");
        }

        #endregion

        #region 提取script配置

        /// <summary>
        /// 数据提取信息列表
        /// </summary>
        /// <param name="hospitalId"></param>
        /// <returns></returns>
        [HttpGet("type/{hospitalId}")]
        public ApiResponse GetExtractTypeAndScript([FromRoute] int hospitalId)
        {
            if (hospitalId == 0) return new ApiResponse(ResponseType.ParameterError, "参数错误");
            var list = _preConfigService.GetExtractTypeAndScript(hospitalId);
            return new ApiResponse(ResponseType.OK, list);
        }

        /// <summary>
        /// 数据提取详情
        /// </summary>
        /// <param name="typeId"></param>
        /// <param name="scriptId"></param>
        /// <returns></returns>
        [HttpGet("type/{typeId}/{scriptId}")]
        public ApiResponse GetExtractTypeAndScriptById([FromRoute] int typeId, int scriptId)
        {
            if (typeId == 0) return new ApiResponse(ResponseType.ParameterError, "参数错误");
            var data = _preConfigService.GetExtractTypeAndScriptById(typeId, scriptId);
            return new ApiResponse(ResponseType.OK, data);
        }

        /// <summary>
        /// 删除提取Sql
        /// </summary>
        /// <param name="typeId"></param>
        /// <param name="scriptId"></param>
        /// <returns></returns>
        [HttpPost("type/{typeId}/{scriptId}")]
        public ApiResponse DeleteExtractTypeAndScript([FromRoute] int typeId, int scriptId)
        {
            if (typeId == 0) return new ApiResponse(ResponseType.ParameterError, "参数错误");
            var flag = _preConfigService.DeleteExtractTypeAndScript(typeId, scriptId);
            return flag
                ? new ApiResponse(ResponseType.OK, "删除成功")
                : new ApiResponse(ResponseType.Fail, "删除失败");
        }

        /// <summary>
        /// 保存数据
        /// </summary>
        /// <param name="hospitalId"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost("type/{hospitalId}/save")]
        public ApiResponse EditExtractTypeAndScript([FromRoute] int hospitalId, [FromBody] ExtractConfigResponse request)
        {
            var flag = _preConfigService.EditExtractTypeAndScript(hospitalId, request);
            return flag
                ? new ApiResponse(ResponseType.OK, "操作成功")
                : new ApiResponse(ResponseType.Fail, "操作失败");
        }

        /// <summary>
        /// 执行Sql
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost("type/{typeId}/execute")]
        public ApiResponse ExecsqlAndGetResult([FromBody] ConsumeTimeRequest request)
        {
            if (request == null) return new ApiResponse(ResponseType.ParameterError, "参数错误");
            var flag = _preConfigService.ExecsqlAndGetResult(request);
            return new ApiResponse(ResponseType.OK, flag);
        }

        #endregion

        #region 字典

        /// <summary>
        /// 数据库类型
        /// </summary>
        /// <returns></returns>
        [HttpGet("database")]
        public ApiResponse<List<TitleValue<int>>> GetDatatypes()
        {
            var list = ExtractPreConfigService.GetDatatypes();
            return new ApiResponse<List<TitleValue<int>>>(ResponseType.OK, list);
        }

        /// <summary>
        /// 来源类型
        /// </summary>
        /// <returns></returns>
        [HttpGet("sheettype")]
        public ApiResponse<List<TitleValue<int>>> GetSheettypes()
        {
            var list = ExtractPreConfigService.GetSheettypes();
            return new ApiResponse<List<TitleValue<int>>>(ResponseType.OK, list);
        }

        /// <summary>
        /// 医院数据库连接配置
        /// </summary>
        /// <param name="hospitalId"></param>
        /// <returns></returns>
        [HttpGet("config/{hospitalId}")]
        public ApiResponse<List<TitleValue<int>>> GetConfigs([FromRoute] int hospitalId)
        {
            var list = _preConfigService.GetConfigs(hospitalId);
            return new ApiResponse<List<TitleValue<int>>>(ResponseType.OK, list);
        }

        #endregion
    }
}