using AutoMapper;
using DamageAssesment.Api.DocuLinks.Db;
using DamageAssesment.Api.DocuLinks.Interfaces;
using DamageAssesment.Api.DocuLinks.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.Eventing.Reader;
using System.Reflection.Metadata;
using System.Runtime.CompilerServices;
using System.Xml;
using System.Xml.Linq;

namespace DamageAssesment.Api.DocuLinks.Providers
{


    public class DoculinkProvider : IDoculinkProvider
    {
        private DoculinkDbContext DocumentDbContext;
        private ILogger<DoculinkProvider> logger;
        private IUploadService uploadservice;
        private IAzureBlobService azureBlobService;
        private IMapper mapper;
        private readonly IHttpContextAccessor httpContextAccessor;
        private string baseUrl;

        public DoculinkProvider(DoculinkDbContext DocumentDbContext, ILogger<DoculinkProvider> logger, IMapper mapper, IUploadService uploadservice, IAzureBlobService azureBlobService, IHttpContextAccessor httpContextAccessor)
        {
            this.DocumentDbContext = DocumentDbContext;
            this.logger = logger;
            this.mapper = mapper;
            this.uploadservice = uploadservice;
            this.httpContextAccessor = httpContextAccessor;
            baseUrl = $"{httpContextAccessor.HttpContext.Request.Scheme}://{httpContextAccessor.HttpContext.Request.Host}";
            baseUrl = baseUrl + "/doculinks/download";
            this.azureBlobService = azureBlobService;
            //SeedData();
        }



