using DocumentFormat.OpenXml.Office2010.Excel;
using FamilyTreeAPI.Entities;
using FamilyTreeAPI.Helper;
using FamilyTreeAPI.Interface;
using FamilyTreeAPI.Models;
using Microsoft.EntityFrameworkCore;

namespace FamilyTreeAPI.Repository
{
    public class PersonPhotoRepository: IPersonPhoto
    {
        private readonly FamilyTreeDBContext _context;
        private readonly IHttpContextAccessor _httpContext;
        private readonly IConfiguration _config;
        public PersonPhotoRepository(IConfiguration config, 
        FamilyTreeDBContext context,
        IRelationShipd relationship,
        IHttpContextAccessor httpContext)
        {
            _context = context;            
            _config = config;
            _httpContext = httpContext;
        }

        private PersonPhotoDto FillDto(PersonPhoto model)
        {
            PersonPhotoDto dto = new();
            dto.Id = model.Id;
            dto.PersonId = model.PersonId;
            dto.Photo = model.Photo;
            dto.PhotoType = model.PhotoType;
            return dto;
        }
        private PersonPhoto FillModel(PersonPhoto model, int personId, string filename)
        {

            model.PersonId = personId;
            model.Photo = filename;
            model.PhotoType = System.IO.Path.GetExtension(filename);

            return model;
        }
        public async Task<ResultModel<int>> SaveAsync(UploadCriteria criteria)
        {
            int result = default(int);
            int statuscode = 0;
            string error = "";

            HttpContext? httpContext = _httpContext.HttpContext;
            string loginName = "";
            if (httpContext != null)
            {
                UserDto? user = (UserDto?)httpContext.Items["User"];
                if (user != null)
                    loginName = user.FirstName + " " + user.LastName;
            }
           
            try
            {
                IFormFile formfile = criteria.File;

                PersonPhoto model;
            
                    model = new();
                    
                    model = FillModel(model,criteria.PersonId, formfile.FileName);
                   
                    using (var stream = new MemoryStream())
                    {
                        await formfile.CopyToAsync(stream);
                        model.ImagePhoto = stream.ToArray();
                    }
                _context.PersonPhotos.Add(model);
                await _context.SaveChangesAsync();

                statuscode = 1;
               
            }
            catch (Exception ex)
            {
                error = ex.ToString();
                statuscode = -1;
            }
            //var dto = await Task.Run(() => result);
            return new ResultModel<int>()
            {
                Data = result,
                StatusCode = statuscode,
                Message = error
            };
        }

        public async Task<ResultModel<FileContent>> DownloadPersonPhoto(int id, string? filename)
        {

            int statusCode = -1;
            string error = "";
            PersonPhoto? model = null;
            FileContent fileContent = new();
            if (id < 1)
            {
                var rlist = await _context.PersonPhotos.Where(x => x.Photo == filename).ToListAsync();
                if (rlist != null)
                {
                    if (rlist.Count > 0)
                    {
                        model = rlist[0];
                    }
                }
            }
            else
            {
                model = await _context.PersonPhotos.FindAsync(id);
            }

            if (model != null)
            {
                fileContent.ContentType = Helpers.GetFileContent(model.PhotoType);
                fileContent.Content = (byte[])model.ImagePhoto;
                fileContent.FileName = model.Photo;
                statusCode = 1;
            }

            return new ResultModel<FileContent>()
            {
                Data = fileContent,
                StatusCode = statusCode,
                Message = error
            };
        }

        public async Task<ResultModel<int>> DeletePersonPhoto(int id)
        {
            int result = default(int);
            int statuscode = 0;
            string error = "";
            try
            {
                PersonPhoto? model = await _context.PersonPhotos.FindAsync(id);
                if (model != null)
                {
                    _context.PersonPhotos.Remove(model);
                    await _context.SaveChangesAsync();
                    statuscode = 1;
                }
            }
            catch (Exception ex)
            {
                error = ex.ToString();
                statuscode = -1;
            }
            //var dto = await Task.Run(() => result);
            return new ResultModel<int>()
            {
                Data = result,
                StatusCode = statuscode,
                Message = error
            };
        }


        public async Task<ResultModel<List<PersonPhotoDto>>> LoadPersonPhoto(int personId)
        {
            List<PersonPhotoDto> result = new();
            int statuscode = 0;
            string error = "";
            PersonPhotoDto dto;
            PersonPhoto? model;
            try
            {
                List<PersonPhoto?> mlist = await _context.PersonPhotos.Where( x => x.PersonId  == personId ).ToListAsync();
                for (int i = 0; i< mlist.Count; i++)
                {
                    model = mlist[i];
                    if (model != null)
                    {
                        dto = FillDto(model);
                        result.Add(dto);
                    }
                    statuscode = 1;
                }
            }
            catch (Exception ex)
            {
                error = ex.ToString();
                statuscode = -1;
            }
            
            return new ResultModel<List<PersonPhotoDto>>()
            {
                Data = result,
                StatusCode = statuscode,
                Message = error
            };
        }
    }
}
