using Hotline.Repository.SqlSugar.Extensions;
using Hotline.Settings;
using Hotline.Share.Dtos;
using Hotline.Share.Dtos.File;
using MapsterMapper;
using Microsoft.AspNetCore.Mvc;
using XF.Domain.Authentications;
using XF.Domain.Exceptions;
using XF.Domain.Repository;
using Hotline.Caching.Interfaces;
using Microsoft.AspNetCore.Authorization;
using DocumentFormat.OpenXml.Presentation;
using Hotline.File;
using NPOI.HPSF;
using Hotline.Share.Requests;
using SqlSugar;
using Hotline.Tools;
using Hotline.Share.Dtos.Order;
using Hotline.Api.Filter;

namespace Hotline.Api.Controllers
{
    public class FileController : BaseController
    {
        private readonly ISessionContext _sessionContext;
        private readonly IMapper _mapper;
        private readonly ISystemDicDataCacheManager _sysDicDataCacheManager;
        private readonly IRepository<File.File> _fileRepository;
        private readonly ILogger<FileController> _logger;
        private readonly IRepository<UploadAudioFiles> _uploadAudioFilesRepository;

        public FileController(
            ISessionContext sessionContext,
            IMapper mapper,
            ISystemDicDataCacheManager sysDicDataCacheManager,
            IRepository<File.File> fileRepository,
            ILogger<FileController> logger,
            IRepository<UploadAudioFiles> uploadAudioFilesRepository)
        {
            _sessionContext = sessionContext;
            _mapper = mapper;
            _sysDicDataCacheManager = sysDicDataCacheManager;
            _fileRepository = fileRepository;
            _logger = logger;
            _uploadAudioFilesRepository = uploadAudioFilesRepository;
        }

        #region 附件管理
        /// <summary>
        /// 新增附件
        /// </summary>
        /// <param name="dtos"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task Add([FromBody] List<FileDto> dtos)
        {
            List<File.File> files = new List<File.File>();
            foreach (var dto in dtos)
            {
                if (string.IsNullOrEmpty(dto.Key))
                    throw UserFriendlyException.SameMessage("请上传附件关联Key");

                var model = _mapper.Map<File.File>(dto);
                model.OrgName = _sessionContext.OrgName;
                model.OrgId = _sessionContext.OrgId;
                model.UserId = _sessionContext.UserId;
                model.UserName = _sessionContext.UserName;
                files.Add(model);
            }
            await _fileRepository.AddRangeAsync(files, HttpContext.RequestAborted);
        }

        /// <summary>
        /// 删除附件
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpDelete]
        public async Task Delete([FromBody] DeleteFileDto dto)
        {
            foreach (var Id in dto.Ids)
            {
                await _fileRepository.RemoveAsync(x => x.Id == Id);
            }
        }