        private async Task SeedDataAsync()
        {
            if (!DocumentDbContext.LinkTypes.Any())
            {
                DocumentDbContext.LinkTypes.Add(new Db.LinkType() { IsActive = true, CustomOrder = 1 });
                DocumentDbContext.LinkTypes.Add(new Db.LinkType() { IsActive = true, CustomOrder = 2 });
                DocumentDbContext.LinkTypes.Add(new Db.LinkType() { IsActive = true, CustomOrder = 3 });
                DocumentDbContext.LinkTypes.Add(new Db.LinkType() { IsActive = true, CustomOrder = 4 });
                DocumentDbContext.SaveChanges();
            }
            if (!DocumentDbContext.LinksTranslations.Any())
            {
                DocumentDbContext.LinksTranslations.Add(new Db.LinksTranslation() { TypeText = "Forms", Language = "en", LinkTypeId = 1 });
                DocumentDbContext.LinksTranslations.Add(new Db.LinksTranslation() { TypeText = "Communiques", Language = "en", LinkTypeId = 2 });
                DocumentDbContext.LinksTranslations.Add(new Db.LinksTranslation() { TypeText = "Memos", Language = "en", LinkTypeId = 3 });
                DocumentDbContext.LinksTranslations.Add(new Db.LinksTranslation() { TypeText = "Trainings", Language = "en", LinkTypeId = 4 });
                DocumentDbContext.LinksTranslations.Add(new Db.LinksTranslation() { TypeText = "Formularios", Language = "es", LinkTypeId = 1 });
                DocumentDbContext.LinksTranslations.Add(new Db.LinksTranslation() { TypeText = "Comunicados", Language = "es", LinkTypeId = 2 });
                DocumentDbContext.LinksTranslations.Add(new Db.LinksTranslation() { TypeText = "notas", Language = "es", LinkTypeId = 3 });
                DocumentDbContext.LinksTranslations.Add(new Db.LinksTranslation() { TypeText = "Entrenamientos", Language = "es", LinkTypeId = 4 });
                DocumentDbContext.LinksTranslations.Add(new Db.LinksTranslation() { TypeText = "Formes", Language = "fr", LinkTypeId = 1 });
                DocumentDbContext.LinksTranslations.Add(new Db.LinksTranslation() { TypeText = "Communiqués", Language = "fr", LinkTypeId = 2 });
                DocumentDbContext.LinksTranslations.Add(new Db.LinksTranslation() { TypeText = "Mémos", Language = "fr", LinkTypeId = 3 });
                DocumentDbContext.LinksTranslations.Add(new Db.LinksTranslation() { TypeText = "Formations", Language = "fr", LinkTypeId = 4 });
                DocumentDbContext.SaveChanges();
            }
            if (!DocumentDbContext.Documents.Any())
            {
                int counter = 0;
                for (int i = 1; i <= 4; i++)
                {
                    int linkTypeId = 2;
                    FileModel fileModel = new FileModel();
                    if (i < 3)
                    {
                        linkTypeId = 1;

                        fileModel = new FileModel() { FileName = "Sample" + i, FileExtension = ".txt", FileContent = "c2FtcGxl", IsAttachments = true, CustomOrder = 1, Language = "en"  };
                    }
                    else
                        fileModel = new FileModel() { url = "www.google" + i + ".com", IsAttachments = false, CustomOrder = 1,Language="en" };
                    ReqDoculink documentInfo = new ReqDoculink() { linkTypeId = i, CustomOrder = i, Files = new List<FileModel>() { fileModel } };
                    Models.Doculink document = uploadservice.UploadDocument(counter, documentInfo);
                    DocumentDbContext.Documents.Add(mapper.Map<Models.Doculink, Db.Doculink>(document));
                    DocumentDbContext.SaveChanges();
                    var dbattachments = mapper.Map<List<Models.DoculinkAttachments>, List<Db.DoculinkAttachments>>(document.doclinksAttachments);
                    dbattachments.ForEach(a => a.DocumentId = i);
                    DocumentDbContext.DoclinksAttachments.AddRange(dbattachments);
                    DocumentDbContext.SaveChanges();
                    counter++;
                }
            }
            if (!DocumentDbContext.DocumentsTranslations.Any())
            {
                string[] titles = {
                         "Mobile App Damage Assessment Instructions",
                         "PC Damage Assessment Instructions",
                         "Emergency Evacuation centers",
                         "Mobile App Damage Assessment Instructions" };
                string[] esTranslations = {
                         "Instrucciones de Evaluación de Daños de la Aplicación Móvil",
                         "Instrucciones de Evaluación de Daños del PC",
                         "Centros de Evacuación de Emergencia",
                         "Instrucciones de Evaluación de Daños de la Aplicación Móvil"  };
                string[] frTranslations = {
                      "Instructions d'Évaluation des Dommages de l'Application Mobile",
                      "Instructions d'Évaluation des Dommages du PC",
                       "Centres d'Évacuation d'Urgence",
                       "Instructions d'Évaluation des Dommages de l'Application Mobile" };
                List<Db.DoculinkTranslation> documents = new List<Db.DoculinkTranslation>();
                for (int i = 0; i < 4; i++)
                {
                    documents.Add(new Db.DoculinkTranslation { DocumentId = i + 1, title = titles[i], description = titles[i], Language = "en" });
                    documents.Add(new Db.DoculinkTranslation { DocumentId = i + 1, title = esTranslations[i], description = esTranslations[i], Language = "es" });
                    documents.Add(new Db.DoculinkTranslation { DocumentId = i + 1, title = frTranslations[i], description = frTranslations[i], Language = "fr" });
                }
                DocumentDbContext.DocumentsTranslations.AddRange(documents);
                DocumentDbContext.SaveChanges();
            }

        }
        public List<Models.DoculinkTranslation> GetDocumentTranslations(int id, string? language)
        {
            List<Models.DoculinkTranslation> QuestionTranslations;
            if (string.IsNullOrEmpty(language))
            {
                QuestionTranslations = mapper.Map<List<Db.DoculinkTranslation>, List<Models.DoculinkTranslation>>(
                    DocumentDbContext.DocumentsTranslations.AsNoTracking().Where(a => a.DocumentId == id).ToList());
            }
            else
            {
                QuestionTranslations = mapper.Map<List<Db.DoculinkTranslation>, List<Models.DoculinkTranslation>>(
                DocumentDbContext.DocumentsTranslations.AsNoTracking().Where(a => a.DocumentId == id && a.Language == language).ToList());
            }
            return QuestionTranslations;
        }
        public ResDoculink CreateMultiLanguageObject(List<Models.DoculinkTranslation> questions)
        {
            ResDoculink MultiLanguage = new ResDoculink();
            Dictionary<string, string> dicttitle = new Dictionary<string, string>();
            Dictionary<string, string> dictdesc = new Dictionary<string, string>();
            foreach (Models.DoculinkTranslation item in questions)
            {
                dicttitle.Add(item.Language, item.title);
                dictdesc.Add(item.Language, item.description);
            }
            MultiLanguage.titles = dicttitle;
            MultiLanguage.description = dictdesc;
            return MultiLanguage;
        }
        public List<Models.LinksTranslation> GetLinkTypeTranslations(int id, string? language)
        {
            List<Models.LinksTranslation> linksTranslations;
            if (string.IsNullOrEmpty(language))
            {
                linksTranslations = mapper.Map<List<Db.LinksTranslation>, List<Models.LinksTranslation>>(
                    DocumentDbContext.LinksTranslations.AsNoTracking().Where(a => a.LinkTypeId == id).ToList());
            }
            else
            {
                linksTranslations = mapper.Map<List<Db.LinksTranslation>, List<Models.LinksTranslation>>(
                DocumentDbContext.LinksTranslations.AsNoTracking().Where(a => a.LinkTypeId == id && a.Language == language).ToList());
            }
            return linksTranslations;
        }
        public object CreateMultiLanguageLinkTypeObject(List<Models.LinksTranslation> links)
        {
            object MultiLanguage = new object();
            Dictionary<string, string> dicttitle = new Dictionary<string, string>();
            foreach (Models.LinksTranslation item in links)
            {
                dicttitle.Add(item.Language, item.TypeText);
            }
            MultiLanguage = dicttitle;
            return MultiLanguage;
        }
        private List<Models.DoculinkAttachments> GetDocumentAttachment(int id,string? language)
        {
            List<Db.DoculinkAttachments> doculinkAttachments = null;
            if (string.IsNullOrEmpty(language))
            {
                doculinkAttachments = DocumentDbContext.DoclinksAttachments.AsNoTracking().Where(a => a.DocumentId == id).ToList();
            }
            else
            {
                doculinkAttachments = DocumentDbContext.DoclinksAttachments.AsNoTracking().Where(a => a.DocumentId == id && a.Language == language).ToList();
            }
            foreach (var attachment in doculinkAttachments)
            {
                if (attachment.IsAttachments)
                    attachment.Path = $"{baseUrl}/{attachment.Id}";
            }
            return mapper.Map<List<Db.DoculinkAttachments>, List<Models.DoculinkAttachments>>(doculinkAttachments);
        }
        public async Task<(bool IsSuccess, Models.DoculinkAttachments DoculinkAttachments, string Path)> GetDownloadAttachmentAsync(int id)
        {
            try
            {
                Db.DoculinkAttachments Attachment = DocumentDbContext.DoclinksAttachments.AsNoTracking().Where(a => a.Id == id).AsNoTracking().FirstOrDefault();
                if (Attachment == null)
                {
                    return (false, null, "Not Found");
                }
                return (true, mapper.Map<Db.DoculinkAttachments, Models.DoculinkAttachments>(Attachment), $"Attachment {id}");
            }
            catch (Exception ex)
            {

                logger?.LogError(ex.ToString());
                return (false, null, ex.Message);
            }
        }
        public async Task<(bool IsSuccess, IEnumerable<Models.ResDoculink> documents, string ErrorMessage)> GetdocumentsByLinkTypeIdAsync(int? linkTypeId, string? language, bool? isactive)
        {

            try
            {
                logger?.LogInformation("Query Question");
                var documents = new List<Db.Doculink>();
                if (linkTypeId==null)
                    documents = await DocumentDbContext.Documents.AsNoTracking().Where(q => (isactive == null || q.IsActive == isactive.Value)).ToListAsync();
                else
                    documents = await DocumentDbContext.Documents.AsNoTracking().Where(q => (isactive == null || q.IsActive == isactive.Value) &&
                     q.linkTypeId == linkTypeId.Value).ToListAsync();
                if (documents != null)
                {
                    var result = mapper.Map<List<Db.Doculink>, List<Models.ResDoculink>>(documents);
                    foreach (var item in result)
                    {
                        var multilan = CreateMultiLanguageObject(GetDocumentTranslations(item.Id, language));
                        item.titles = multilan.titles;
                        item.description = multilan.description;
                        item.linktypes = CreateMultiLanguageLinkTypeObject(GetLinkTypeTranslations(item.linkTypeId, language));
                        item.doclinksAttachments = GetDocumentAttachment(item.Id,language);
                    }
                   // List<ResDoculinks> doculinks = result.GroupBy(a => a.linkTypeId).Select(a => new ResDoculinks() { linkTypeId = a.Key, doculinks = a.ToList() }).ToList();
                    return (true, result, null);
                }
                return (false, null, "Not found");
            }
            catch (Exception ex)
            {
                logger?.LogError(ex.ToString());
                return (false, null, ex.Message);
            }

        }
        public async Task<(bool IsSuccess, IEnumerable<Models.ResDoculink> documents, string ErrorMessage)> GetdocumentsByLinkAsync(string? linkType, string? language, bool? isactive)
        {

            try
            {
                logger?.LogInformation("Query Question");
                var documents = new List<Db.Doculink>();
                if (String.IsNullOrEmpty(linkType))
                    documents = await DocumentDbContext.Documents.AsNoTracking().Where(q => (isactive == null || q.IsActive == isactive.Value)).ToListAsync();
                else
                    documents = await DocumentDbContext.Documents.AsNoTracking().Where(q => (isactive == null || q.IsActive == isactive.Value) &&
                     q.linkTypeId == (DocumentDbContext.LinksTranslations.AsNoTracking().Where(a => a.TypeText.ToLower() == linkType.ToLower()).Select(a => a.Id).FirstOrDefault())).ToListAsync();
                if (documents != null)
                {
                    var result = mapper.Map<List<Db.Doculink>, List<Models.ResDoculink>>(documents);
                    foreach (var item in result)
                    {
                        var multilan = CreateMultiLanguageObject(GetDocumentTranslations(item.Id, language));
                        item.titles = multilan.titles;
                        item.description = multilan.description;
                        item.linktypes = CreateMultiLanguageLinkTypeObject(GetLinkTypeTranslations(item.linkTypeId, language));
                        item.doclinksAttachments = GetDocumentAttachment(item.Id, language);
                    }
                    //List<ResDoculinks> doculinks =  result.GroupBy(a => a.linkTypeId).Select(a => new ResDoculinks() { linkTypeId = a.Key, doculinks = a.ToList() }).ToList();
                    return (true, result, null);
                }
                return (false, null, "Not found");
            }
            catch (Exception ex)
            {
                logger?.LogError(ex.ToString());
                return (false, null, ex.Message);
            }

        }
        //public async Task<(bool IsSuccess, IEnumerable<Models.ResDoculink> documents, string ErrorMessage)> GetDocumnetsAsync(string? language)
        //{

