using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using GxPress.Auth;
using GxPress.Common.Exceptions;
using GxPress.Common.Tools;
using GxPress.Entity;
using GxPress.Repository.Interface;
using GxPress.Request.App.FileLibrary;
using GxPress.Result.App.FileLibrary;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using GxPress.Service.Interface.FileLibrary;
using GxPress.Repository.Interface.VerificationCode;
using Datory;

namespace GxPress.Api.AppControllers
{
    [Route("api/app/file")]
    [ApiController]
    [Authorize]
    public class FileController : ControllerBase
    {
        private readonly IWebHostEnvironment _environment;
        private readonly IFileLibraryRepository _fileLibraryRepository;
        private readonly IFileLibraryService fileLibraryService;
        private readonly ILoginContext _loginContext;
        private readonly IVerificationCodeRepository verificationCodeRepository;
        public FileController(IWebHostEnvironment environment, IFileLibraryRepository fileLibraryRepository, ILoginContext loginContext, IFileLibraryService fileLibraryService, IVerificationCodeRepository verificationCodeRepository)
        {
            _environment = environment;
            _fileLibraryRepository = fileLibraryRepository;
            _loginContext = loginContext;
            this.fileLibraryService = fileLibraryService;
            this.verificationCodeRepository = verificationCodeRepository;
        }

        /// <summary>
        /// App上传
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("upload")]
        public async Task<ResultPath> Upload(IFormFile file)
        {
            if (file == null) throw new BusinessException("请选择需要上传的文件");
            byte[] bytes;
            await using (var ms = new MemoryStream())
            {
                file.CopyTo(ms);
                bytes = ms.ToArray();
            }
            var saveResult = FileHelper.SaveFile(StringUtils.GetWebRootPath(_environment.WebRootPath), file.FileName,
                bytes);
            saveResult.AbsolutePath = "https://" + Request.Host.Host +
                                      (Request.Host.Port > 0 ? $":{Request.Host.Port}" : string.Empty) +
                                      saveResult.RelativePath;
            saveResult.FileName = file.FileName;
            saveResult.FileType = saveResult.FileName.Split('.')[saveResult.FileName.Split('.').Length - 1];
            //图片种类
            string imageType =
                "bmp,jpg,jpeg,png,tif,gif,pcx,tga,exif,fpx,svg,psd,cdr,pcd,dxf,ufo,eps,ai,raw,wmf,webp";
            var imageTypeList = StringUtils.StringCollectionToStringList(imageType);
            if (imageTypeList.Contains(saveResult.FileType.ToLower()))
            {
                saveResult.FileType = "image";
                saveResult.MinAbsolutePath = StringUtils.AddDomainMin(saveResult.RelativePath);
            }
            //添加
            var fileLibrary = new FileLibrary
            {
                FileName = saveResult.FileName,
                FileType = saveResult.FileType,
                FileUrl = saveResult.RelativePath,
                UserId = 0,
                Size = file.Length
            };
            saveResult.Size = file.Length;
            saveResult.FileId = await fileLibraryService.InsertAsync(fileLibrary);
            return saveResult;
        }

        /// <summary>
        /// App多文件上传
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        [HttpPost("uploads")]
        [AllowAnonymous]
        public async Task<List<ResultPath>> Uploads(List<IFormFile> file)
        {
            if (file == null) throw new BusinessException("请选择需要上传的文件");
            List<ResultPath> result = new List<ResultPath>();
            foreach (var item in file)
            {
                byte[] bytes;
                await using (var ms = new MemoryStream())
                {
                    item.CopyTo(ms);
                    bytes = ms.ToArray();
                }

                var saveResult = FileHelper.SaveFile(StringUtils.GetWebRootPath(_environment.WebRootPath), item.FileName,
                    bytes);
                saveResult.AbsolutePath = "https://" + Request.Host.Host +
                                          (Request.Host.Port > 0 ? $":{Request.Host.Port}" : string.Empty) +
                                          saveResult.RelativePath;
                saveResult.FileName = item.FileName;
                saveResult.FileType = item.FileName.Split('.')[item.FileName.Split('.').Length - 1];
                //图片种类
                string imageType =
                    "bmp,jpg,jpeg,png,tif,gif,pcx,tga,exif,fpx,svg,psd,cdr,pcd,dxf,ufo,eps,ai,raw,wmf,webp";
                var imageTypeList = StringUtils.StringCollectionToStringList(imageType);
                if (imageTypeList.Contains(saveResult.FileType.ToLower()))
                {
                    saveResult.MinAbsolutePath = StringUtils.AddDomainMin(saveResult.RelativePath);
                    if (saveResult.FileType.ToLower() == "webp")
                        saveResult = Common.Tools.FileHelper.WebPToImage(StringUtils.GetWebRootPath(_environment.WebRootPath), item.FileName, saveResult, Request.Scheme + "://" + Request.Host.Host +
                                          (Request.Host.Port > 0 ? $":{Request.Host.Port}" : string.Empty));
                    saveResult.FileType = "image";
                }
                //添加
                var fileLibrary = new FileLibrary
                {
                    FileName = saveResult.FileName,
                    FileType = saveResult.FileType,
                    FileUrl = saveResult.RelativePath,
                    UserId = 0,
                    Size = item.Length
                };
                saveResult.Size = item.Length;
                saveResult.FileId = await _fileLibraryRepository.InsertAsync(fileLibrary);
                result.Add(saveResult);
            }

            return result;
        }


