using CoviDok.Api.Request;
using CoviDok.BLL;
using CoviDok.BLL.User.Handlers;
using CoviDok.BLL.User.Managers;
using CoviDok.Data.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

namespace CoviDok.Data.MySQL
{
    public class MySqlCaseHandler : ICaseHandler
    {
        private readonly MySqlContext context = new MySqlContext();
        public async Task<Case> AddCase(Case c)
        {
            context.Cases.Add(c);
            await context.SaveChangesAsync();
            return c;
        }

        public async Task SetCase(int id, CaseStatus status, Update message)
        {
            Case c = await context.Cases.FindAsync(id);
            message.CaseId = c.Id;
            context.Updates.Add(message);
            c.CaseStatus = status;
            c.Updates.Add(message);
            await context.SaveChangesAsync();
        }

        public List<Update> GetUpdatesForCase(int id)
        {
            return (from u in context.Updates where u.CaseId == id select u).ToList();
        }

        public Update GetUpadte(int id)
        {
            Update update = (from u in context.Updates where u.Id == id select u).First();
            if (update != null)
            {
                update.Images = (from i in context.Images where i.UpdateId == update.Id select i.ImageId).ToList();
            }
            return update;
        }

        public bool IsAssistantOfDoctor(int id, int doctorId)
        {
            return context.Assistants.Any( (a) => a.Id == id && a.DoctorId == doctorId);
        }

        public async Task<List<Case>> Filter(CaseFilter filter)
        {
            List<Case> ret = new List<Case>();
            
            await Task.Run(() => {
                var query = from c in context.Cases select c;
                if (filter.ChildId != int.MinValue)
                {
                    query = query.Where(c => c.ChildId == filter.ChildId);
                }
                if (filter.DoctorId != int.MinValue)
                {
                    query = query.Where(c => c.DoctorId == filter.DoctorId);
                }
                if (filter.ParentId != int.MinValue)
                {
                    query = query.Where(c => c.ParentId == filter.ParentId);
                }
                if (filter.Assignee != int.MinValue)
                {
                    query = query.Where(c => c.Assignee == filter.Assignee);
                }
                if (filter.Title != null)
                {
                    query = query.Where(c => c.Title.Contains(filter.Title));
                }
                ret = query.ToList();
            });
            return ret;
        }

        public async Task<Case> GetCase(int id)
        {
            return await context.Cases.FindAsync(id);
        }

        public async Task UpdateCase(int id, Case Case, Update update)
        {
            Case c = await context.Cases.FindAsync(id);
            context.Entry(c).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
            string[] forbidden = { "Updates" };
            PropertyCopier<Case>.Copy(Case, c, forbidden);
            context.Updates.Add(update);
            await context.SaveChangesAsync();
            foreach (string ImageId in update.Images)
            {
                Image image = new Image
                {
                    UpdateId = update.Id,
                    ImageId = ImageId
                };
                context.Images.Add(image);
            }
            update.CreatedDate = DateTime.Now;
            c.Updates.Add(update);
            await context.SaveChangesAsync();
        }

        public bool IsAuthorized(int Id, Case c)
        {
            if (Id == c.DoctorId || Id == c.ParentId) return true;
            // Ha van olyan Asszisztens, akinek;
            //     - a dokija egyezik az ügy dokijával
            //     - azonosítója a bejelentezett user azonosítója
            return (context.Assistants.Any(a => a.Id == Id && a.DoctorId == c.DoctorId));
        }
    }
}