using Back.Common;
using Back.Data.Contracts;
using Back.Data.Models;
using Microsoft.EntityFrameworkCore;
using Shared.DTOs;
using System;
using System.Diagnostics;
using System.Text;

namespace Back.Services
{
    public class ServBase
    {
      private readonly  IAsyncRepository<Pricing> _repoPricing;
        private readonly IAsyncRepository<Blog> _repoBlog;
        private readonly IAsyncRepository<Question> _repoQuestion;
        private readonly IAsyncRepository<SaleLead> _repoSaleLead;
        private readonly Service.Main _Taxtools;
        public ServBase(IAsyncRepository<Pricing> repoPricing,
            IAsyncRepository<Blog> repoBlog, IAsyncRepository<Question> repoQuestion
            , Service.Main taxtools, IAsyncRepository<SaleLead> repoSaleLead)
        {
            _repoPricing = repoPricing;
            _repoBlog = repoBlog;
            _repoQuestion = repoQuestion;
            _Taxtools = taxtools;
            _repoSaleLead = repoSaleLead;
        }
        public async Task<List<BasePriceDto>> GetBasePrice()
        {
            return await _repoPricing.GetAll().Select(x => new BasePriceDto
            {
                Price = x.Price,
                CalculationType = x.CalculationTypeID == 1 && x.PermissionID == 16 ? "هر ارسال"
                :x.CalculationTypeID== 1 && x.PermissionID != 16 ? "واحدی"
                : x.CalculationTypeID == 2 ? "نامحدود" : "روزانه",
                PermissionID=x.PermissionID,
            }).ToListAsync();
        }
        public async Task<PagingDto<BlogDto>> GetBlog(int PageIndex, int PageSize)
        {
            return await _repoBlog.Get(w=>w.Status).OrderByDescending(o=>o.ID)
                .Select(s=>new BlogDto
                {
                    Title = s.Title,
                    Date=s.Date,
                    ID=s.ID,
                    Photo=string.IsNullOrEmpty(s.Photo) ? "blog-SampleTitle.jpg" : s.Photo
                }).Paging(PageIndex, PageSize); ;
        }
        public async Task<PagingDto<QuestionDto>> GetQuestion(int PageIndex, int PageSize)
        {
            return await _repoQuestion.Get(w => w.Status)
                .Include(inc=>inc.questionCategory).OrderByDescending(o => o.ID)
                .Select(s => new QuestionDto
                {
                    Answer=s.Answer,
                    Category=s.questionCategory.Title,
                    Title=s.Title,
                    ID = s.ID   
                }).Paging(PageIndex, PageSize);
        }
        public async Task<BlogDtoFull?> GetBlogByID(int ID)
        {
            var result= await _repoBlog.Get(w => w.Status && w.ID==ID)
                .Select(s => new BlogDtoFull
                {
                    Title = s.Title,
                    Date = s.Date,
                    ID = s.ID,
                    Photo = string.IsNullOrEmpty(s.Photo) ? "blog-SampleTitle.jpg" : s.Photo,
                    Text=s.Text,
                    Time=s.Time
                }).FirstOrDefaultAsync();
            return result;
        }
        public async Task<TaxToolsDTO?> CreateCsrAndPrivateKey(CsrPrivateKeyDto model)
        {
            TaxToolsDTO taxTools = null;
            List<Service.PrmValue> values = new List<Service.PrmValue>()
            {
                new Service.PrmValue(){Prm="CN",Value=model.cn},
                   new Service.PrmValue(){Prm="serialNumber",Value=model.sn},
                        new Service.PrmValue(){Prm="O",Value="Non-Governmental"},
                          new Service.PrmValue(){Prm="3.OU",Value=model.company},
                            new Service.PrmValue(){Prm="2.OU",Value=model.company},
                              new Service.PrmValue(){Prm="1.OU",Value=model.company},
                                 new Service.PrmValue(){Prm="C",Value="IR"},
            };
            string msg = "";
            if (_Taxtools.CraeteCnfFile(values, ref msg))
            {
                if (_Taxtools.CreateCsrAndPrivateKey(model.cn, ref msg))
                {
                    taxTools = new TaxToolsDTO();
                    //خواندن
                    Stream stream = File.Open($"C:\\OpenSSL\\bin\\{model.cn}.Csr", FileMode.Open);
                    byte[] buffer = new byte[stream.Length];
                    stream.Read(buffer, 0, (int)stream.Length);
                    string csr = Encoding.UTF8.GetString(buffer);
                    stream.Flush();
                    stream.Close();
                    taxTools.Base64csr = Convert.ToBase64String(buffer);
                    taxTools.typecsr = "Csr";
                    stream = File.Open($"C:\\OpenSSL\\bin\\{model.cn}.key", FileMode.Open);
                    buffer = new byte[stream.Length];
                    stream.Read(buffer, 0, (int)stream.Length);
                    string key = Encoding.UTF8.GetString(buffer);
                    taxTools.Base64key = Convert.ToBase64String(buffer);
                    taxTools.typekey = "key";
                    stream.Flush();
                    stream.Close();

                    //_contextMongodb.InsertItem(new SysLog()
                    //{
                    //    TraceIdentifierID = _httpContextAccessor.HttpContext.TraceIdentifier,
                    //    Datetime = DateTime.Now.ConvertMiladiToShamsi(),
                    //    Method = $"{_httpContextAccessor.HttpContext.Request.Method}/{this.GetType().FullName}/CreateCsrAndPrivateKey",
                    //    Value = JsonConvert.SerializeObject(model),
                    //    Route = _httpContextAccessor.HttpContext.Request.Path,
                    //    Type = "User"
                    //});
                   await _repoSaleLead.AddAsync(new SaleLead
                    {
                        cn = model.cn,
                        company = model.company,
                        csr = csr,
                        Key = key,
                        Mobile = model.Mobile,
                        sn = model.sn
                    });
                }

            }

            if (string.IsNullOrEmpty(msg))
            {
                //_contextMongodb.InsertItem(new SysLog()
                //{
                //    TraceIdentifierID = _httpContextAccessor.HttpContext.TraceIdentifier,
                //    Datetime = DateTime.Now.ConvertMiladiToShamsi(),
                //    Method = $"{_httpContextAccessor.HttpContext.Request.Method}/{this.GetType().FullName}/CreateCsrAndPrivateKey",
                //    Value = msg,
                //    Route = _httpContextAccessor.HttpContext.Request.Path,
                //    Type = "ERROR"
                //});
            }

            return taxTools;
        }
        public async Task<PublicKeyDTO?> ReadPublicKeyFromCER(string modelfromBase64)
        {
            try
            {

           
            string name = $"{DateTime.Now.Year}{DateTime.Now.Month}{DateTime.Now.DayOfWeek}{DateTime.Now.Hour}{DateTime.Now.Minute}{DateTime.Now.Second}";
            string filePath = $"C:\\cer\\{name}.cer";
            Stream stream = System.IO.File.Open(filePath, FileMode.Create);
            var encoding = Convert.FromBase64String(modelfromBase64);
            stream.Write(encoding, 0, encoding.Length);
            stream.Flush();
            stream.Close();

            Process cmd = new Process();
            cmd.StartInfo.WorkingDirectory = Environment.CurrentDirectory + "C\\OpenSSL\\bin";
            cmd.StartInfo.FileName = "cmd.exe";
            cmd.StartInfo.RedirectStandardInput = true;
            cmd.StartInfo.RedirectStandardOutput = true;
            cmd.StartInfo.CreateNoWindow = true;
            cmd.StartInfo.UseShellExecute = false;
            cmd.Start();

            cmd.StandardInput.WriteLine($"openssl x509 -pubkey -noout -in {filePath}> {name}.txt");
            cmd.StandardInput.Flush();
            cmd.StandardInput.Close();
            cmd.WaitForExit();


            //خواندن
            stream = System.IO.File.Open($"C\\OpenSSL\\bin\\{name}.txt", FileMode.Open);
            byte[] buffer = new byte[stream.Length];
            stream.Read(buffer, 0, (int)stream.Length);
            string PublicKey = Encoding.UTF8.GetString(buffer);
            stream.Flush();
            stream.Close();

            //_contextMongodb.InsertItem(new SysLog()
            //{
            //    TraceIdentifierID = _httpContextAccessor.HttpContext.TraceIdentifier,
            //    Datetime = DateTime.Now.ConvertMiladiToShamsi(),
            //    Method = $"{_httpContextAccessor.HttpContext.Request.Method}/{this.GetType().FullName}/ReadPublicKeyFromCER",
            //    Value = modelfromBase64,
            //    Route = _httpContextAccessor.HttpContext.Request.Path,
            //    Type = "User"
            //});
            return new PublicKeyDTO
            {
                PublicKeyBase64 = Convert.ToBase64String(buffer),
                type = "txt"
            };
            }
            catch (Exception)
            {
                return new PublicKeyDTO
                {
                    PublicKeyBase64 = "error",
                    type = "error"
                };
            }
        }
    }
}
