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)
        {
            Case c = await context.Cases.FindAsync(id);
            c.CaseStatus = status;
            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)
        {
            return (from u in context.Updates where u.Id == id select u).First();
        }

        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 = new Case { Id = id };
            context.Attach(c);
            context.Entry(c).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
            string[] forbidden = { "Updates" };
            PropertyCopier<Case>.Copy(Case, c, forbidden);
            context.Updates.Add(update);
            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));
        }
    }
}