        /// <summary>
        /// 更新附件
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPut]
        public async Task Update([FromBody] UpdateFileDto dto)
        {
            //验证工单是否可以申请
            var file = await _fileRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
            if (file is null)
                throw UserFriendlyException.SameMessage("无效附件");
            _mapper.Map(dto, file);
            file.OrgName = _sessionContext.OrgName;
            file.OrgId = _sessionContext.OrgId;
            file.UserId = _sessionContext.UserId;
            file.UserName = _sessionContext.UserName;
            await _fileRepository.UpdateAsync(file, HttpContext.RequestAborted);
        }

        /// <summary>
        /// 获取附件列表
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpGet("list")]
        public async Task<PagedDto<File.File>> List([FromQuery] FileListDto dto)
        {
            var (total, items) = await _fileRepository.Queryable()
                .WhereIF(!string.IsNullOrEmpty(dto.Name), x => x.Name.Contains(dto.Name))
                .WhereIF(!string.IsNullOrEmpty(dto.Key), x => x.Key == dto.Key)
                .WhereIF(!string.IsNullOrEmpty(dto.Type), x => x.Type == dto.Type)
                .WhereIF(!string.IsNullOrEmpty(dto.OrgName), x => x.OrgName.Contains(dto.OrgName))
                .WhereIF(dto.Publicity > 0, x => x.Publicity == dto.Publicity)
                .WhereIF(!string.IsNullOrEmpty(dto.Classify), x => x.Classify == dto.Classify)
                .WhereIF(dto.CreationTimeStart.HasValue, d => d.CreationTime >= dto.CreationTimeStart)
                .WhereIF(dto.CreationTimeEnd.HasValue, d => d.CreationTime <= dto.CreationTimeEnd)
                .OrderByDescending(x => x.CreationTime)
                .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
            return new PagedDto<File.File>(total, items);
        }

        /// <summary>
        /// 获取附件实体
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("{id}")]
        public async Task<File.File> Entity(string id)
        {
            return await _fileRepository.Queryable()
                .FirstAsync(x => x.Id == id);
        }


        /// <summary>
        /// 获取附件分类
        /// </summary>
        /// <returns></returns>
        [HttpGet("classify")]
        public Task<object> FileClassify()
        {
            var rsp = new
            {
                FileClassify = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.FileClassify),
            };
            return Task.FromResult<object>(rsp);
        }
        #endregion

        /// <summary>
        /// 下载（代理模式）
        /// </summary>
        [HttpGet("download-proxy")]
        public async Task<IActionResult> DownloadProxy([FromServices] IHttpClientFactory clientFactory, string path)
        {
            using var client = clientFactory.CreateClient();
            var responseMessage = await client.GetAsync(path, HttpContext.RequestAborted);
            responseMessage.EnsureSuccessStatusCode();
            var stream = await responseMessage.Content.ReadAsStreamAsync(HttpContext.RequestAborted);
            return File(stream, responseMessage?.Content?.Headers?.ContentType?.MediaType);
        }

        #region 录音上传
        /// <summary>
        /// 上传录音保存
        /// </summary>
        /// <param name="dtos"></param>
        /// <returns></returns>
        [HttpPost("adduploadaudiofiles")]
        public async Task<object> AddUploadAudioFiles([FromBody] List<FileDto> dtos)
        {
            if (dtos == null || dtos.Count == 0)
                throw UserFriendlyException.SameMessage("请上传附件");
            var successNum = 0;
            var errorNum = 0;
            foreach (var item in dtos)
            {
                var fileName = item.FileName;
                string strSuffix = fileName.LastIndexOf(".") > 0 ? fileName.Substring(fileName.LastIndexOf(".") + 1) : "";
                string strSubFileName = fileName.LastIndexOf(".") > 0 ? fileName.Substring(0, fileName.LastIndexOf(".")) : fileName;
                UploadAudioFiles audioFiles = new UploadAudioFiles()
                {
                    FileId = item.Additions,
                    FileName = item.FileName,
                    Name = strSubFileName,
                    Type = strSuffix,
                    Path = item.Path,
                    AllPath = item.AllPath
                };
                var id = await _uploadAudioFilesRepository.AddAsync(audioFiles, HttpContext.RequestAborted);
                if (!string.IsNullOrEmpty(id))
                    successNum++;
                else
                    errorNum++;

            }
            return new
            {
                successNum = successNum,
                errorNum = errorNum
            };
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="Ids"></param>
        /// <returns></returns>
        [HttpGet("deleteuploadaudiofiles")]
        public async Task DeleteUploadAudioFiles([FromQuery] List<string> Ids)
        {
            if (Ids == null || Ids.Count == 0)
                throw UserFriendlyException.SameMessage("请选择需要删除的数据");
            foreach (var item in Ids)
            {
                await _uploadAudioFilesRepository.RemoveAsync(p => p.Id == item, false, HttpContext.RequestAborted);
            }
        }

        /// <summary>
        /// 查询列表
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpGet("getaudiofileslist")]
        public async Task<PagedDto<UploadAudioFilesRequestDto>> GetAudioFilesList([FromQuery] PagedKeywordRequest dto)
        {
            var (total, items) = await _uploadAudioFilesRepository.Queryable()
                .Where(p => p.CreationTime >= dto.StartTime && p.CreationTime <= dto.EndTime)
                .WhereIF(!string.IsNullOrEmpty(dto.Keyword), p => p.Name.Contains(dto.Keyword))
                .OrderByIF(dto is { SortField: "creationTime", SortRule: 0 }, d => d.CreationTime, OrderByType.Asc) //创建时间升序
                .OrderByIF(dto is { SortField: "creationTime", SortRule: 1 }, d => d.CreationTime, OrderByType.Desc) //创建时间降序
                 .ToPagedListAsync(dto, HttpContext.RequestAborted);

            return new PagedDto<UploadAudioFilesRequestDto>(total, _mapper.Map<IReadOnlyList<UploadAudioFilesRequestDto>>(items));
        }

        /// <summary>
        /// 查询列表导出
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("getaudiofileslist/export")]
		[LogFilterAlpha("导出日志")]
		public async Task<FileStreamResult> ExportGetAudioFilesList([FromBody] ExportExcelDto<PagedKeywordRequest> dto)
        {
            var query = _uploadAudioFilesRepository.Queryable()
                .Where(p => p.CreationTime >= dto.QueryDto.StartTime && p.CreationTime <= dto.QueryDto.EndTime)
                .WhereIF(!string.IsNullOrEmpty(dto.QueryDto.Keyword), p => p.Name.Contains(dto.QueryDto.Keyword))
                .OrderByIF(dto.QueryDto is { SortField: "creationTime", SortRule: 0 }, d => d.CreationTime, OrderByType.Asc) //创建时间升序
                .OrderByIF(dto.QueryDto is { SortField: "creationTime", SortRule: 1 }, d => d.CreationTime, OrderByType.Desc);//创建时间降序

            List<UploadAudioFiles> lists;
            if (dto.IsExportAll)
            {
                lists = await query.ToListAsync(HttpContext.RequestAborted);
            }
            else
            {
                var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
                lists = items;
            }

            var listDtos = _mapper.Map<ICollection<UploadAudioFilesRequestDto>>(lists);

            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass<UploadAudioFilesRequestDto>(dto.ColumnInfos);

            var dtos = listDtos
                .Select(stu => _mapper.Map(stu, typeof(UploadAudioFilesRequestDto), dynamicClass))
                .Cast<object>()
                .ToList();

            var stream = ExcelHelper.CreateStream(dtos);

            return ExcelStreamResult(stream, "录音上传数据导出");

        }

        #endregion
    }
}
