using System;
using System.IO;
using System.Threading.Tasks;
using GxPress.Auth;
using GxPress.Common.Exceptions;
using GxPress.Repository.Interface.Media;
using GxPress.Request.Media;
using GxPress.Result.Media;
using GxPress.Service.Interface.Media;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Net.Http.Headers;
using GxPress.Repository.Interface.Order;
using System.Collections.Generic;
using GxPress.EnumConst;
using GxPress.Common.Tools;

namespace GxPress.Api.WebControllers
{
    /// <summary>
    /// 媒体
    /// </summary>
    [Route("api/web/media")]
    [ApiController]
    [Authorize]
    public class WebMediaController : Controller
    {
        private readonly IMediaRepository mediaRepository;
        private readonly ILoginContext _loginContext;
        private readonly IMediaService mediaService;
        private IHttpContextAccessor _contextAccessor;
        private readonly IMediaLibraryRepository mediaLibraryRepository;
        private HttpContext _context { get { return _contextAccessor.HttpContext; } }
        private readonly IOrderRepository orderRepository;
        public WebMediaController(IMediaRepository mediaRepository, ILoginContext _loginContext, IMediaService mediaService, IHttpContextAccessor contextAccessor, IMediaLibraryRepository mediaLibraryRepository, IOrderRepository orderRepository)
        {
            this.mediaRepository = mediaRepository;
            this._loginContext = _loginContext;
            this.mediaService = mediaService;
            _contextAccessor = contextAccessor;
            this.mediaLibraryRepository = mediaLibraryRepository;
            this.orderRepository = orderRepository;
        }
        /// <summary>
        /// 详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("{id}")]
        [AllowAnonymous]
        public async Task<MediaResult> GetAsync(int id)
        {

            return await mediaService.GetAsync(id);
        }
        /// <summary>
        /// 书籍详情
        /// /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("book/{id}")]
        [AllowAnonymous]
        public async Task<BookMediaResult> GetBookMediaResult(int id)
        {
            var result = await mediaService.GetBookMediaResultAsync(id, _loginContext.AccountId);
            if (_loginContext.AccountId > 0 && result.FreeProportion == 0)
                result.IsBuy = true;
            else if (_loginContext.AccountId > 0)
                result.IsBuy = await orderRepository.GetExistsAsync(_loginContext.AccountId, id);
            return result;
        }
        /// <summary>
        /// 获取视频详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("video/{id}")]
        [AllowAnonymous]
        public async Task<VideoMediaResult> GetVideoMediaResultAsync(int id)
        {
            var result = await mediaService.GetVideoMediaResultAsync(id);
            if (_loginContext.AccountId > 0 && result.FreeProportion == 0)
                result.IsBuy = true;
            else if (_loginContext.AccountId > 0)
                result.IsBuy = await orderRepository.GetExistsAsync(_loginContext.AccountId, id);
            return result;
        }
        /// <summary>
        /// 获取章节内容
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost("book/content")]
        [AllowAnonymous]
        public async Task<string> GetBookMediaContentResultAsync(BookCatalogRequest request)
        {
            request.UserId = _loginContext.AccountId;
            return await mediaService.GetBookMediaContentResultAsync(request);
        }
        /// <summary>
        /// 分页视频流
        /// </summary>
        /// <returns></returns>
        [HttpPost("video")]
        [AllowAnonymous]
        public async Task<IActionResult> Video(VideoMediaFileStreamRequest request)
        {
            //获取文件
            // var mediaLibrary = await mediaLibraryRepository.GetAsync(request.MediaLibraryId);
            var filepath = "wwwroot" + "/cache/20200529/456789.mp4";
            //获取文件流
            var stream = System.IO.File.OpenRead(filepath);
            return new FileStreamResult(stream, new MediaTypeHeaderValue("video/mp4")) { EnableRangeProcessing = true };
        }