        //    try
        //    {
        //        logger?.LogInformation("Query Question");
        //        var documents = await DocumentDbContext.Documents.Include(a => a.LinkType).AsNoTracking().Where(q => q.IsActive).ToListAsync();
        //        if (documents != null)
        //        {
        //            logger?.LogInformation($"{documents.Count} Document(s) found");
        //            var result = mapper.Map<List<Db.Document>, List<Models.ResDoculink>>(documents);
        //            foreach (var item in result)
        //            {
        //                var multilan = CreateMultiLanguageObject(GetDocumentTranslations(item.Id, language));
        //                item.titles = multilan.titles;
        //                item.description = multilan.description;
        //            }
        //            return (true, result, null);
        //        }
        //        return (false, null, "Not found");
        //    }
        //    catch (Exception ex)
        //    {
        //        logger?.LogError(ex.ToString());
        //        return (false, null, ex.Message);
        //    }

        //}
        public async Task<(bool IsSuccess, Models.Doculink Document, string ErrorMessage)> GetDocumentByidAsync(int id)
        {
            try
            {
                logger?.LogInformation("Query LinkType");
                var Document = await DocumentDbContext.Documents.AsNoTracking().FirstOrDefaultAsync(q => q.Id == id && q.IsActive);
                if (Document != null)
                {
                    logger?.LogInformation($"{Document} customer(s) found");
                    var result = mapper.Map<Db.Doculink, Models.Doculink>(Document);
                    result.documentsTranslations = mapper.Map<List<Db.DoculinkTranslation>, List<Models.DoculinkTranslation>>(
                            DocumentDbContext.DocumentsTranslations.Where(a => a.DocumentId == result.Id).ToList());

                    result.doclinksAttachments = GetDocumentAttachment(id, "");
                    return (true, result, null);
                }
                return (false, null, "Not found");
            }
            catch (Exception ex)
            {
                logger?.LogError(ex.ToString());
                return (false, null, ex.Message);
            }
        }
        //added linktype filter 
        public async Task<(bool IsSuccess, Models.ResDoculink Document, string ErrorMessage)> GetDocumentAsync(int id, string? linkType, string? language)
        {
            try
            {
                logger?.LogInformation("Query LinkType");
                //var Document = await DocumentDbContext.Documents.Include(a => a.LinkType).AsNoTracking().FirstOrDefaultAsync(q => q.Id == id && q.IsActive);
                var Document = new Db.Doculink();
                if (String.IsNullOrEmpty(linkType))
                    Document = await DocumentDbContext.Documents.AsNoTracking().Where(q => q.IsActive && q.Id == id).FirstOrDefaultAsync();
                else
                    Document = await DocumentDbContext.Documents.AsNoTracking().Where(q => q.IsActive && q.Id == id &&
                     q.linkTypeId == (DocumentDbContext.LinksTranslations.AsNoTracking().Where(a => a.TypeText.ToLower() == linkType.ToLower()).Select(a => a.Id).FirstOrDefault())).FirstOrDefaultAsync();
                if (Document != null)
                {
                    logger?.LogInformation($"{Document} customer(s) found");
                    var result = mapper.Map<Db.Doculink, Models.ResDoculink>(Document);
                    var multilan = CreateMultiLanguageObject(GetDocumentTranslations(result.Id, language));
                    result.linktypes = CreateMultiLanguageLinkTypeObject(GetLinkTypeTranslations(result.linkTypeId, language));
                    result.titles = multilan.titles;
                    result.description = multilan.description;
                    result.doclinksAttachments = GetDocumentAttachment(id, language);
                    return (true, result, null);
                }
                return (false, null, "Not found");
            }
            catch (Exception ex)
            {
                logger?.LogError(ex.ToString());
                return (false, null, ex.Message);
            }
        }
        public async Task<(bool IsSuccess, Models.ResDoculink Document, string ErrorMessage)> PostDocumentAsync(Models.Doculink Document)
        {
            try
            {
                var document = mapper.Map<Models.Doculink, Db.Doculink>(Document);
                document.dateCreated = DateTime.Now; document.dateUpdated = DateTime.Now;
                DocumentDbContext.Documents.Add(document);
                DocumentDbContext.SaveChanges();
                var dbtranslation = mapper.Map<List<Models.DoculinkTranslation>, List<Db.DoculinkTranslation>>(Document.documentsTranslations);
                dbtranslation.ForEach(i => i.DocumentId = document.Id);
                DocumentDbContext.DocumentsTranslations.AddRange(dbtranslation);
                var dbattachments = mapper.Map<List<Models.DoculinkAttachments>, List<Db.DoculinkAttachments>>(Document.doclinksAttachments);
                dbattachments.ForEach(i => i.DocumentId = document.Id);
                DocumentDbContext.DoclinksAttachments.AddRange(dbattachments);
                DocumentDbContext.SaveChanges();
                var result = mapper.Map<Db.Doculink, Models.ResDoculink>(document);
                var multilan = CreateMultiLanguageObject(GetDocumentTranslations(document.Id, ""));
                result.linktypes = CreateMultiLanguageLinkTypeObject(GetLinkTypeTranslations(Document.linkTypeId, ""));
                result.titles = multilan.titles;
                result.description = multilan.description;
                result.doclinksAttachments = GetDocumentAttachment(document.Id,"");
                return (true, result, null);
            }
            catch (Exception ex)
            {
                logger?.LogError(ex.ToString());
                return (false, null, ex.Message);
            }
        }

