using Contracts.BindingModels;
using Contracts.SearchModel;
using Contracts.Storage;
using Contracts.ViewModels;
using MongoDB.Bson;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MongoDB
{
    public class HumanStorage : IHumanStorage
    {
        public MongoClient contex;
        public HumanStorage()
        {
            contex = MongoDateBase.getInstance().client;
        }
        public HumanVM? Delete(HumanBM model)
        {
            IMongoDatabase db = contex.GetDatabase("logistic");
            var collection = db.GetCollection<BsonDocument>("Human");
            var res = collection.FindOneAndDelete(new BsonDocument("phone", model.Phone));
            if (res == null)
                return null;
            return new HumanVM
            {
                Name = res["name"].ToString(),
                Phone = res["phone"].ToString(),
                StatusTitle = res["Status"].ToString(),

            };
        }

        public HumanVM? GetElement(HumanSM model)
        {
            IMongoDatabase db = contex.GetDatabase("logistic");
            var collection = db.GetCollection<BsonDocument>("Human");
            BsonDocument human = collection.Find(new BsonDocument("phine", model.Phone)).FirstOrDefault();
            if (human == null)
                return null;
            return new HumanVM
            {
                Name = human["name"].ToString(),
                Phone = human["phone"].ToString(),
                StatusTitle = human["Status"].ToString()
            };
        }

        public List<HumanVM> GetFilteredList(HumanSM model)
        {
            IMongoDatabase db = contex.GetDatabase("logistic");
            var collection = db.GetCollection<BsonDocument>("Human");
            List<BsonDocument> humans = collection.Find(new BsonDocument { { "$regex", $"^.{model.Name}.$" } }).ToList();
            List<HumanVM> res = new List<HumanVM>();
            foreach (var human in humans)
            {
                res.Add(new HumanVM
                {
                    Name = human["name"].ToString(),
                    Phone = human["phone"].ToString(),
                    StatusTitle = human["Status"].ToString()
                });
            }
            return res;
        }

        public List<HumanVM> GetFullList()
        {
            IMongoDatabase db = contex.GetDatabase("logistic");
            var collection = db.GetCollection<BsonDocument>("Human");
            List<BsonDocument> humans = collection.Find(new BsonDocument()).ToList();
            List<HumanVM> res = new List<HumanVM>();
            foreach (var human in humans)
            {
                res.Add(new HumanVM
                {
                    Name = human["name"].ToString(),
                    Phone = human["phone"].ToString(),
                    StatusTitle = human["Status"].ToString()
                });
            }
            return res;
        }

        public HumanVM? Insert(HumanBM model)
        {
            IMongoDatabase db = contex.GetDatabase("logistic");
            var collection = db.GetCollection<BsonDocument>("Human");
            BsonDocument human = new BsonDocument {  { "name", model.Name }, { "Status", model.StatusTitle }, { "phone" , model.Phone} };
            collection.InsertOne(human);
            return new HumanVM { Name = model.Name, StatusTitle = model.StatusTitle,Phone = model.Phone };
        }

        public HumanVM? Update(HumanBM model)
        {
            IMongoDatabase db = contex.GetDatabase("logistic");
            var collection = db.GetCollection<BsonDocument>("Human");
            var result = collection.UpdateOneAsync(new BsonDocument("name", model.oldName), new BsonDocument("$set", new BsonDocument("name", model.Name)));
            if (result == null)
                return null;
            return new HumanVM
            {
                Name = model.Name,
                StatusTitle = model.StatusTitle,
                Phone = model.Phone
            };
        }
    }
}