        /// <summary>
        /// 分页视频流
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [AllowAnonymous]
        public async Task<IActionResult> GetVideo(VideoMediaFileStreamRequest request)
        {
            var range = Request.Headers["Range"].ToString().Replace("bytes=", "");
            try
            {
                if (request.MediaLibraryId == 0)
                    throw new BusinessException("不存在");
                if (string.IsNullOrEmpty(range))
                    throw new BusinessException("服务器异常");
                //获取文件
                var mediaLibrary = await mediaLibraryRepository.GetAsync(request.MediaLibraryId);
                var filepath = "wwwroot" + mediaLibrary.FileUrl;
                //var filepath = "http://localhost:83/cache/20200428/1588144602647614.mp4";
                //从第3个到第12个字节,共10个字节。(0是第一个字节)
                var begin = int.Parse(range.Split('-')[0]);
                var end = int.Parse(range.Split('-')[1]);
                var byteLength = (end - begin) + 1;
                var bytes = new byte[byteLength];
                //var fristBytes = new byte[1024];
                FileInfo fileInfo = new FileInfo(filepath);
                //获取后缀名
                var ext = fileInfo.Extension;
                new FileExtensionContentTypeProvider().Mappings.TryGetValue(ext, out var contenttype);
                //获取文件流
                StreamReader stream = new StreamReader(System.IO.File.OpenRead(filepath));
                //stream.BaseStream.Read(fristBytes, 0, 1024);
                stream.BaseStream.Seek(begin, SeekOrigin.Begin);
                stream.BaseStream.Read(bytes, 0, byteLength);
                stream.Close();
                //var newBytes = new byte[fristBytes.Length + bytes.Length];
                // fristBytes.CopyTo(newBytes, 0);
                // bytes.CopyTo(newBytes, fristBytes.Length);
                _context.Response.Headers.Add(HeaderNames.AcceptRanges, "bytes");
                _context.Response.Headers.Add(HeaderNames.ContentRange, $"bytes {Request.Headers["Range"].ToString()}/{fileInfo.Length}");
                _context.Response.StatusCode = 206;
                var actionResult = File(bytes, contenttype ?? "application/octet-stream", fileInfo.Name);
                return actionResult;
            }
            catch (Exception ex)
            {
                throw new BusinessException($"{ex.Message}");
            }
        }
        /// <summary>
        /// 分页视频流
        /// </summary>
        /// <returns></returns>
        [HttpHead("header/{id}")]
        [AllowAnonymous]
        public async Task<IActionResult> GetVideoInfo(int id)
        {
            try
            {
                var mediaLibrary = await mediaLibraryRepository.GetAsync(id);
                var filepath = "wwwroot" + mediaLibrary.FileUrl;
                FileInfo fileInfo = new FileInfo(filepath);
                byte[] bytsize = new byte[fileInfo.Length];
                var ext = fileInfo.Extension;
                new FileExtensionContentTypeProvider().Mappings.TryGetValue(ext, out var contenttype);
                var actionResult = File(bytsize, contenttype ?? "application/octet-stream", fileInfo.Name);
                return actionResult;
            }
            catch (FileNotFoundException e)
            {
                throw new Common.Exceptions.BusinessException(e.Message);
            }
            catch (IOException e)
            {
                throw new Common.Exceptions.BusinessException(e.Message);
            }
        }
        [HttpGet("html")]
        [AllowAnonymous]
        public string GetHtmlUrl()
        {
            var str = @"wwwroot/123456.txt";
            return Common.Tools.HtmlAgilityPackHelper.GetHmtlContent(str);
        }
        /// <summary>
        /// 排行榜
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost("ranking-list")]
        [AllowAnonymous]
        public async Task<RankingListCategoryResult> GetRankingListResults(RankingListRequest request)
        {
            var result = new RankingListCategoryResult();
            result.RankingListResults = await mediaRepository.GetRankingListResults(request);
            foreach (var item in result.RankingListResults)
                item.ImageUrls = StringUtils.AddDomain(item.ImageUrls);
            result.Category = new Dictionary<int, string>();
            Type t = typeof(RankingListConst);
            Array arrays = Enum.GetValues(t);
            for (int i = 0; i < arrays.LongLength; i++)
            {
                RankingListConst test = (RankingListConst)arrays.GetValue(i);
                result.Category.Add((int)test, test.GetDescriptionOriginal());
            }
            return result;
        }

    }
}