using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using AutoMapper;
using Qusion.Cms.Classifications;
using Qusion.Cms.Classifications.Core;
using Qusion.Cms.Core.Domain;
using Qusion.Cms.Core.Exceptions;
using Qusion.Cms.Modules.Events;
using Qusion.Cms.Modules.Events.Core;
using Qusion.Cms.Users.Core;
using Qusion.Cms.Users.Domain;
using Qusion.Cms.Web.Http;
using Qusion.WebApp.Areas.Qusion.Filters;
using Qusion.WebApp.Areas.Qusion.Models.Events;
using Qusion.Framework.Configuration;
using Qusion.WebApp.Areas.Qusion.Helpers;
using Qusion.WebApp.Areas.Qusion.Mailers.News;


namespace Qusion.WebApp.Areas.Qusion.Controllers.Api
{
    [Authorize]
    public class EventController : ApiController
    {
        private readonly EventService _eventService;
        private readonly EventUserService _eventUserService;
        private readonly EventTeamService _eventTeamService;
        private readonly LabelService _labelService;
        private readonly UserService _userService;
     

        public EventController(EventService eventService, EventUserService eventUserService, EventTeamService eventTeamService, LabelService labelService,
                               UserService userService)
        { 
            _eventService = eventService;
            _eventUserService = eventUserService;
            _eventTeamService = eventTeamService;
            _labelService = labelService;
            _userService = userService;

        }

        [HttpGet]
        public PageResult<EventListModel> Query([FromUri] EventQueryInput input)
        {
          
                EventQuery query = Mapper.Map(input, EventQuery.Default) ?? EventQuery.Default;
                IEnumerable<Event> events = _eventService.Search(query);
                var a = events.ToList().Where(x => x.Title != null);
                IList<EventListModel> model = Mapper.Map<IList<Event>, IList<EventListModel>>(a.ToList());

                return new PageResult<EventListModel>
                {
                    Items = model,
                    Count = query.Paging.TotalCount
                };
            
        }

        [HttpGet]
        public EventModel Get(Guid id)
        {
            Event _event = _eventService.GetById(id);
            return Mapper.Map<Event, EventModel>(_event);
            
        }

        [HttpPost]
        [ModelValidationFilter]
        public HttpResponseMessage Create(EventCreateInput model)
        {
            var errors = new Dictionary<string, string[]>();

            if (DateTime.Now.AddDays(-1) > model.StartsOn || model.StartsOn > model.EndsOn)
                errors.Add("model.StartsOn", new string[] {"events.start_date_invalid"});

            if (model.EndsOn < model.StartsOn)
                errors.Add("model.EndsOn", new string[] { "events.end_date_invalid" });

            if (errors.Count > 0)
                return Request.CreateResponse(HttpStatusCode.OK, new {Errors = errors});

            var _event = new Event();
            Mapper.Map(model, _event);
            _event.Status = WorkflowStatus.Draft;
           _event.Labels.Clear();
            foreach (string labelId in model.Labels)
            {
                if (labelId != null)
                {
                    _event.Labels.Add(_labelService.GetById(new Guid(labelId)));
                }
            }

            try{
                _event.Alias = _eventService.GenerateAlias(string.IsNullOrWhiteSpace(model.Alias) ? model.Title : model.Alias);
            }catch (AliasException){
                errors.Add("model.Alias", new string[] { "utility.InvalidAlias" });
                return Request.CreateResponse(HttpStatusCode.OK, new { Errors = errors });
            }

            _eventService.Save(_event);
            return Request.CreateResponse(HttpStatusCode.OK, Mapper.Map<Event, EventModel>(_event));
        }

        [HttpPost]
        [ModelValidationFilter]
        public HttpResponseMessage CreateUser(EventUserInput model)
        {
            Event _event = _eventService.GetById(model.EventID);
            User _user = _userService.GetById(model.UserID);
            EventUser eventUser = null;

            eventUser = new EventUser();
            Mapper.Map(model, eventUser);
            eventUser.EventSubscriptionStatus = EventSubscriptionStatus.Approved;
            eventUser.IsInvited = true;
            _eventUserService.Save(eventUser);
            var mail = new CreateNewArticleNotification
            {
                Email = _user.Email.ToString(),
                ArticleUrl = "www.zvjezdana.com/events/" + _event.ID,
                Body = "Objavljena je nova najava:" + Environment.NewLine + _event.Title.ToString() + Environment.NewLine + _event.Summary.ToString() + Environment.NewLine + "Kompletan pregled objave:" + Environment.NewLine + "http://wwwwww.zvjezdana.com/astroz/evenye/" + _event.ID
            };
            new NewsMailer().CreateNotification(mail).Send();
            return Request.CreateResponse(HttpStatusCode.OK, model);
        }