        public async Task<(bool IsSuccess, Models.ResDoculink Document, string ErrorMessage)> UpdateDocumentAsync(int id, Models.Doculink Document)
        {
            try
            {
                if (Document != null)
                {
                    var existing = DocumentDbContext.Documents.AsNoTracking().FirstOrDefault(x => x.Id == id);
                    if (existing != null)
                    {
                        Document.Id = existing.Id;
                        var document = mapper.Map<Models.Doculink, Db.Doculink>(Document);
                        document.dateUpdated = DateTime.Now;
                        DocumentDbContext.Documents.Update(document);
                        DocumentDbContext.SaveChanges();
                        var oldtranslations = DocumentDbContext.DocumentsTranslations.Where(a => a.DocumentId == id).ToList();
                        if (oldtranslations != null)
                            DocumentDbContext.DocumentsTranslations.RemoveRange(oldtranslations);
                        var oldattachments = DocumentDbContext.DoclinksAttachments.Where(a => a.DocumentId == id).ToList();
                        if (oldattachments != null)
                            DocumentDbContext.DoclinksAttachments.RemoveRange(oldattachments);
                        var dbtranslation = mapper.Map<List<Models.DoculinkTranslation>, List<Db.DoculinkTranslation>>(Document.documentsTranslations);
                        dbtranslation.ForEach(i => i.DocumentId = Document.Id);
                        DocumentDbContext.DocumentsTranslations.AddRange(dbtranslation);
                        var dbattachments = mapper.Map<List<Models.DoculinkAttachments>, List<Db.DoculinkAttachments>>(Document.doclinksAttachments);
                        dbattachments.ForEach(i => i.DocumentId = document.Id);
                        DocumentDbContext.DoclinksAttachments.AddRange(dbattachments);
                        DocumentDbContext.SaveChanges();
                        var result = mapper.Map<Db.Doculink, Models.ResDoculink>(document);
                        var multilan = CreateMultiLanguageObject(GetDocumentTranslations(document.Id, ""));
                        result.linktypes = CreateMultiLanguageLinkTypeObject(GetLinkTypeTranslations(document.linkTypeId, ""));
                        result.titles = multilan.titles;
                        result.description = multilan.description;
                        result.doclinksAttachments = GetDocumentAttachment(document.Id, "");
                        return (true, result, "Successful");
                    }
                    else
                    {
                        logger?.LogInformation($"{Document} Not found");
                        return (false, null, "Not Found");
                    }
                }
                else
                {
                    logger?.LogInformation($"{Document} Bad Request");
                    return (false, null, "Bad request");
                }

            }
            catch (Exception ex)
            {

                logger?.LogError(ex.ToString());
                return (false, null, ex.Message);
            }
        }
        public async Task<(bool IsSuccess, Models.ResDoculink Document, string ErrorMessage)> UpdateDocumentAsync(int id,bool isactive)
        {

            try
            {
                Db.Doculink Document = DocumentDbContext.Documents.AsNoTracking().Where(a => a.Id == id).FirstOrDefault();
                if (Document == null)
                {
                    return (false, null, "Not Found");
                }
                Document.IsActive = isactive;
                DocumentDbContext.Documents.Update(Document);
                DocumentDbContext.SaveChanges();
                var result = mapper.Map<Db.Doculink, Models.ResDoculink>(Document);
                var multilan = CreateMultiLanguageObject(GetDocumentTranslations(Document.Id, ""));
                result.titles = multilan.titles;
                result.description = multilan.description;
                result.linktypes = CreateMultiLanguageLinkTypeObject(GetLinkTypeTranslations(result.linkTypeId, ""));
                result.doclinksAttachments = mapper.Map<List<Db.DoculinkAttachments>, List<Models.DoculinkAttachments>>(
                    DocumentDbContext.DoclinksAttachments.AsNoTracking().Where(a => a.DocumentId == id).ToList());
                return (true, result, $"DocumentId {id} deleted Successfuly");
            }
            catch (Exception ex)
            {

                logger?.LogError(ex.ToString());
                return (false, null, ex.Message);
            }
        }
        public async Task<(bool IsSuccess, Models.ResDoculink Document, string ErrorMessage)> DeleteDocumentAsync(int id)
        {

            try
            {
                Db.Doculink Document = DocumentDbContext.Documents.AsNoTracking().Where(a => a.Id == id).FirstOrDefault();
                if (Document == null)
                {
                    return (false, null, "Not Found");
                }
                var result = mapper.Map<Db.Doculink, Models.ResDoculink>(Document);
                var multilan = CreateMultiLanguageObject(GetDocumentTranslations(Document.Id, ""));
                result.titles = multilan.titles;
                result.description = multilan.description;
                result.linktypes = CreateMultiLanguageLinkTypeObject(GetLinkTypeTranslations(result.linkTypeId, ""));
                result.doclinksAttachments = mapper.Map<List<Db.DoculinkAttachments>, List<Models.DoculinkAttachments>>(
                    DocumentDbContext.DoclinksAttachments.AsNoTracking().Where(a => a.DocumentId == id).ToList());
                Document.IsActive = false;
                DocumentDbContext.Documents.Update(Document);
                DocumentDbContext.SaveChanges();
                return (true, result, $"DocumentId {id} deleted Successfuly");
            }
            catch (Exception ex)
            {

                logger?.LogError(ex.ToString());
                return (false, null, ex.Message);
            }
        }

