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;

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;

        public FileController(
            ISessionContext sessionContext,
            IMapper mapper,
            ISystemDicDataCacheManager sysDicDataCacheManager,
            IRepository<File.File> fileRepository,
            ILogger<FileController> logger)
        {
            _sessionContext = sessionContext;
            _mapper = mapper;
            _sysDicDataCacheManager = sysDicDataCacheManager;
            _fileRepository = fileRepository;
            _logger = logger;
        }
        #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);
        }
    }
}