        [HttpPost]
        [ModelValidationFilter]
        public HttpResponseMessage CreateTeam(EventTeamInput model)
        {
            Event _event = _eventService.GetById(model.EventID);
            EventTeam eventTeam = null;

            if (model.Labels != null)
            {
                foreach (string labelId in model.Labels)
                {
                    Label label = _labelService.GetById(new Guid(labelId));
                    IQueryable<User> users = _userService.GetByLabel(label);
                    foreach (User user in users)
                    {
                        eventTeam = new EventTeam();
                        eventTeam.User = user;
                        eventTeam.Event = _event;
                        eventTeam.ApprovedOn = model.ApprovedOn;
                        eventTeam.ExpiresOn = model.ExpiresOn;
                        eventTeam.StartsOn = model.StartsOn;
                        eventTeam.ExpiresOn = model.ExpiresOn;
                        eventTeam.EventSubscriptionStatus = EventSubscriptionStatus.Approved;
                        eventTeam.IsInvited = true;
                        _eventTeamService.Save(eventTeam);
                        var mail = new CreateNewArticleNotification
                        {
                            Email = eventTeam.User.Email.ToString(),
                            ArticleUrl = "www.zvjezdana.com/astro/events/" + _event.ID,
                            Body = "Objavljena je nova!" + Environment.NewLine + _event.Title.ToString() + Environment.NewLine + _event.Summary.ToString() + Environment.NewLine + "Više o najavi na:" + Environment.NewLine + "http://wwwwww.zvjezdana/astro/events/" + _event.ID
                        };
                        new NewsMailer().CreateNotification(mail).Send();
                    }
                }
            }
            else
            {
                var errors = new Dictionary<string, string[]>();
                errors.Add("model.Labels", new string[] { "events.required_team" });
                return Request.CreateResponse(HttpStatusCode.OK, new { Errors = errors });
            }
            return Request.CreateResponse(HttpStatusCode.OK, model);
        }

        [HttpGet]
        public EventModel GetEdit(Guid id)
        {
            Event _event = _eventService.GetByIdForEditing(id);
            return Mapper.Map<Event, EventModel>(_event);
        }

        [HttpPost]
        [ModelValidationFilter]
        public HttpResponseMessage Edit(EventEditInput model)
        {
            var errors = new Dictionary<string, string[]>();

            if (DateTime.Now.AddDays(-1) > model.StartsOn || model.StartsOn > model.EndsOn)
                errors.Add("model.StartsOn", new string[] { "events.start_date_invalid" });

            if (model.EndsOn < model.StartsOn)
                errors.Add("model.EndsOn", new string[] { "events.end_date_invalid" });

            if (errors.Count > 0)
                return Request.CreateResponse(HttpStatusCode.OK, new { Errors = errors });

            Event _event = _eventService.GetById(model.Id);
            Mapper.Map(model, _event);
            _event.Labels.Clear();
            foreach (string labelId in model.Labels)
            {
                _event.Labels.Add(_labelService.GetById(new Guid(labelId)));
            }
            if (_event.StartsOn <= DateTime.Today)
                _event.Status = WorkflowStatus.Live;
            _eventService.Save(_event);
            return Request.CreateResponse(HttpStatusCode.OK, Mapper.Map<Event, EventModel>(_event));
        }

        [HttpPost]
        [ModelValidationFilter]
        public HttpResponseMessage EditTeam(EventTeamEdit model)
        {
            EventTeam user = _eventTeamService.GetById(model.ID);
            Mapper.Map(model, user);
            _eventTeamService.Save(user);

            return Request.CreateResponse(HttpStatusCode.OK, model);
        }

        [HttpGet]
        public HttpResponseMessage Delete(Guid id)
        {
            Event _event = _eventService.GetById(id);
            _eventService.Delete(_event);
            return Request.CreateResponse(HttpStatusCode.OK);
        }

        [HttpGet]
        public HttpResponseMessage DeleteTeam(Guid id)
        {
            EventTeam user = _eventTeamService.GetById(id);
            _eventTeamService.Delete(user);
            return Request.CreateResponse(HttpStatusCode.OK);
        }
    }
}