using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using Azure.Storage.Blobs.Specialized;
using DamageAssesment.Api.Attachments.Interfaces;
using DamageAssesment.Api.Attachments.Models;
using System.Diagnostics.Metrics;
using System.Text;

namespace DamageAssesment.Api.Attachments.Providers
{
    public class AzureBlobService: IAzureBlobService
    {
        BlobServiceClient _blobClient;
        BlobContainerClient _containerClient;
        string azureConnectionString;
        private string uploadpath = "";
        private string Deletepath = "";
        public AzureBlobService(IConfiguration configuration)
        {
            uploadpath = configuration.GetValue<string>("Fileupload:folderpath");
            Deletepath = configuration.GetValue<string>("Fileupload:Deletepath");
            _blobClient = new BlobServiceClient(configuration.GetValue<string>("Fileupload:BlobConnectionString"));
            _containerClient = _blobClient.GetBlobContainerClient(configuration.GetValue<string>("Fileupload:BlobContainerName"));
        }
        public async Task<List<Attachment>> UploadAttachment(int responseId, int answerId, int counter, List<IFormFile> postedFile)
        {
            var pathToSave = Path.Combine(uploadpath, "Response-" + responseId);
            String fullDirectoryPath = Path.Combine(pathToSave, "Answer-" + answerId);
            List<Models.Attachment> attachments = new List<Models.Attachment>();
            foreach (IFormFile item in postedFile)
            {

                counter++;
                var UserfileName = Path.GetFileName(item.FileName);
                var extension = System.IO.Path.GetExtension(UserfileName);
                var fileName = String.Format("Attachment_{0}{1}", counter, extension);
                var stream = item.OpenReadStream();
                BlobClient client = _containerClient.GetBlobClient(fullDirectoryPath + "/" + fileName);
                string dbPath = fullDirectoryPath + "/" + fileName;
                var result = await client.UploadAsync(stream, true);
                attachments.Add(new Models.Attachment { AnswerId = answerId, ResponseId = responseId, IsDeleted = false, FileName = UserfileName, URI = dbPath });
            }
            return attachments;
        }
        public async Task<List<Attachment>> UploadAttachment(int responseId, int counter, List<AnswerInfo> answers)
        {
            List<Models.Attachment> attachments = new List<Models.Attachment>();
            try
            {
                foreach (var item in answers)
                {
                    int answerId = item.AnswerId;
                    var pathToSave = Path.Combine(uploadpath, "Response-" + responseId);
                    String fullDirectoryPath = Path.Combine(pathToSave, "Answer-" + answerId);
                    foreach (var file in item.postedFiles)
                    {
                        counter++;

                        var UserfileName = Path.GetFileName(file.FileName);
                        var fileName = String.Format("Attachment_{0}{1}", counter, file.FileExtension);
                        byte[] byteArray = Convert.FromBase64String(file.FileContent);
                        MemoryStream stream = new MemoryStream(byteArray);
                        BlobClient client = _containerClient.GetBlobClient(fullDirectoryPath + "/" + fileName);
                        string dbPath = fullDirectoryPath + "/" + fileName;
                        var result = await client.UploadAsync(stream, true);
                        attachments.Add(new Models.Attachment { AnswerId = answerId, ResponseId = responseId, IsDeleted = false, FileName = UserfileName, URI = dbPath });
                    }
                }
                return attachments;
            }
            catch (Exception ex)
            {
                return new List<Models.Attachment>();
            }


        }
        public async Task<List<Attachment>> UpdateAttachments(int responseId, List<AnswerInfo> answers, IEnumerable<Models.Attachment> attachments)
        {
            List<Models.Attachment> Dbattachments = new List<Models.Attachment>();
            foreach (Models.Attachment searchFile in attachments)
            {
                Movefile(searchFile.URI);
            }
            foreach (var item in answers)
            {
                int answerId = item.AnswerId;
                var pathToSave = Path.Combine(uploadpath, "Response-" + responseId);
                String fullDirectoryPath = Path.Combine(pathToSave, "Answer-" + answerId);
                foreach (var file in item.postedFiles)
                {
                    Models.Attachment attachment = attachments.Where(a => a.Id == file.AttachmentId).FirstOrDefault();
                    var UserfileName = Path.GetFileName(file.FileName);
                    var fileName = String.Format("Attachment_{0}{1}", attachment?.Id, file.FileExtension);
                    byte[] byteArray = Convert.FromBase64String(file.FileContent);
                    MemoryStream stream = new MemoryStream(byteArray);
                    BlobClient client = _containerClient.GetBlobClient(fullDirectoryPath + "/" + fileName);
                    string dbPath = fullDirectoryPath + "/" + fileName;
                    var result = await client.UploadAsync(stream, true);
                    Dbattachments.Add(new Models.Attachment { Id = attachment.Id, AnswerId = answerId, ResponseId = responseId, IsDeleted = false, FileName = UserfileName, URI = dbPath });
                }
            }
            return Dbattachments;
        }

        public async Task<List<Azure.Response<BlobContentInfo>>> UploadFiles(List<IFormFile> files)
        {

            var azureResponse = new List<Azure.Response<BlobContentInfo>>();
            foreach (var file in files)
            {
                string fileName = file.FileName;
                using (var memoryStream = new MemoryStream())
                {
                    file.CopyTo(memoryStream);
                    memoryStream.Position = 0;
                    var client = await _containerClient.UploadBlobAsync(fileName, memoryStream, default);
                    azureResponse.Add(client);
                }
            };

            return azureResponse;
        }
        public string getMovefilename(string movefilename)
        {
            var list = movefilename.Split('.');
            if (list.Length > 0)
                list[list.Length - 1] = DateTime.Now.ToShortDateString().Replace("/", "_") + "_" + DateTime.Now.ToShortTimeString().Replace("/", "_") + "." + list[list.Length - 1];
            return string.Join("_", list);
        }
        public void Movefile(string path)
        {
            try
            {
                if (path != "")
                {
                    string MovePath = getMovefilename(path.Replace(uploadpath, Deletepath));
                    // Get references to the source and destination blobs
                    BlobClient sourceBlobClient = _containerClient.GetBlobClient(path);
                    BlobClient destinationBlobClient = _containerClient.GetBlobClient(MovePath);
                    // Start the copy operation from the source to the destination
                    destinationBlobClient.StartCopyFromUri(sourceBlobClient.Uri);

                    // Check if the copy operation completed successfully
                    WaitForCopyToComplete(destinationBlobClient);

                    // Delete the source blob after a successful copy
                    sourceBlobClient.DeleteIfExists();
                }
            }
            catch (Exception ex)
            {

            }
        }
        static void WaitForCopyToComplete(BlobClient blobClient)
        {
            BlobProperties properties = blobClient.GetProperties();

            while (properties.CopyStatus == CopyStatus.Pending)
            {
                Task.Delay(TimeSpan.FromSeconds(1));
                properties = blobClient.GetProperties();
            }
        }
        public void Deletefile(string url)
        {
            BlobClient sourceBlobClient = _containerClient.GetBlobClient(url);
            sourceBlobClient.DeleteIfExists();
        }
    }
}