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.Core;
using Qusion.Cms.Core;
using Qusion.Cms.Core.Domain;
using Qusion.Cms.Core.Exceptions;
using Qusion.Cms.Core.Security;
using Qusion.Cms.Modules.Polls.Core;
using Qusion.Cms.Modules.Polls.Domain;
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.Polls;
using Qusion.Cms.Modules.Polls.Queries;
using Qusion.Framework.Configuration;
using Qusion.WebApp.Areas.Qusion.Helpers;



namespace Qusion.WebApp.Areas.Qusion.Controllers.Api
{
   [Authorize(Roles = "Administrator,Administrators")]
    public class PollController : ApiController
    {
       
        private readonly PollService _pollService;
        private readonly LabelService _labelService;
        private readonly UserService _userService;

        public PollController(PollService pollService, UserService userService, PollService questionService,
                              LabelService labelService)
        {
            _pollService = pollService;
            _userService = userService;
            _labelService = labelService;
        }

        [HttpPost]
        [ModelValidationFilter]
        [Authorize(Roles = "Administrator,Administrators,Radnik")]
        public HttpResponseMessage Create(PollCreateModel newPoll)
        {
            Poll poll = Mapper.Map<PollCreateModel, Poll>(newPoll);
            poll.Status = WorkflowStatus.Aktivan;
            try
            {
                poll.Alias = _pollService.GenerateAlias(string.IsNullOrEmpty(poll.Alias) ? poll.Title : poll.Alias);
            }
            catch (AliasException e)
            {
                var errors = new Dictionary<string, string[]>();
                errors.Add("newPoll.Alias", new[] {"utility.InvalidAlias"});
                return Request.CreateResponse(HttpStatusCode.OK, new {Errors = errors});
            }
            _pollService.Save(poll);
            return Request.CreateResponse(HttpStatusCode.OK, Mapper.Map<Poll, PollModel>(poll));
        }

        [HttpPost]
        [ModelValidationFilter]
        [Authorize(Roles = "Administrator,Administrators,Radnik")]
        public HttpResponseMessage Edit(PollEditModel poll)
        {
            Poll newPoll = _pollService.GetById(poll.ID);
           
            try
            {
                if (newPoll.Alias != poll.Alias)
                {
                    poll.Alias = _pollService.GenerateAlias(poll.Alias);
                }
                Mapper.Map(poll, newPoll);
                newPoll.Title = poll.Title;
                newPoll.Summary = poll.Summary;
                newPoll.Alias = poll.Alias;
                _pollService.Save(newPoll);
            }
            catch (AliasException e)
            {
                var errors = new Dictionary<string, string[]>();
                errors.Add("poll.Alias", new[] {"utility.InvalidAlias"});
                return Request.CreateResponse(HttpStatusCode.OK, new {Errors = errors});
            }
            return Request.CreateResponse(HttpStatusCode.OK, Mapper.Map<Poll, PollModel>(newPoll));
        }

    

        [HttpGet]
        public PollModel Get(Guid id)
        {
           Poll poll = _pollService.GetById(id);
                PollModel mapped = Mapper.Map<Poll, PollModel>(poll);
                return mapped;

        }

