using HiTeachCC.Model.Core.Models;
using HiTeachCC.Service.Core.Interface;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using PdfSharpCore.Pdf;
using PdfSharpCore.Pdf.IO;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using TEAMModelOS.SDK.Context.Configuration;
using TEAMModelOS.SDK.Context.Constant.Common;
using TEAMModelOS.SDK.Context.Exception;
using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
using TEAMModelOS.SDK.Helper.Common.JsonHelper;
using TEAMModelOS.SDK.Helper.Network.HttpHelper;
using TEAMModelOS.SDK.Helper.Security.ShaHash;
using TEAMModelOS.SDK.Module.AzureBlob.Container;
using TEAMModelOS.SDK.Module.AzureBlob.Interfaces;
using TEAMModelOS.SDK.Module.PowerPointX;
using TEAMModelOS.SDK.Module.PowerPointX.Model;

namespace HiTeachCC.Service.Core.Implement
{
    public class FileService : BaseService, IFileService
    {

        private readonly IAzureBlobDBRepository azureBlobDBRepository;

        public FileService(IAzureBlobDBRepository _azureBlobDBRepository) {
            azureBlobDBRepository = _azureBlobDBRepository;
        }
        public async Task<Dictionary<string, object>> UploadDocument(IFormFile file)
        {
            Dictionary<string, object> resdict = new Dictionary<string, object>();
           
            if (FileType.GetExtention(file.FileName).ToLower().Equals("pptx"))
            {


                 await ProcessPPT(file, resdict);
                return resdict;
            }
            else if (FileType.GetExtention(file.FileName).ToLower().Equals("pdf"))
            {
                PdfDocument inputDocument = PdfSharpCore.Pdf.IO.PdfReader.Open(file.OpenReadStream(), PdfDocumentOpenMode.Import);
                int count = inputDocument.PageCount;
                int limit = BaseConfigModel.Configuration.GetSection("HABOOKConfig:PDFLimit").Get<int>();
                if (count > limit)
                {
                    throw new BizException(500, "PDF file cannot exceed " + limit + " pages!");
                }
                await ProcessPDF(file, resdict);
                resdict.Add("page", count);
                return resdict;
            }
            else {
                throw new BizException(500, "file type does not support!");
            }
        }

        private async Task ProcessPDF(IFormFile file, Dictionary<string, object> resdict)
        {
            string shaCode = ShaHashHelper.GetSHA1(file.OpenReadStream());
            Dictionary<string, object> dict = new Dictionary<string, object> { { "Sha1Code", shaCode } };
            List<AzureBlobModel> models = await FindListByDict<AzureBlobModel>(dict);
            if (models.IsNotEmpty())
            {
                resdict.Add("model", models[0]);
                resdict.Add("type", "pdf");
            }
            else
            {
                AzureBlobModel azureBlobModel = await azureBlobDBRepository.UploadFile(file, "pdffiles", true);
                azureBlobModel.Sha1Code = shaCode;
                await SaveOrUpdate<AzureBlobModel>(azureBlobModel);
                azureBlobModel.Sha1Code = shaCode;
                resdict.Add("model", azureBlobModel);
                resdict.Add("type", "pdf");
            }
        }
        private async Task ProcessPPT(IFormFile file, Dictionary<string, object> resdict)
        {
            string shaCode = ShaHashHelper.GetSHA1(file.OpenReadStream());
            Dictionary<string, object> dict = new Dictionary<string, object> { { "Sha1Code", shaCode } };

            List<AzureBlobModel> models = await FindListByDict<AzureBlobModel>(dict);
            PPTXInfo info;
            if (models.IsNotEmpty())
            {
                List<PPTData> pptData = await FindListByDict<PPTData>(dict);
                var pptxjson = HttpHelper.HttpGet(pptData[0].DataUrl);
                info = JsonSerialization.FromJsonAbs<PPTXInfo>(pptxjson);
                resdict.Add("pptx", info);
                resdict.Add("model", models[0]);
                resdict.Add("type", "pptx");
            }
            else
            {
                AzureBlobModel azureBlobModel = await azureBlobDBRepository.UploadFile(file, "pptfiles", true);
                azureBlobModel.Sha1Code = shaCode;
                await SaveOrUpdate<AzureBlobModel>(azureBlobModel);
                PresentationConvert convert = new PresentationConvert();
                info = convert.LoadPresentation(file.OpenReadStream());
                AzureBlobModel pptJsonFileModel = await azureBlobDBRepository.UploadObject(shaCode + ".json", info, "pptfiles", true);
                PPTData pptData = new PPTData { DataUrl = pptJsonFileModel.BlobUrl, Sha1Code = shaCode, RowKey = shaCode, PartitionKey = "pptfiles" };
                await SaveOrUpdate<PPTData>(pptData);
                resdict.Add("pptx", info);
                resdict.Add("model", azureBlobModel);
                resdict.Add("type", "pptx");
            }
        }
    }
}
