using CoviDok.Api.Request;
using CoviDok.BLL.Sessions;
using CoviDok.BLL.User.Handlers;
using CoviDok.Data.Model;
using CoviDok.Data.MySQL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace CoviDok.BLL.User.Managers
{
    public class CaseManager
    {
        private readonly ICaseHandler handler = new MySqlCaseHandler();

        public async Task<List<Case>> FilterCases(Session s, CaseFilter filter)
        {
            // TODO: Jogosultságkezelés            
            return await handler.Filter(filter);
        }

        public async Task<List<Update>> GetUpdatesForCase(Session s, int id)
        {
            Case c = await handler.GetCase(id);
            if (c == null) throw new KeyNotFoundException();
            if (handler.IsAuthorized(s.ID, c))
            {
                return handler.GetUpdatesForCase(id);
            }
            else throw new UnauthorizedAccessException();
            
        }

        public async Task SetCertified(Session s, int id)
        {
            Case c = await handler.GetCase(id);
            if (c == null) throw new KeyNotFoundException();
            if (handler.IsAuthorized(s.ID, c) && s.Type == Api.Role.Ast)
            {
                Update update = new Update { 
                CaseID = c.Id,
                SenderID = s.ID,
                SenderRole = s.Type,
                CreatedDate = DateTime.Now,
                Content = "Case set to 'Certified'"
                };
                await handler.SetCase(id, CaseStatus.Cured, update);
            }
            else
            {
                throw new UnauthorizedAccessException();
            }
        }

        public async Task SetCured(Session s, int id)
        {            
            Case c = await handler.GetCase(id);
            if (c == null) throw new KeyNotFoundException();
            if (s.ID == c.DoctorID)
            {
                Update update = new Update
                {
                    CaseID = c.Id,
                    SenderID = s.ID,
                    SenderRole = s.Type,
                    CreatedDate = DateTime.Now,
                    Content = "Case set to 'Cured'"
                };
                await handler.SetCase(id, CaseStatus.Cured, update);
            }
            else
            {
                throw new UnauthorizedAccessException();
            }
        }

        public async Task<Update> GetUpdate(Session s, int id)
        {
            // Parent, Doctor, and doctors assistants can access a case
            Update u = handler.GetUpadte(id);
            Case c = await handler.GetCase(u.CaseID);
            if (c == null) throw new KeyNotFoundException();
            if (handler.IsAuthorized(s.ID, c))
            {
                return u;
            }
            else
            {
                throw new UnauthorizedAccessException();
            }
        }



        public async Task<Case> GetCase(Session s, int id)
        {
            // Parent, Doctor, and doctors assistants can access a case
            Case c = await handler.GetCase(id);
            if (c == null) throw new KeyNotFoundException();
            if (handler.IsAuthorized(s.ID, c))
            {
                return c;
            }
            else
            {
                throw new UnauthorizedAccessException();
            }
        }

        public async Task<Case> CreateCase(Session s, int DoctorID, int ChildID, string Title, DateTime startDate)
        {
            // TODO szülő csak saját gyereket jelenthet
            Case c = new Case { 
                StartDate = startDate,
                ChildID = ChildID,
                ParentID = s.ID,
                DoctorID = DoctorID,
                Title = Title,
                CreatedDate = DateTime.Now,
                LastModificationDate = DateTime.Now,
                CaseStatus = CaseStatus.InProgress,
                Assignee = s.ID
            };
            return await handler.AddCase(c);
        }

        public async Task UpdateCase(Session s, int id, string updateMsg, List<string> Images)
        {
            Case c = await handler.GetCase(id);
            if (c == null) throw new KeyNotFoundException("Case ID not found: " + id);
            if (handler.IsAuthorized(s.ID, c))
            {
                if (c.CaseStatus == CaseStatus.Certified) throw new ArgumentException("Can't modify closed Case!");

                if (s.ID == c.ParentID) c.Assignee = c.DoctorID; // Ha szülő updatel, az assignee az orvos lesz
                // TODO Ha a doki VAGY asszisztense frissít
                if (s.ID == c.DoctorID) c.Assignee = c.ParentID; // Ha doki frissít, a szülőhöz kerül

                c.LastModificationDate = DateTime.Now;
                Update update = new Update {
                    CaseID = c.Id,
                    SenderID = s.ID,
                    SenderRole = s.Type,
                    Content = updateMsg,
                    CreatedDate = DateTime.Now,
                    Images = Images
                };                
                await handler.UpdateCase(id, c, update);
            }
            else
            {
                throw new UnauthorizedAccessException();
            }
        }
    }
}