        [HttpGet]
        public PageResult<PollListModel> Query([FromUri] PollQueryInput input)
        {
            PollQuery query = Mapper.Map(input, PollQuery.Default) ?? PollQuery.Default;
                IEnumerable<Poll> polls = _pollService.Search(query);
                IList<PollListModel> model = Mapper.Map<IList<Poll>, IList<PollListModel>>(polls.ToList());

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

        /// <summary>
        ///   Set newsletter aktivan i neaktivan
        /// </summary>
        /// <param name="id"> User id. </param>
        /// <returns> Http status code 200 (Ok) or 404 (NotFound) </returns>
        [HttpGet]
        public HttpResponseMessage Status(Guid id)
        {
            Poll poll = _pollService.GetById(id);
            if (poll.Status == WorkflowStatus.Aktivan)
            {
                poll.Status = WorkflowStatus.NeAktivan;
                _pollService.Save(poll);
                return Request.CreateResponse(HttpStatusCode.OK, new { poll.Status });
            }
            else
            {
                poll.Status = WorkflowStatus.Aktivan;
                _pollService.Save(poll);
                return Request.CreateResponse(HttpStatusCode.OK, new { poll.Status });
            }
            return Request.CreateResponse(HttpStatusCode.NotFound);
        }

        [HttpGet]
        public HttpResponseMessage Delete(Guid id)
        {
            Poll poll = _pollService.GetById(id);
            _pollService.Delete(poll);
            return Request.CreateResponse(HttpStatusCode.OK);
        }

        /********************************************************************
         *******                 Questions manipulation                 *********
         *******************************************************************/

        [HttpGet]
        public IQueryable<PollQuestionListModel> GetQuestioniByPollId(Guid pollId)
        {
           var list = _pollService.GetQustionByPollId(pollId);
                var model = Mapper.Map<IEnumerable<PollQuestion>, IList<PollQuestionListModel>>(list.OrderBy(x => x.CreatedOn));
                return model.AsQueryable();
            
        }

      
  

        [Authorize(Roles = "Administrator,Administrators,Radnik")]
        public HttpResponseMessage CreateQuestion(PollQuestionCreateModel question)
        {
            Poll poll = _pollService.GetById(question.PollID);
            var newQuestion = new PollQuestion
                    {
                        Poll = poll,
                        Title = question.Title,
                        Alias = question.Title
                    };
                    _pollService.SaveQuestion(newQuestion);
                    return Request.CreateResponse(HttpStatusCode.OK, Mapper.Map<PollQuestion, PollQuestionListModel>(newQuestion));

        }


        [HttpGet]
        public HttpResponseMessage QuestionForEdit(Guid id)
        {
            PollQuestion question = _pollService.GetQuestionById(id);

            return Request.CreateResponse(HttpStatusCode.OK, Mapper.Map<PollQuestion, PollQuestionModel>(question));
        }



       /*Updae Question*/ 

        [HttpPost]
        [ModelValidationFilter]
        [Authorize(Roles = "Administrator,Administrators,Radnik")]
        public HttpResponseMessage UpdateQuestion(PollQuestionEditModel question)
        {
             PollQuestion newQuestion = _pollService.GetQuestionById(question.ID);
           
            try
            {
                if (newQuestion.Alias != question.Alias)
                {
                    newQuestion.Alias = _pollService.GenerateAlias(question.Alias);
                }
                Mapper.Map(question, newQuestion);
                newQuestion.Title = question.Title;
                newQuestion.Alias = question.Alias;
                _pollService.SaveQuestion(newQuestion);
            }
            catch (AliasException e)
            {
                var errors = new Dictionary<string, string[]>();
                errors.Add("poll.Alias", new[] {"utility.InvalidAlias"});
                return Request.CreateResponse(HttpStatusCode.OK, new {Errors = errors});
            }
            return Request.CreateResponse(HttpStatusCode.OK, Mapper.Map<PollQuestion, PollQuestionModel>(newQuestion));
        }


        [HttpGet]
        public HttpResponseMessage DeleteQuestion(Guid id)
        {

            PollQuestion question = _pollService.GetQuestionById(id);
                _pollService.DeleteQuestion(question);
                return Request.CreateResponse(HttpStatusCode.OK);
        }

        /********************************************************************
      *******                 Answers manipulation                 *********
      *******************************************************************/

        [HttpGet]
        public IQueryable<PollAnswerListModel> GetAnswerByQuestionId(Guid questionId)
        {
           var list = _pollService.GetAnswerByQuesionId(questionId);
                var model = Mapper.Map<IEnumerable<PollAnswer>, IList<PollAnswerListModel>>(list.OrderBy(x => x.CreatedOn));
                return model.AsQueryable();
            
        }




        [Authorize(Roles = "Administrator,Administrators,Radnik")]
        public HttpResponseMessage CreateAnswer(PollAnswerCreateModel answer)
        {
            PollQuestion question = _pollService.GetQuestionById(answer.QuestionID);
            var newAnswer = new PollAnswer
            {
                Question = question,
                Title = answer.Title,
                Color = answer.Color
            };
            _pollService.SaveAnswer(newAnswer);
            return Request.CreateResponse(HttpStatusCode.OK, Mapper.Map<PollAnswer, PollAnswerListModel>(newAnswer));

        }

        [HttpGet]
        public HttpResponseMessage AnswerForEdit(Guid id)
        {
            PollAnswer answer = _pollService.GetAnswerById(id);
            return Request.CreateResponse(HttpStatusCode.OK, Mapper.Map<PollAnswer, PollAnswerModel>(answer));
        }

        [HttpPost]
        [ModelValidationFilter]
        [Authorize(Roles = "Administrator,Administrators,Radnik")]
        public HttpResponseMessage UpdateAnswer(PollAnswerEditModel answer)
        {
            PollAnswer newAnswer = _pollService.GetAnswerById(answer.ID);
            newAnswer.Title = answer.Title;
            newAnswer.Color = answer.Color;
            _pollService.SaveAnswer(newAnswer);
            return Request.CreateResponse(HttpStatusCode.OK, Mapper.Map<PollAnswer, PollAnswerEditModel>(newAnswer));
        }

        [HttpGet]
        public HttpResponseMessage DeleteAnswer(Guid id)
        {
            PollAnswer answer = _pollService.GetAnswerById(id);
            _pollService.DeleteAnswer(answer);
            return Request.CreateResponse(HttpStatusCode.OK);
        }



        /********************************************************************
      *******                 Votes manipulation                 *********
      *******************************************************************/

       /// <summary>
       /// Glasaj
       /// </summary>
       /// <param name="answer"></param>
       /// <param name="ip"></param>
       /// <param name="user"></param>
       /// <returns></returns>
        [HttpGet]
        [ModelValidationFilter]
        [Authorize(Roles = "Administrator,Administrators,Radnik")]
        public HttpResponseMessage ExecuteVote(string answer, string ip, string user)
        {
            Guid a = new Guid(answer);
            PollAnswer ans = _pollService.GetAnswerById(a);
            _pollService.ExecuteVote(ans,ip,user);
            return Request.CreateResponse(HttpStatusCode.OK);
        }
       // provjeri IP

        [HttpPost]
        [ModelValidationFilter]
        [Authorize(Roles = "Administrator,Administrators,Radnik")]
        public IQueryable<PollAnswerVoteListModel> GetVoteByIp(object qustionId,string ip)
        {
           var list = _pollService.GetVoteByIp(ip).Where(x => x.Answer.Question.ID == qustionId);
           var model = Mapper.Map<IEnumerable<PollAnswerVote>, IList<PollAnswerVoteListModel>>(list.ToList().OrderBy(x => x.Ip));
           return model.AsQueryable();        
        }
    }
}