        public async Task<(bool IsSuccess, int counter, string message)> GetDocumentCounter()
        {
            try
            {
                int AttachmentId = DocumentDbContext.DoclinksAttachments.Max(a => a.Id);
                return (true, AttachmentId, "");
            }
            catch (Exception ex)
            {
                return (false, 0, ex.Message);
            }
        }

        //Link Type methods
        public async Task<(bool IsSuccess, IEnumerable<Models.ResLinkType> LinkTypes, string ErrorMessage)> GetLinkTypesAsync(string? language)
        {

            try
            {
                logger?.LogInformation("Query Question");
                var LinkType = await DocumentDbContext.LinkTypes.AsNoTracking().Where(q => q.IsActive).ToListAsync();
                if (LinkType != null)
                {
                    logger?.LogInformation($"{LinkType.Count} LinkTypes(s) found");
                    var result = mapper.Map<IEnumerable<Db.LinkType>, IEnumerable<Models.ResLinkType>>(LinkType);
                    foreach (var item in result)
                    {
                        item.titles = CreateMultiLanguageLinkTypeObject(GetLinkTypeTranslations(item.Id, language));
                    }
                    return (true, result, null);
                }
                return (false, null, "Not found");
            }
            catch (Exception ex)
            {
                logger?.LogError(ex.ToString());
                return (false, null, ex.Message);
            }

        }
        public async Task<(bool IsSuccess, Models.ResLinkType LinkType, string ErrorMessage)> GetLinkTypeAsync(int Id, string? language)
        {
            try
            {
                logger?.LogInformation("Query LinkType");
                var LinkType = await DocumentDbContext.LinkTypes.AsNoTracking().FirstOrDefaultAsync(q => q.Id == Id && q.IsActive);
                if (LinkType != null)
                {
                    logger?.LogInformation($"{LinkType} customer(s) found");
                    var result = mapper.Map<Db.LinkType, Models.ResLinkType>(LinkType);
                    result.titles = CreateMultiLanguageLinkTypeObject(GetLinkTypeTranslations(result.Id, language));
                    return (true, result, null);
                }
                return (false, null, "Not found");
            }
            catch (Exception ex)
            {
                logger?.LogError(ex.ToString());
                return (false, null, ex.Message);
            }
        }
        public async Task<(bool IsSuccess, Models.ResLinkType LinkType, string ErrorMessage)> PostLinkTypeAsync(Models.LinkType LinkType)
        {
            try
            {
                logger?.LogInformation("Query LinkType");
                if (!LinkTypeExists(LinkType.Id))
                {
                    var dbLink = mapper.Map<Models.LinkType, Db.LinkType>(LinkType);
                    DocumentDbContext.LinkTypes.Add(dbLink);
                    DocumentDbContext.SaveChanges();
                    var dbtranslation = mapper.Map<List<Models.LinksTranslation>, List<Db.LinksTranslation>>(LinkType.linksTranslations);
                    dbtranslation.ForEach(i => i.LinkTypeId = dbLink.Id);
                    DocumentDbContext.LinksTranslations.AddRange(dbtranslation);
                    DocumentDbContext.SaveChanges();
                    var result = mapper.Map<Db.LinkType, Models.ResLinkType>(dbLink);
                    result.titles = CreateMultiLanguageLinkTypeObject(GetLinkTypeTranslations(result.Id, ""));
                    return (true, result, null);
                }
                return (false, null, "LinkType is already exits");
            }
            catch (Exception ex)
            {
                logger?.LogError(ex.ToString());
                return (false, null, ex.Message);
            }
        }
        public async Task<(bool IsSuccess, Models.ResLinkType LinkType, string ErrorMessage)> UpdateLinkTypeAsync(int id, Models.LinkType LinkType)
        {
            try
            {
                if (LinkType != null)
                {
                    var existing = DocumentDbContext.LinkTypes.AsNoTracking().FirstOrDefault(x => x.Id == id);
                    if (existing != null)
                    {
                        var dbLink = mapper.Map<Models.LinkType, Db.LinkType>(LinkType);
                        DocumentDbContext.LinkTypes.Update(dbLink);
                        DocumentDbContext.SaveChanges();
                        var oldtranslations = DocumentDbContext.LinksTranslations.Where(a => a.LinkTypeId == id).ToList();
                        if (oldtranslations != null)
                            DocumentDbContext.LinksTranslations.RemoveRange(oldtranslations);
                        var dbtranslation = mapper.Map<List<Models.LinksTranslation>, List<Db.LinksTranslation>>(LinkType.linksTranslations);
                        dbtranslation.ForEach(i => i.LinkTypeId = dbLink.Id);
                        DocumentDbContext.LinksTranslations.AddRange(dbtranslation);
                        DocumentDbContext.SaveChanges();
                        var result = mapper.Map<Db.LinkType, Models.ResLinkType>(dbLink);
                        result.titles = CreateMultiLanguageLinkTypeObject(GetLinkTypeTranslations(result.Id, ""));
                        return (true, result, "Successful");
                    }
                    else
                    {
                        logger?.LogInformation($"{LinkType} Not found");
                        return (false, null, "Not Found");
                    }
                }
                else
                {
                    logger?.LogInformation($"{LinkType} Bad Request");
                    return (false, null, "Bad request");
                }

            }
            catch (Exception ex)
            {

                logger?.LogError(ex.ToString());
                return (false, null, ex.Message);
            }
        }
        public async Task<(bool IsSuccess, Models.ResLinkType LinkType, string ErrorMessage)> DeleteLinkTypeAsync(int id)
        {

            try
            {
                Db.LinkType LinkType = DocumentDbContext.LinkTypes.AsNoTracking().Where(a => a.Id == id).FirstOrDefault();
                if (LinkType == null)
                {
                    return (false, null, "Not Found");
                }
                LinkType.IsActive = false;
                var result = mapper.Map<Db.LinkType, Models.ResLinkType>(LinkType);
                result.titles = CreateMultiLanguageLinkTypeObject(GetLinkTypeTranslations(result.Id, ""));
                DocumentDbContext.LinkTypes.Update(LinkType);
                DocumentDbContext.SaveChanges();
                return (true, result, $"LinkTypeId {id} deleted Successfuly");
            }
            catch (Exception ex)
            {

                logger?.LogError(ex.ToString());
                return (false, null, ex.Message);
            }
        }
        private bool LinkTypeExists(int id)
        {
            return DocumentDbContext.LinkTypes.AsNoTracking().Count(e => e.Id == id) > 0;
        }
    }
}