using System;
using System.Linq;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using AsbCloudApp.Data;
using AsbCloudApp.Services;
using AsbCloudDb.Model;

namespace AsbCloudInfrastructure.Services
{
    public class FileService : IFileService
    {
        public string RootPath { get; private set; }
        private readonly IAsbCloudDbContext db;
        private readonly ITelemetryService telemetryService;

        public FileService(IAsbCloudDbContext db, ITelemetryService telemetryService)
        {
            RootPath = "files";
            this.db = db;
            this.telemetryService = telemetryService;
        }

        public IDictionary<string, int> SaveFilesPropertiesToDb(int idWell, int idCategory, 
            IEnumerable<(string fileName, int idWell, int idCategory, DateTime date, int idUser)> filesInfo)
        {
            var fileIdsToNames = new Dictionary<string, int>();

           foreach(var fileInfo in filesInfo)
           {
                var file = new File()
                {
                    Name = fileInfo.fileName,
                    IdWell = fileInfo.idWell,
                    IdCategory = fileInfo.idCategory,
                    Date = fileInfo.date,
                    IdAuthor = fileInfo.idUser
                };

                db.Files.Add(file);
                db.SaveChanges();
                fileIdsToNames.Add(file.Name, file.Id);
            }

            return fileIdsToNames;
        }

        public PaginationContainer<FilePropertiesDto> GetFilesInfo(int idWell,
            int idCategory, DateTime begin = default, DateTime end = default, 
            int skip = 0, int take = 32)
        {
            var filesInfoQuery = db.Files.Include(f => f.User)
                .Where(f => f.IdWell == idWell &&
                f.IdCategory == idCategory);

            if (!filesInfoQuery.Any())
                return null;

            var result = new PaginationContainer<FilePropertiesDto>() { Skip = skip, Take = take };

            if (begin != default)
                filesInfoQuery = filesInfoQuery.Where(m => m.Date >= begin);

            if (end != default)
                filesInfoQuery = filesInfoQuery.Where(m => m.Date <= end);

            result.Count = filesInfoQuery.Count();

            if (skip > 0)
                filesInfoQuery = filesInfoQuery.Skip(skip);

            var filesInfoList = filesInfoQuery.OrderBy(f => f.Date).Take(take).ToList();

            if (filesInfoList.Count == 0)
                return result;

            foreach (var fileInfo in filesInfoList)
            {
                var messageDto = new FilePropertiesDto
                {
                    Id = fileInfo.Id,
                    Name = fileInfo.Name,
                    IdCategory = fileInfo.IdCategory,
                    UploadDate = fileInfo.Date,
                    UserName = fileInfo.User.Name
                };

                result.Items.Add(messageDto);
            }

            return result;
        }

        public (int Id, string Name, int IdCategory)? GetFileInfo(int fileId)
        {
            var fileInfo = db.Files.FirstOrDefault(f => f.Id == fileId);

            if (fileInfo is null)
                return null;

            return (fileInfo.Id, fileInfo.Name, fileInfo.IdCategory);
        }
    }
}