        /// <summary>
        /// 根据ID查询文件数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("{id}")]
        public async Task<FileLibraryResult> GetFileLibraryById(int id)
        {
            return await _fileLibraryRepository.GetFileLibraryByIdAsync(id);
        }

        /// <summary>
        /// 根据ID获取文件数据
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        [HttpPost("find")]
        public async Task<IEnumerable<FileLibraryResult>> GetFileLibraryByIds([FromBody] GetFileLibraryByIdsRequest ids)
        {
            return await _fileLibraryRepository.GetFileLibraryByIdsAsync(ids.FileLibraryByIds);
        }

        /// <summary>
        /// App多文件上传
        /// </summary>
        /// <param name="file"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        [HttpPost("upload-files")]
        [AllowAnonymous]
        public async Task<List<ResultPath>> UploadFiles(List<IFormFile> file, [FromForm] string code)
        {
            if (string.IsNullOrWhiteSpace(code))
                throw new BusinessException("code无效或为空值");
            if (file == null) throw new BusinessException("请选择需要上传的文件");
            //获取verificationCode
            var verificationCode = await verificationCodeRepository.GetAsync(Q.Where(nameof(Entity.VerificationCode.VerificationCode.Code), code).OrderByDesc(nameof(Entity.VerificationCode.VerificationCode.CreatedDate)));
            if (verificationCode == null)
                throw new BusinessException("验证码无效");
            var verificationCodeTime = Convert.ToDateTime(verificationCode.CreatedDate).AddMinutes(verificationCode.ExpireTime);
            if (verificationCodeTime < DateTime.Now)
                throw new BusinessException("验证码已经过期");
            List<ResultPath> result = new List<ResultPath>();
            foreach (var item in file)
            {

                byte[] bytes;
                await using (var ms = new MemoryStream())
                {
                    item.CopyTo(ms);
                    bytes = ms.ToArray();
                }

                var saveResult = FileHelper.SaveFile(StringUtils.GetWebRootPath(_environment.WebRootPath), item.FileName,
                    bytes);
                saveResult.AbsolutePath = Request.Scheme + "://" + Request.Host.Host +
                                          (Request.Host.Port > 0 ? $":{Request.Host.Port}" : string.Empty) +
                                          saveResult.RelativePath;
                saveResult.FileName = item.FileName;
                saveResult.FileType = item.FileName.Split('.')[item.FileName.Split('.').Length - 1];
                //图片种类
                string imageType =
                    "bmp,jpg,jpeg,png,tif,gif,pcx,tga,exif,fpx,svg,psd,cdr,pcd,dxf,ufo,eps,ai,raw,wmf,webp";
                var imageTypeList = StringUtils.StringCollectionToStringList(imageType);
                if (imageTypeList.Contains(saveResult.FileType.ToLower()))
                {
                    saveResult.FileType = "image";
                    saveResult.MinAbsolutePath = StringUtils.AddDomainMin(saveResult.RelativePath);
                }
                //
                //添加
                var fileLibrary = new FileLibrary
                {
                    FileName = saveResult.FileName,
                    FileType = saveResult.FileType,
                    FileUrl = saveResult.RelativePath,
                    UserId = verificationCode.UserId,
                    Size = item.Length
                };
                saveResult.Size = item.Length;
                saveResult.FileId = await fileLibraryService.InsertAsync(fileLibrary);
                result.Add(saveResult);
            }

            return result;
        }
    }
}